囲み型ショートコードはテキストを囲むようなタイプのショートコードで、以下のように記述する。
[ショートコード名 パラメータ=’値’, パラメータ=’値’…] テキスト [/ショートコード名]
function 関数名($atts, $content = null) { extract(shortcode_atts(array( 'パラメータ1' => '規定値1', 'パラメータ2' => '規定値2', ・・・ ), $atts)); //$content = do_shortcode($content); ショートコードの入れ子に対応する場合 HTMLなどを出力する処理 return $html; など //echo ではなくて return を使用する } add_shortcode('ショートコード名', 'ショートコードの関数名');
囲み方のショートコードの場合、囲んだテキストの中にさらにショートコードを入れることも考えられる(ショートコードの入れ子)。
内側のショートコードが処理されるようにするには、ショートコードに囲まれたテキストは、$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 );