ショートコードを作るとき、[box color="red"] のように属性で見た目や動作を切り替えたくなることがあります。このとき欠かせないのが shortcode_atts() です。利用者が指定した属性と、あらかじめ用意した初期値を組み合わせて、扱いやすい配列にまとめてくれる関数です。この記事では shortcode_atts() の基本的な使い方、初期値の設定、属性が指定されなかったときの挙動、そしてつまずきやすいポイントまでを、実際のコードで解説します。なお、ショートコード自体の登録方法(add_shortcode())の基本は理解している前提で進めます。
目次
なぜ shortcode_atts が必要なのか
ショートコードのコールバック関数には、第1引数として「利用者が指定した属性」が配列で渡されます。たとえば [box color="red"] と書かれていれば ['color' => 'red'] が渡ってきます。ところが、利用者が [box] のように属性を省略すると、その項目はそもそも配列に存在しません。そのまま $atts['color'] を読もうとすると「未定義キー」の警告が出てしまいます。
shortcode_atts() は、こうした「指定されたりされなかったりする属性」を安全に扱うための関数です。あらかじめ用意した初期値の配列と、利用者が指定した属性をつき合わせ、足りない項目は初期値で埋めた配列を返します。これにより、どの属性も必ず存在する状態でコードを書けます。
基本の使い方
shortcode_atts() は、第1引数に「初期値の配列」、第2引数に「利用者が指定した属性(コールバックの $atts)」を渡します。戻り値は、初期値をベースに利用者の指定で上書きした配列です。
function my_box_shortcode( $atts, $content = null ) {
// 初期値と、利用者が指定した属性を組み合わせる
$a = shortcode_atts(
array(
'color' => 'gray', // 指定がなければ gray
'size' => 'medium',
),
$atts
);
return '<div class="box box--' . esc_attr( $a['color'] )
. ' box--' . esc_attr( $a['size'] ) . '">'
. esc_html( $content ) . '</div>';
}
add_shortcode( 'box', 'my_box_shortcode' );
この状態で [box color="red"]テキスト[/box] と書くと、color は red、指定しなかった size は初期値の medium になります。どちらの属性も必ず値を持つので、$a['size'] を安心して読めます。
引数と戻り値
shortcode_atts() が受け取る引数と返すものは次のとおりです。第3引数は省略できますが、指定するとフィルターフックの名前づけに使われます。
| 項目 | 説明 |
|---|---|
第1引数 $defaults | 許可する属性名とその初期値をまとめた配列 |
第2引数 $atts | 利用者が指定した属性(コールバックの第1引数をそのまま渡す) |
第3引数 $shortcode | ショートコード名(省略可)。指定すると shortcode_atts_{$shortcode} フィルターが使える |
| 戻り値 | 初期値を利用者の指定で上書きした配列 |
初期値にない属性は捨てられる
shortcode_atts() の重要な性質として、第1引数の初期値に書かれていないキーは、利用者が指定しても戻り値に含まれません。これは想定外の属性を弾く安全策として働きます。たとえば初期値に color と size しか定義していなければ、[box width="100"] のように指定された width は結果の配列に入りません。
つまり、ショートコードで受け付けたい属性は、必ず第1引数の初期値に列挙しておく必要があります。「属性を追加したのに値が反映されない」という場合は、初期値の配列にそのキーを書き忘れていないかを最初に確認しましょう。
属性名は小文字に変換される
WordPress は、ショートコードの属性名をすべて小文字に変換してからコールバックに渡します。そのため、利用者が [box Color="red"] と大文字を混ぜて書いても、コールバックには color として届きます。初期値の配列のキーも小文字でそろえておかないと、うまくつき合わせができず初期値のままになってしまいます。
// 初期値のキーは小文字で定義する
$a = shortcode_atts(
array(
'color' => 'gray', // OK
// 'Color' => ... のように大文字を混ぜると対応しない
),
$atts
);
属性値はすべて文字列で渡る
もう1つ覚えておきたいのが、ショートコードの属性値は数値を書いても文字列として渡るという点です。[box count="3"] の 3 は文字列の "3" です。数として計算したい、あるいは「真偽」で分岐したいときは、コールバック側で型を変換します。とくに [box show="false"] のように false という文字列を渡しても、PHP では空でない文字列なので真として扱われる点に注意が必要です。
$a = shortcode_atts(
array(
'count' => '1',
'show' => 'true',
),
$atts
);
// 数として使うなら整数に変換する
$count = (int) $a['count'];
// 真偽として使うなら文字列を判定する
$show = filter_var( $a['show'], FILTER_VALIDATE_BOOLEAN );
filter_var() に FILTER_VALIDATE_BOOLEAN を渡すと、"true" や "1" は true、"false" や "0" は false と判定してくれます。文字列の "false" を真偽値として扱いたいときに便利です。
属性が反映されないと感じたとき
初期値に書き忘れていないか
前述のとおり、初期値の配列にないキーは結果に含まれません。新しい属性を追加したのに効かないときは、まず shortcode_atts() の第1引数にそのキーを足したかを確認します。ここが最もよくある原因です。
クォートで囲まずに値を書いていないか
属性値にスペースや日本語などが含まれる場合、[box title=こんにちは 世界] のようにクォートで囲まないと、スペース以降が別の属性として解釈されてしまいます。値はダブルクォートで囲む(title="こんにちは 世界")のが基本です。記事の編集中に意図せずクォートが外れていないかも見直してみてください。
まとめ
shortcode_atts() は、ショートコードの属性を初期値とつき合わせ、安全に扱える配列にまとめる関数です。要点を振り返ります。
- 第1引数に初期値、第2引数にコールバックの
$attsを渡す - 利用者が省略した属性は初期値で埋められるので、未定義キーの警告を防げる
- 初期値に列挙していない属性は結果に含まれない(受け付けたい属性は必ず定義する)
- 属性名は小文字に変換されるため、初期値のキーも小文字でそろえる
- 属性値は文字列で渡るので、数値や真偽として使うときは型を変換する
add_shortcode() でショートコードを登録したら、コールバックの先頭で shortcode_atts() を呼ぶ——この流れを定番にしておくと、属性を扱うショートコードを安全に作れます。