../ |
---|
WordPressにPHPのコードを差し込んで利用する方法には、ショートコードを使うのが一般的なようだ。その他にもプラグインや<iframe>
タグの利用もあるようだ。まずは、ショートコードの使い方を段階的に試してみた。分かったことをメモしておく。
ショートコードの基本操作
(1) function.php にハンドラ関数を定義する。wp-includes/function.php にある。実際には、直接 function.php に記述するのではなく、自身のサイト用の.phpファイルを別に作成して、function.php から include(require) して利用する。シグニチャは、一般に以下の感じになる。関数名は好きな名前でよい。引数は、HTMLの要素(element)を生成するイメージになっている。
/**
* 遷移先のHTMLやHTMLの要素(element)を生成して返す。
* @param array $attributes 属性の連想配列
* @param string $content 囲みショートコードの場合のテキスト
* @param string $tag ショートコード名(複数のショートコードが同じ関数を使用する場合)
*/
function shortcode_handler_function(array $attributes, string $content = '', string $tag = ''): string;
(2) ショートコード名とハンドラ関数のマッピングを定義する。1つのハンドラ関数に複数のショートコード名を対応付けできる。add_shortcode() を呼び出すタイミングはいくつかある。function.php の末尾やハンドラ関数の直後に記述してもよい。add_shortcode() 関数は、wp-includes/shortcodes.php 内に定義されていて、$shortcode_tags
という連想配列にハンドラ関数をセットしている。shortcode_handler_functionをnamespace で定義している場合は、namespace を添えて指定すること。
add_shortcode('shortcode_name', 'shortcode_handler_function');
add_shortcode('shortcode_name2', 'shortcode_handler_function');
add_shortcode('shortcode_name3', 'namespace\shortcode_handler_function'); // namespaceありのとき
(3) ショートコードの呼び出しは、以下の感じになる。ショートコード名(タグ名)、属性(attribute)の並び、テキストはHTMLの要素(element)を表現するような記法で書く。ショートコードは、本来、1つのHTMLの要素(element)を生成するために用意されたものと言える。contentを挟み込むものを「囲みショートコード」と呼ぶ。ショートコードは固定ページ、投稿、ウィジェットを対象に差し込みが行える。
[shortcode_name att1='123' att2='abc']content[/shortcode_name]
[shortcode_name att1='123' att2='abc']
[shortcode_name]content[/shortcode_name]
[shortcode_name]
[shortcode_name/]や[shortcode_name att1='123' att2='abc'/]のような記法はないみたい。末尾のスラッシュは不要。ショートコード名から(2)で定義されたマッピングを経由して、(1)のハンドラ関数が呼び出される。
- 引数
$attributes
には、上記の例だと、array(`att1 => '123', 'att2' => 'abc') のような連想配列が渡される。HTMLと同様に属性(attribute)はすべて文字列として渡される。'123'も整数ではなく、文字列である。 - 引数
$content
には、contentで指定されるテキストが渡される。 - 引数
$tag
には、shortcode_nameが渡される。1つのハンドラ関数に複数のショートコード名を定義した場合に有効に使える。
(4) 固定ページ、投稿、ウィジェット以外でも、do_shortcode() コールバック関数を使えば、任意の箇所でショートコードを利用できる。このdo_shortcode() 関数は、wp-includes/shortcodes.php 内に定義されている。
<?= do_shortcode("[shortcode_name]"); ?>
<?= do_shortcode("[shortcode_name style='color:red;']注意[/shortcode_name]"); ?>
例1: ショートコードの練習
自身のサイト用に mysite/shortcodeHandler.php といったファイルを作成し、wp-includes/functions.php から読み込むようにしておく。shortcodes.php が重複して読み込まれないように、require_once に変更しておこう。
require_once ABSPATH . '/mysite/shortcodeHandler.php'; // 末尾に追加
require ABSPATH . WPINC . '/shortcodes.php'; // 228行目あたり
↓
require_once ABSPATH . WPINC . '/shortcodes.php'; // require_onceに変更しておく
自サイト用の shortcodeHandler.php にハンドラ関数を書く。また、ハンドラ関数にショートコード名を付けて登録しておく。1つのハンドラ関数に複数のショートコードを定義できる。namespace を指定して、構造化した方がよいと思う。テスト用のtest
というショートコードとphpinfo() のINFO_VARIABLESを表示するvariables
というショートコードを作ってみる。ハンドラ関数の直後に add_shortcode() でショートコードを定義する。
<?php
namespace mysite;
require_once ABSPATH . '/wp-includes/shortcodes.php';
/**
* テスト用
* @return string
*/
function test(): string {
return '<p>こんにちは、ショートコードのテストです。</p>';
}
add_shortcode('test', 'mysite\test');
/**
* phpinfoのINFO_VARIABLESを表示する
* @return string
*/
function dumpVariables(): string {
ob_start();
phpinfo(INFO_VARIABLES);
return ob_get_clean();
}
add_shortcode('variables', 'mysite\dumpVariables');
namespace(上記の例ではmysite)を使うときは、ハンドラ関数に添えて定義すること。これらのショートコードを投稿ページから呼び出してみよう。投稿一覧から、適当な投稿を1つ開き、ダイレクトに以下の2行を追記する。ビジュアルエディタでもコードエディタでも構わない。'[ ]'では挟めば、ショートコードの呼び出しと判定してくれる。
[test]
[variables]
編集した投稿ページを「更新」し、「投稿を表示」する。「こんにちは、ショートコードのテストです」とphpinfo()の一部が表示されるはずである。
例2: HTMLの要素(element)を生成する例
HTMLの要素(element)を生成するようなショートコードも書いてみる。例えば、<a>
タグや<input>
タグを生成できるようなショートコードを作成してみる。<select>
タグにも挑戦してみる。
[a href='mysite/dummy1.php']登録[/a]
[button onclick="location.href='mysite/dummy2.php'" value='更新']
[select array='test_array2' value='20' onchange="location.href='mysite/dummy3.php'"]
自サイト用の shortcodeHandler.php にハンドラ関数を追加する。HTMLのAttributesとElementを処理するメソッドを作成し、createLink()、createInput()、createSelect()を作成しておく。createInput()は、typeを指定して、button,submit,checkbox,radioなどに利用できる。createSelect()では、呼び出す前に事前にoptionの配列を生成して変数に代入しておく必要がある。例では、$selectMap['test_array2']
に事前にoptionの配列をセットしている。
<?php
namespace mysite;
require_once ABSPATH . '/wp-includes/shortcodes.php';
function createAttributes(array $attributes): string {
$s = '';
foreach ($attributes as $k => $v){
$s .= ' ' . $k . '="' . $v . '"';
}
return $s;
}
function createElement(array $attributes, string $content = '', string $tag = 'a'): string {
return '<' . $tag . createAttributes($attributes) . '>' . $content . '</' . $tag . '>';
}
/**
* リンク<a>を生成する
* @param array $attributes 属性
* @param string $content テキスト
* @return string
*/
function createLink(array $attributes, string $content = ''): string {
return createElement($attributes, $content, 'a');
}
add_shortcode('a', 'mysite\createLink');
/**
* ボタンなどのエレメント<input type='xxx'>を生成する
* @param array $attributes 属性
* @param string $content テキスト
* @param string $type ショートコード名(inputのtype属性)
* @return string
*/
function createInput(array $attributes, string $content = '', string $type = 'button'): string {
$attributes['type'] = $type;
return createElement($attributes, $content, 'input');
}
add_shortcode('checkbox', 'mysite\createInput');
add_shortcode('button', 'mysite\createInput');
add_shortcode('submit', 'mysite\createInput');
add_shortcode('radio', 'mysite\createInput');
/**
* メニュー<select><option value='10' selected='selected'>AAA</option></select>を生成する
* @param array $attributes 属性
* @return string
*/
function createSelect(array $attributes): string {
global $selectMap;
$array = $selectMap[$attributes['array']]; // optionリスト
if (is_array($array)){
$selectedValue = $attributes['value']; // 選択されたoptionのvalue
unset($attributes['array']);
unset($attributes['value']);
$content = '';
foreach ($array as $p){
if (is_array($p)){
$value = $p[0];
$text = $p[1];
} else {
$value = $p;
$text = $p;
}
$selected ='';
if ($value == $selectedValue){
$selected = ' selected="selected"';
}
$content .= '<option' . $selected . ' value="' .$value . '">' . $text . '<option>';
}
return createElement($attributes, $content, 'select');
}
return '';
}
add_shortcode('select', 'mysite\createSelect');
$selectMap = array();
$selectMap['test_array1'] = [ 10, 20, 30 ];
$selectMap['test_array2'] = [ [10, 'AAA'], [20, 'BB'], [30, 'CCCC'] ];
投稿ページなどに以下のように記述しておくと、
[a href='mysite/dummy1.php']登録[/a]
[button onclick="location.href='mysite/dummy2.php'" value='更新']
[select array='test_array2' value='20' onchange="location.href='mysite/dummy3.php'"]
展開されて、以下のようなHTMLが生成される。onclickやonchange属性でlocation.hrefを使うのを避けたい場合には、<form>
内で formaction属性を使ってもよい。
<a href="mysite/dummy1.php">登録</a>
<input onclick="location.href='mysite/dummy2.php'" value="更新" type="button">
</input>
<select onchange="location.href='mysite/dummy3.php'">
<option value="10">AAA<option>
<option selected="selected" value="20">BB<option>
<option value="30">CCCC<option>
</select>
例3: 任意の.phpファイルをロードする例
ハンドラ関数は、本来、HTMLの要素(element)を生成するためのシグニチャになっているが、遷移先のHTMLをごっそり生成したり、HTMLのごく一部の部品だけを生成してもよい。また、副作用のみを利用して、stringを返さなくてもよい。
ob_start()とob_get_clean()を利用して、指定の.phpファイルから遷移先のHTMLを生成する例をあげておく。loadFile()という関数にショートコード名を付けて登録しておく。名前を例えば、'load'としておこう。
<?php
namespace mysite;
require_once ABSPATH . '/wp-includes/shortcodes.php';
/**
* ファイルを読み込む(テキストを返す)
* @param array $attributes 属性 { path, echo }
* @return string
*/
function loadFile(array $attributes): string {
if (empty($attributes)){
return '$attributes is empty at shortcodeHandler::loadFile';
}
if (!isset($attributes['path'])){
return '$path is empty at shortcodeHandler::loadFile';
}
// 例えば、path='mysite/test.php'のような相対パスで指定する。
$path = $attributes['path'];
// 絶対パスを取得する。
$abspath = __DIR__ . '/../' . $path;
if (!file_exists($abspath)){
return 'Not found ' . $abspath . ' at shortcodeHandler::loadFile';
}
// 指定の.phpを実行し、出力されたテキストを取り込んで返す。
// .php内でechoやprintで標準出力に吐き出している場合には出力制御関数も使える。
$echo = false;
if (isset($attributes['echo'])){
$s = strtolower($attributes['echo']);
$echo = ($s == 'true' || $s == 'on' || $s == '1');
}
if ($echo) ob_start();
include($abspath);
return $echo ? ob_get_clean() : '';
}
add_shortcode('load', 'mysite\loadFile');
固定ページや投稿ページから呼び出すときには、以下の感じ。ショートコード名(load)とパラメータ(path)を指定する。pathで指定した.phpファイルがロードされ実行される。更新系の操作などで副作用のみで十分であれば、echoの指定は不要である。.php内でechoやprintを使用して標準出力を利用している場合、echo='true'を添えると出力したテキストが取得できる。
[load path='mysite/dummy1.php']
[load path='mysite/dummy2.php' echo='true']
このloadショートコードを埋め込んでおくと、HTMLでのアクション(<a>
タグ、<input>
タグ、<select>
タグなど)とは関係なく、任意の箇所から任意の.phpを実行できる。画面遷移してもいいし、HTMLの要素を生成して差し込んでもよい。
../ |
---|