wordpress 囲み型ショートコードの作成

2013年4月22日

囲み型ショートコードはテキストを囲むようなタイプのショートコードで、以下のように記述する。

[ショートコード名 パラメータ=’値’, パラメータ=’値’…] テキスト [/ショートコード名]

囲み型ショートコードの関数の作成

function 関数名($atts, $content = null) {
  extract(shortcode_atts(array(
    'パラメータ1' => '規定値1',
    'パラメータ2' => '規定値2',
    ・・・  
  ), $atts));
  //$content = do_shortcode($content); ショートコードの入れ子に対応する場合
  HTMLなどを出力する処理
  return $html; など  //echo ではなくて return を使用する
}
add_shortcode('ショートコード名', 'ショートコードの関数名');
  • 囲み型の場合、以下の2つのパラメータが渡される
  • $atts:ショートコードのパラメータ(属性)
  • $content:ショートコードで囲まれたテキスト
  • $atts(パラメータ)と $content(テキスト) からHTML などを生成し、その結果を関数の戻り値として返すようにする
shortcode_atts($pairs, $atts)
パラメータ $atts の値で $pairs の値を上書きした配列を返す。
配列は、$pairs のすべてのキーを含み、$atts に存在しても $pairs に存在しないキーは無視される。
extract()
shortcode_atts()で処理された配列を読み取って、その属性名と同じ名前の変数に値を代入する
add_shortcode('ショートコード名', 'ショートコードの関数名')
ショートコードの関数を WordPress に登録して、ショートコードとして動作するようにする。

ショートコードの入れ子

囲み方のショートコードの場合、囲んだテキストの中にさらにショートコードを入れることも考えられる(ショートコードの入れ子)。
内側のショートコードが処理されるようにするには、ショートコードに囲まれたテキストは、$content パラメータに渡されるので、この $content パラメータに対して do_shortcode() を実行すると、テキスト内のショートコードを処理することができる。

タグをエスケープするショートコードの作成例

管理画面の本文エリアで、テキストエディタで入力して pre タグ内にインデントをつけるためにタブを挿入しておいて、その後ビジュアルエディタに切り替えると、インデントの空白(スペースやタグ)が削除されてしまったりするため、テキストエディタのみを使用しているが、HTML タグを記述する際など、ちょっと面倒なので、以下のようなタグをエスケープするショートコードを作成。

使い方は[escp]文字列[/escp]と記述する。
デフォルトでは p 要素のクラス属性なしで出力される。「elem」を指定するとその要素で、「class」を指定するとそのクラスを付けて出力する。

function escp_func($atts, $content = null) {
  extract(shortcode_atts(array(
    'elem' => 'p',
    'class' => '',
  ), $atts));
  if(isset($content)) {
    //classが指定されていれば、エスケープ処理してクラス属性に、指定がなければクラス属性はなし
    $class = ($class)? ' class="' .esc_attr($class). '"' : '';
    $html = "<" . $elem. "${class}>".htmlspecialchars( $content, ENT_QUOTES )."</" . $elem. ">\n";
    return $html; 
  }else{
    return '';
  }
}
add_shortcode('escp', 'escp_func');

このままだと、「wpautop」などで br タグなどが挿入されてしまうので、フィルターの前にショートコードを実行する必要があるので、以下を functions.php に追加。

function run_shortcode_before( $content ) {
  global $shortcode_tags;
  $orig_shortcode_tags = $shortcode_tags;  // 現在のショートコードの登録情報をすべてバックアップ
  remove_all_shortcodes();  // 現在のショートコードの登録情報を一時的にすべて削除
  add_shortcode('escp', 'escp_func' );  // フィルターの前に実行するショートコードを登録
  $content = do_shortcode( $content );  // 登録したショートコードの実行
  $shortcode_tags = $orig_shortcode_tags;  // バックアップしておいたショートコードの登録情報を復元
  return $content;
}
add_filter( 'the_content', 'run_shortcode_before', 7 );

定義リストを出力するショートコードの作成例

dt と dd 要素は「|」で区切り、dd 要素を複数持つ場合は、「\dd」で区切る。(ネストはできない)

使い方は、
[dlf]
dt 要素部分のテキスト |
dd 要素部分のテキスト \dd
dd 要素部分のテキスト
[/dlf]

function dl_func($atts, $content=null) {
  extract(shortcode_atts(array(
    'id' => '',
    'class' => '',
  ), $atts));
  $trimmed = trim($content);  //テキストから空白などを取り除いたものを $trimmed に代入
  //空のショートコードを置いたときに、エラーにならないように(空の場合 $elems[1] は存在しない)
  if(isset($content) && ($trimmed)) {
    $elems = explode('|', $content);  //テキストを「|」で区切り、dt 部分とdd 部分に分ける
    $dds = explode('\dd', $elems[1]);  //dd 部分を「\dd」で分割。(デリミタを含まない文字列の場合は、単に元の文字列だけを含む一要素の配列が返るので$ddsは配列になる)  
    $id = ($id)? ' id="' . esc_attr($id). '"': '';
    $class = ($class)? ' class="' .esc_attr($class). '"' : '';
    $html = "<dl${class}${id}>\n";  //先頭の dl タグを生成
    $html .= "<dt>" . htmlspecialchars( $elems[0], ENT_QUOTES ) . "</dt>\n";  //dt 要素を追加
    foreach($dds as $dd) {  //$ddsは配列
      $html .= "<dd>" . htmlspecialchars( $dd, ENT_QUOTES ) . "</dd>\n";  //dd 要素を追加
    }
    $html .= "</dl>\n";
    return $html;
  }else{
    return '';
  }  
}
add_shortcode('dlf', 'dl_func');

これも同様に、「wpautop」などで br タグなどが挿入されてしまうので、フィルターの前にショートコードを実行する必要があるので、前述の「run_shortcode_before() 」に追加。

function run_shortcode_before( $content ) {
  global $shortcode_tags;
  $orig_shortcode_tags = $shortcode_tags;  
  remove_all_shortcodes();
  add_shortcode('dlf', 'dl_func' );  // フィルターの前に実行するショートコードを登録
  add_shortcode('escp', 'escp_func' );
  $content = do_shortcode( $content );  
  $shortcode_tags = $orig_shortcode_tags;
  return $content;
}
add_filter( 'the_content', 'run_shortcode_before', 7 );