• 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細

このWikiはいつでも誰でも編集できます

ショートコード API

提供: WordPress Codex 日本語版
移動先: 案内検索

この項目「ショートコード API」は、翻訳チェック待ちの項目です。加筆、訂正などを通して、Codex ドキュメンテーションにご協力下さい。

ショートコード API は、投稿や固定ページで使える WordPress のショートコードを作るための関数のシンプルなセットです。例えば次のショートコードは(投稿や固定ページの本文に書くと)その投稿や固定ページへ添付されたイメージのギャラリーを追加します:

[gallery]

この API を使ってプラグイン開発者は特別な種類のコンテンツ(例えばフォームやコンテンツ生成器)を作成できます。ユーザーはそれに対応するショートコードをページのテキストに追加して、そのコンテンツをページへ追加できます。

ショートコード API は次の例のように属性をサポートするショートコードも簡単に作成できます:

[gallery id="123" size="medium"]

API が手の込んだパーシング(構文解析)を処理するので、いちいちショートコードに独自の正規表現を書く必要はありません。属性にデフォルトを設定し取り込むヘルパー関数が含まれています。API は自己完結型ショートコードと囲み型ショートコードの両方をサポートします。

手っ取り早く使い始めたい人のために、ショートコードを作成するのに最低限必要な PHP コードの例を示します:

// [foobar]
function foobar_func( $atts ){
	return "foo and bar";
}
add_shortcode( 'foobar', 'foobar_func' );

これで [foobar] ショートコードが作られて、使用すると次の値を返します: foo and bar

属性を持つショートコードの場合は:

// [bartag foo="foo-value"]
function bartag_func( $atts ) {
    $a = shortcode_atts( array(
        'foo' => 'something',
        'bar' => 'something else',
    ), $atts );

    return "foo = {$a['foo']}";
}
add_shortcode( 'bartag', 'bartag_func' );

このコードは、[bartag] ショートコードを作成し、2つの属性 foobar をサポートします。どちらの属性もオプションで、省略するとデフォルト値 foo="something"bar="something else" が入ります。そして foo = {foo 属性の値} を返します。

ショートコードを作るにはハンドラー関数を記述します。おおまかに言うとショートコードハンドラーは WordPress のフィルターと似ています。フィルターがパラメータを受け取って結果を返すように、ハンドラーは属性を受け取ってショートコード出力を返します。

ショートコードの名前は英小文字、数字、下線を使う必要があります。特にハイフン(ダッシュ)には注意して、使わないのが賢明です。

ショートコードハンドラーを登録するには add_shortcode 関数を使います。この関数には2つのパラメータ、ショートコード名(投稿の本文で使う文字列)とコールバック関数の名前を渡します。

ショートコードのコールバック関数には3つのパラメータが渡されます。いくつ使うか、どれも使わないかはあなたの自由です。

  • $atts - 属性の連想配列、または空文字列(属性が省略された場合)
  • $content - 囲まれたコンテンツ(囲み型ショートコードとして使われた場合)
  • $tag - ショートコードのタグ。共有コールバック関数の場合に便利です

ショートコードハンドラーを登録する API 呼び出しは例えば次のようになります;

add_shortcode( 'myshortcode', 'my_shortcode_handler' );

the_content が表示されるとき、ショートコード API は [myshortcode] のような登録済みショートコードをパースして、属性と (存在するならば) コンテンツを分離してパースし、対応するショートコードハンドラー関数へ渡します。ショートコードハンドラが返した(表示されたのではなく)文字列はショートコードの代わりにページの本文へ挿入されます。

次のようにショートコードの属性が入力されたとしましょう:

[myshortcode foo="bar" bar="bing"]

属性は次のような連想配列に変換され、$atts パラメータとしてハンドラー関数へ渡されます:

array( 'foo' => 'bar', 'bar' => 'bing' )

配列のキーは属性名で、値は対応する属性値です。

属性の処理

生の $atts 配列にはユーザーが指定した任意の属性が含まれている可能性があります。

省略された属性にデフォルト値を付与し、ショートコードが認識しない属性をすべて取り除くために、API には shortcode_atts() 関数が用意されています。

shortcode_atts()wp_parse_args 関数に似ていますが、いくつか重要な違いがあります。パラメータは以下のとおりです:

shortcode_atts( $defaults_array, $atts );

両方のパラメータが必須です。$defaults_array は認識される属性名とそのデフォルト値を指定する連想配列です。$atts はショートコードハンドラーに渡された生の属性配列です。shortcode_atts() は、$defaults_array のキーを全て含み、$atts 配列に値が存在すればその値を上書きした、正規化された配列を返します。例を以下に示します:

$a = shortcode_atts( array(
    'title' => 'My Title',
    'foo' => 123,
), $atts );

もし $atts の内容が array( 'foo' => 456, 'bar' => 'something' ) なら、結果の $aarray( 'title' => 'My Title', 'foo' => 456 ) になります。$atts['foo'] の値はデフォルト値 123 を上書きします。$atts['title'] は設定されていないので、デフォルト値 'My Title' が使用されます。デフォルト配列には 'bar' 要素がないので、結果に含まれません。

属性の名前はハンドラー関数へ渡される前にいつも小文字へ変換されます。値はそのままです。[myshortcode FOO="BAR"]$atts = array( 'foo' => 'BAR' ) になります。

ショートコードハンドラーでデフォルトを宣言して属性をパースする推奨のコード形式は以下のとおりです:

function my_shortcode_handler( $atts, $content = null ) {
    $a = shortcode_atts( array(
        'attr_1' => 'attribute 1 default',
        'attr_2' => 'attribute 2 default',
        // ...etc
    ), $atts );
}

これは属性をパースし、デフォルトを設定し、サポートされない属性を除去し、結果をローカルの配列変数 $a へ入れます。その配列は属性がキーになります($a['attr_1']$a['attr_2'] など)。見方を変えると、デフォルトの配列はローカル変数の宣言のリストみたいなものです。


重要なヒント - $atts の属性名にキャメルケースや大文字を使わない 
$atts の値は shortcode_atts( array( 'attr_1' => 'attr_1 default', // ...etc ), $atts ) の処理前に小文字にされているので、小文字だけを使うようにしましょう。


出力

ショートコードハンドラー関数の返り値はショートコードマクロの代わりに投稿コンテンツの出力へ挿入されます。 echo ではなく return を使うようにしてください。echo されたものはすべてブラウザへ出力されますが、ページの適切な箇所に表示されません。

ショートコードは wpautop および wptexturize による投稿の整形適用後にパースされます(2.5.02.5.1 の違いについては後の注記を参照してください)。つまりショートコードが出力した HTML には、例えば曲線形のクォートが適用されず、p タグや br タグが追加されません。ショートコードの出力を整形したい場合は、ショートコードハンドラーから出力を返すときに wpautop()wptexturize() を直接呼び出す必要があります。

wpautop はショートコードの構文を認識し、ショートコードだけが書かれた行を p あるいは br タグで括らないようにします。この方法で使用されることを前提とするショートコードは、出力を <p><div> などの適切なブロックタグで括る必要があります。

参考:WordPress 2.5.0では、ショートコードは投稿の整形を行う前にパースされるので、ショートコードが出力した HTML が p タグや br タグで括られることがありました。これは正しくない動作だったので 2.5.1 で修正されました。

ショートコードが大量の HTML を生成する場合、次のように ob_start を使って出力を取り込んでから文字列へ変換することができます:

function my_shortcode() {
	ob_start();
	?> <HTML> <here> ... <?php
	return ob_get_clean();
}


囲み型ショートコードと自己完結型ショートコード

上で示した例は [myshortcode] のような自己完結型ショートコードマクロでした。ショートコード API は [myshortcode]コンテンツ[/myshortcode] のような囲み型ショートコードもサポートしています。

ショートコードマクロがコンテンツを囲むように使用された場合、ハンドラー関数はそのコンテンツを第2パラメータとして受け取ります。ユーザーはショートコードをどちらの形式で記述しても構いません。そのためハンドラー関数の第2パラメータにデフォルト値を与えておくことによりどちらのケースにも対応する必要があります。

function my_shortcode_handler( $atts, $content = null )

こうすれば is_null( $content ) を使用して囲み型と自己完結型を区別することができます。

コンテンツがタグで囲まれている場合は、そのコンテンツを含むショートコードマクロ全体が関数の出力で置き換えられます。生のコンテンツ文字列に必要なエスケープやエンコードを適用し、出力に含める処理は、ハンドラー関数が行う必要があります。

囲み型ショートコードの例を以下に示します:

function caption_shortcode( $atts, $content = null ) {
    return '<span class="caption">' . $content . '</span>';
}

これを次のように使用すると:

[caption]My Caption[/caption]

出力は以下のようになります:

<span class="caption">My Caption</span>

$content はエスケープやエンコードされずに返り値へ含められるので、ユーザーが生の HTML を含めることができます:

[caption]<a href="http://example.com/">My Caption</a>[/caption]

これは次のような結果を生成します:

<span class="caption"><a href="http://example.com/">My Caption</a></span>

これは意図したとおり、またはそうではない動作かもしれません。ショートコードが生の HTML の出力を許可しないようにするには、エスケープまたはフィルター関数を使用してから結果を返すようにしてください。

ショートコードのパーサーは投稿コンテンツを一度だけパースします。つまりショートコードハンドラーの $content パラメータが別のショートコードを含む場合、それはパースされません。次の場合:

[caption]Caption: [myshortcode][/caption]

出力はこうなるでしょう:

<span class="caption">Caption: [myshortcode]</span>

囲み型ショートコードが出力に他のショートコードを許可する場合、ハンドラー関数が do_shortcode() を再帰的に呼び出すことができます。

function caption_shortcode( $atts, $content = null ) {
    return '<span class="caption">' . do_shortcode($content) . '</span>';
}

この例では、タグで囲まれたコンテンツ内の [myshortcode] マクロがパースされることが保証され、出力は caption クラスの span タグで囲まれます。

<span class="caption">Caption: myshortcode のハンドラー関数の結果</span>

パーサーは同じショートコードの囲み型と自己完結型のミックスを、そうして欲しいようには処理しません。例えば次のように書いたとします:

[myshortcode example='non-enclosing' /] non-enclosed content [myshortcode] enclosed content [/myshortcode]

これを「 non-enclosed content 」というテキストで区切られた2つのショートコードとして処理するのではなく、パーサーは「 non-enclosed content [myshortcode] enclosed content 」を囲むひとつのショートコードとして処理します。

囲み型ショートコードは自己完結型ショートコードと同様に属性をサポートします。class 属性をサポートするように改良された caption_shortcode() の例を以下に示します:

function caption_shortcode( $atts, $content = null ) {
    extract( shortcode_atts( array(
       'class' => 'caption',
       ), $atts ) );
  
    return '<span class="' . esc_attr($class) . '">' . $content . '</span>';
}

これで次のようなコンテンツを処理させると:

[caption class="headline"]My Caption[/caption]

次のように出力されます:

<span class="headline">My Caption</span>

その他の機能

  • パーサーは [myshortcode /] のような xhtml スタイルのショートコードをサポートしていますが、これはオプションです。
  • ショートコードマクロの属性の値にはシングルクォートとダブルクォートのどちらも使えます。属性の値が空白を含まない場合はクォートを省略できます。[myshortcode foo='123' bar=456][myshortcode foo="123" bar="456"] と同等です。参考:最後尾の属性の値はスラッシュ「/」で終わることができません。ひとつ前に説明した機能がそのスラッシュを消してしまうためです。
  • 古くてアドホックなショートコードとの後方互換性のため、属性名を省略することができます。属性名がない場合は位置を表す数値キーをつけて $atts 配列へ入れられます。例えば、[myshortcode 123]$atts = array( 0 => 123 ) を生成します。属性名を省略した属性と属性名のある属性を混ぜて使うことができます。そして値が空白や他の特殊文字を含む場合はクォートを使用することができます。

関数リファレンス

利用可能なショートコード API 関数を、以下に示します。

add_shortcode()

function add_shortcode( $tag, $func )

新しいショートコードハンドラー関数を登録します。$tagmyshortcode のようなユーザーによって記述されるショートコード文字列(角括弧 [] を除いたもの)です。$func はハンドラー関数名です。

ひとつのショートコードには1つのハンドラー関数のみが存在できます。同じ $tag 名に対して再び add_shortcode() を呼び出すと以前のハンドラーが上書きされます。

remove_shortcode()

function remove_shortcode( $tag )

既存のショートコードを抹消します。$tagadd_shortcode() で使用されるショートコード名です。

remove_all_shortcodes()

function remove_all_shortcodes()

すべてのショートコードを抹消します。

shortcode_atts()

function shortcode_atts( $pairs, $atts )

$pairs で指定されているデフォルト値に対して、生の属性の配列 $atts を処理します。配列を返します。結果は $pairs のすべてのキーを含み、$atts の値をマージしたものになります。$atts に存在しても $pairs に存在しないキーは無視されます。

do_shortcode()

function do_shortcode( $content )

$content 文字列に含まれる既知のショートコードをパースします。元のコンテンツに含まれたショートコードマクロがハンドラー関数の出力で置き換えられた文字列を返します。

do_shortcode()'the_content' フックのデフォルトフィルターとして優先度11で登録されます。


制限事項

入れ子のショートコード

ショートコードパーサーは、再帰的に do_shortcode() を呼び出すことでハンドラー関数がサポートしていれば、入れ子になったショートコードマクロを正しく処理することができます:

[tag_a]
   [tag_b]
      [tag_c]
   [/tag_b]
[/tag_a]

しかしショートコードマクロが同じ名前のマクロをもうひとつ囲むように使用するとパースに失敗します:

[tag_a]
   [tag_a]
   [/tag_a]
[/tag_a]

これは do_shortcode() で使われる文脈自由正規表現パーサーの制限によるものです。このパーサーはとても高速ですが入れ子のレベルを数えることができません。そのためこの場合にはそれぞれの開始タグを正しい終了タグとマッチさせることができません。

WordPress の将来のバージョンでは、wptexturize() の処理が内側のコードを邪魔しないようにすることが、入れ子のショートコードを持つプラグインに対して求められるかもしれません。そういう複雑な構文の場合、外側のタグについて no_texturize_shortcodes /en フィルターの適用が推奨されます。ここで用いた例でいうと、texturize しないショートコードのリストへ tag_a を追加すべきです。tag_a や tag_b のコンテンツを texturize する必要があるなら、上で説明したように do_shortcode() の呼び出し前に wptexturize() を呼び出すことができます。

未登録のショートコード名

一部のプラグイン作者はショートコード名を登録しないという戦略を選んでいます。これは例えば親のショートコードのハンドラー関数が呼び出されるまで入れ子のショートコードを無効化するためです。これはショートコードの属性値のパースを失敗するような、意図しない結果をもたらすかもしれません。例えば:

[tag_a unit="north"]
   [tag_b size="24"]
      [tag_c color="red"]
   [/tag_b]
[/tag_a]

バージョン 4.0.1 以降、プラグインが tag_b と tag_c を有効なショートコードとして登録し損なうと、wptexturize() の処理はショートコードのパースを始める前に次のようなテキストを出力します:

[tag_a unit="north"]
   [tag_b size=&#8221;24&#8221;]
      [tag_c color=&#8221;red&#8221;]
   [/tag_b]
[/tag_a]

未登録のショートコードは特別な意味を持たない普通のプレーンなテキストとして扱われるべきであり、ショートコードをわざと未登録にするのは勧められません。もしショートコードの間に生のコードをはさみ込む必要があるなら、少なくとも tag_a のコンテンツの texturize 処理を避けるために no_texturize_shortcodes /en フィルターの使用を検討してください:

add_shortcode( 'tag_a', 'my_tag_a_handler' );
add_filter( 'no_texturize_shortcodes', 'ignore_tag_a' );

function ignore_tag_a( $list ) {
  $list[] = 'tag_a';
  return $list;
}

閉じないショートコード

ある状況ではショートコードのパーサーが閉じたショートコードと閉じないショートコードの両方を正しく処理できません。例えば次の場合、パーサーは2番目のショートコードだけを正しく識別します:

[tag]
[tag]
   コンテンツ
[/tag]

しかし次の場合はパーサーが両方とも識別します:

[tag]
   コンテンツ
[/tag]
[tag]

ハイフン

参考: 以下で説明するハイフン ('-') を使ったショートコードに関する動作は WordPress 3 以上にも当てはまります。これは do_shortcode() や get_shortcode_regex() のバグによるものかもしれません。

ショートコードの名前にハイフンを使うときは注意してください。次の例では WordPress が2番目のショートコードを1番目と同じだと見る場合があります(WordPress は基本的にハイフンより前の部分を見ます):

[tag]
[tag-a]

結果はどのショートコードが最初に定義されたかに完全に依存します。もしハイフンを使うつもりなら一番短いショートコードを最初に定義してください。

これを避けるには下線を使うか、区切り文字なしにしてください:

[tag]
[tag_a]

[tag]
[taga]

ショートコードの最初の部分がどれも異なっていれば、ハイフンを使っても問題ありません:

[tag]
[tagfoo-a]

重要: ハイフンを使うと知らないうちに影響を与える可能性があります。もしインストールされた他のショートコードもハイフンを使っていると、ハイフンをつけた一般的な単語が衝突するかもしれません(同じリクエスト内で両方のショートコードが使われた場合):

// plugin-A
[is-logged-in]

// plugin-B
[is-admin]

角括弧

ショートコードのパーサーは属性に含まれる角括弧を受け付けません。そのため次の使い方は失敗します:

[tag attribute="[Some value]"]

飾りの角括弧 (cosmetic brackets) で囲まれたタグは wptexturize() やそのフィルターで完全にはサポートされていません。そのため次のコードは予想外の結果になるかもしれません:

[I put random text near my captions. [caption]]

参考: これらの制限は WordPress の将来のバージョンで変わるかもしれませんので、確実さを求めるならテストすべきです。

HTML

バージョン 3.9.3 から、ショートコードの属性内の HTML 使用は制限されるようになりました。例えば次のショートコードは「>」文字を含むので正しく動作しません:

[tag value1="35" value2="25" compare=">"]

バージョン 4.0 は予め認められた HTML を許すようになったので、次のコードは動作します:

[tag description="<b>Greetings</b>"]

HTML の制限に対する推奨の回避方法は、すべてのユーザー入力に HTML エンコードを行った上で、カスタムショートコードハンドラー内で HTML デコードを行うというものです。拡張 API 関数が計画されています。

ショートコード属性における HTML のフルサポートはこれまで公式に行われたことはなく、将来のバージョンで拡張される予定もありません。

バージョン 4.2.3 からは、類似の制限が HTML 内でのショートコード利用に対しても行われました。例えば次のショートコードは、スクリプト属性の入れ子なので正しく動作しません:

<a onclick="[tag]">

動的な属性値に対する推奨の回避方法は、ひとつだけ値を出力するのでなく必要な HTML 全体を出力するショートコードを設計するというものです。これは動くでしょう:

[link onclick="tag"]

また次のショートコードは属性のクォートが正しくないので使用できません:

<a title="[tag attr="id"]">

これを正しい HTML としてパースする唯一の方法はシングルクォートとダブルクォートによる入れ子を使うというものです:

<a title="[tag attr='id']">

登録する個数

ショートコードを数百個も登録すると API が不安定になることが知られています。プラグイン作者は少数のショートコード名だけで実現できる解決方法を用意すべきです。この制限は将来のバージョンで変わる可能性があります。


正式な構文

WordPress のショートコードは特殊文字の扱いが HTML とは異なります。角括弧は一見魔法のように思えますが、決してどんな言語の一部でもありません。例えば:

[gallery]

gallery ショートコードは登録済みショートコードなので API によって特別なシンボルとしてパースされます。一方、ショートコードが登録されていなければ角括弧は単に無視されます:

[randomthing]

randomthing シンボルと角括弧は登録済みショートコードの一部ではないので無視されます。

完璧な世界なら、どんな [*] シンボルも API で扱うことができるでしょう。しかし次のようなチャレンジを考えておく必要があります:角括弧 ( [・] ) は HTML の中で使うことができて常にショートコードというわけではなく、山括弧 ( <・> ) は限られた状況でのみショートコード内で使うことができ、そしてショートコードは出力される前に何層ものカスタマイズ可能なフィルターとパーサーを潜り抜けなければなりません。こうした言語の互換性問題があるので、角括弧は魔法になれません。

ショートコード構文は次のような一般形を使います:

[名前 属性 閉じる]
[名前 属性]任意の HTML やショートコードをここへ書くことができる。[/名前]

エスケープされたショートコードは角括弧がちょうど2つ多いだけで同じ形になります:

[[名前 属性 閉じる]]
[[名前 属性]任意の HTML やショートコードをここへ書くことができる。[/名前]]

繰り返しますがショートコード名は登録されている必要があります。さもないと4つの例はどれも無視されます。

ショートコード名

ショートコードの名前は以下の文字を絶対に含んではいけません:

  • 角括弧: [ ]
  • 山括弧: < >
  • アンパサンド: &
  • スラッシュ: /
  • 空白: スペース 改行(ラインフィード) タブ
  • 印刷できない文字: \x00 - \x20

クォートもショートコード名に含めないことを推奨します:

  • クォート: ' "

属性

属性はオプションです。ショートコード名とショートコードの属性の間にひとつスペースが必要です。2つ以上の属性を使うときは少なくともひとつのスペースで区切らなければなりません。

ひとつひとつの属性は次のいずれかの形式に従う必要があります:

属性名 = '値'

属性名 = "値"

属性名 = 値

"値"

値

属性名はオプションです。どのプラットフォームでも互換性を保つために次の文字だけを含む必要があります:

  • 大文字と小文字のアルファベット: A-Z a-z
  • 数字: 0-9
  • 下線: _
  • ハイフン: - (バージョン 4.3.0 より前は使えませんでした)

属性名にスペースは使えません。名前と = の間、それから = と値の間にスペースを入れても構いません。

属性値は次の文字を含んではいけません:

  • 角括弧: [ ]
  • クォート: " '

クォートで囲まない値は絶対にスペースを含んではなりません。

HTML 文字の <> は属性の中で限定的な使用がサポートされます。

ショートコード属性の中で特殊文字をエスケープする推奨の方法は HTML エンコードです。一番重要なのは、ショートコード属性にユーザーが入力した値を入れるなら必ずエスケープするか特殊文字を除去することです。

参考:シングルクォートで囲んだ値にダブルクォートを含めることができます。その逆も可能です。しかしこの方法はユーザー入力を扱うときは推奨されません。

次の文字は、属性値の中でエスケープされなければ、自動的に除去されてスペースへ置換されます:

セルフクロージング

セルフクロージングの印(スラッシュひとつ)はオプションです。印の前のスペースはオプションです。印の後にスペースを入れるのは禁止です。

[example /]

セルフクロージングの印は純粋に飾りであって効果を持ちませんが、ショートコードのパーサーはその後に来る「閉じるタグ」を無視します。

囲み型ショートコードはセルフクロージングの印を使ってはいけません。

エスケープ

WordPress は [name] と [/name] タグに挟まれた部分へ曲線形のクォートを入れようとします。他の部分と同じように処理するわけです。4.0.1 以降、未登録のショートコードも同様に「texturize」されるので予期しない曲線形のクォートが入る場合があります:

[randomthing param="test"]

良い例は次のようなものです:

<code>[randomthing param="test"]</code>

<code> 要素はいつも texturize 処理の対象外になります。

登録済みショートコードは <code> 要素の内側でも処理されます。登録済みショートコードを web サイトへ表示するためにエスケープする書き方は次のようになります:

[[caption param="test"]]

... このように出力されます ...

[caption param="test"]

この状況では <code> 要素はオプションです。


外部リソース

デフォルトで使えるショートコード

活用事例

変更履歴

  • 2.5.1 :
    • do_shortcode()the_content でのプライオリティが 11 になりました。
  • 2.5 : 新規導入


ショートコード: do_shortcode(), add_shortcode(), remove_shortcode(), remove_all_shortcodes(), shortcode_atts(), strip_shortcodes() /en, shortcode_exists(), has_shortcode(), get_shortcode_regex() /en, wp_audio_shortcode(), wp_video_shortcode(), フック no_texturize_shortcodes /en


最新英語版: WordPress Codex » Shortcode API最新版との差分