0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WordPressでのショートコードの使い方

Last updated at Posted at 2022-07-04
../

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 に変更しておこう。

wp-includes/functions.php
require_once ABSPATH . '/mysite/shortcodeHandler.php';		// 末尾に追加
wp-settings.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() でショートコードを定義する。

mysite/shortcodeHandler.php
<?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の配列をセットしている。

mysite/shortcodeHandler.php
<?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'としておこう。

mysite/shortcodeHandler.php
<?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の要素を生成して差し込んでもよい。

../
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?