べんりワザ・WordPressのカスタマイズの土台

ショートコードの作り方(add_shortcode)

記事の中に[myform]と書くだけで機能を呼び出せるショートコードの作り方。属性の受け取り方、囲み型の書き方、テンプレートで使うdo_shortcode、動かないときの原因をまとめました。

ショートコードは、記事の本文に[myform]と書くだけで機能を呼び出せる仕組みです。「編集する人にHTMLを書かせずに、決まった部品を置いてもらう」のに向いています。

作り方は2行です。

function my_year_shortcode() {
  return esc_html(date('Y'));
}
add_shortcode('year', 'my_year_shortcode');

これで、記事に[year]と書くと2026と表示されます。

属性を受け取る

[box color="red"]のように属性で見た目や中身を変えられるのが、ショートコードの本当の便利さです。

function my_badge_shortcode($atts) {
  $a = shortcode_atts([
    'label' => 'NEW',
    'color' => 'pink',
  ], $atts, 'badge');

  return sprintf(
    '<span class="badge badge--%s">%s</span>',
    esc_attr($a['color']),
    esc_html($a['label'])
  );
}
add_shortcode('badge', 'my_badge_shortcode');

記事側ではこう書きます。

[badge]                          → NEW(pink)
[badge label="限定" color="blue"] → 限定(blue)

shortcode_atts()既定値を決めて、指定された属性だけ上書きする関数です。これを通しておくと、属性が書かれていないときのUndefined indexエラーを防げます。

囲み型(開始と終了があるもの)

function my_note_shortcode($atts, $content = '') {
  $a = shortcode_atts(['title' => 'ポイント'], $atts, 'note');

  return sprintf(
    '<div class="note"><p class="note__title">%s</p>%s</div>',
    esc_html($a['title']),
    wp_kses_post(do_shortcode($content))   // 中のHTMLとショートコードも処理する
  );
}
add_shortcode('note', 'my_note_shortcode');
[note title="注意"]
ここに<strong>本文</strong>を書けます。
[/note]

第2引数の$contentに囲まれた中身が入ります。do_shortcode($content)を通すと、入れ子のショートコードも動きます。中身のHTMLを許可するときはwp_kses_post()で危険なタグを取り除きます。

べんりワザエスケープ関数の使い分け(esc_html・esc_attr・esc_url)エスケープ関数の使い分けはこちら

HTMLが長いときはob_startで受ける

テンプレートのようにHTMLを書きたいときは、出力バッファを使うと読みやすくなります。

function my_products_shortcode($atts) {
  $a = shortcode_atts(['count' => 3], $atts, 'products');

  $query = new WP_Query([
    'post_type'      => 'shohin',
    'posts_per_page' => (int) $a['count'],
  ]);

  ob_start();   // ここから出力を溜める
  ?>
  <?php if ($query->have_posts()) : ?>
    <ul class="products">
      <?php while ($query->have_posts()) : $query->the_post(); ?>
        <li>
          <a href="<?php the_permalink(); ?>">
            <?php the_post_thumbnail('medium'); ?>
            <span><?php the_title(); ?></span>
          </a>
        </li>
      <?php endwhile; ?>
    </ul>
  <?php endif; ?>
  <?php
  wp_reset_postdata();

  return ob_get_clean();   // 溜めた出力を文字列として返す
}
add_shortcode('products', 'my_products_shortcode');

記事に[products count="6"]と書けば、商品一覧が入ります。編集する人がPHPを触らずに一覧を置ける——これがショートコードの主な使い道です。

べんりワザループの外で投稿を取得する方法(WP_Query)WP_Queryの書き方と後始末はこちら

テンプレートの中で使う

<?php echo do_shortcode('[products count="4"]'); ?>

プラグインが提供するショートコード(お問い合わせフォームなど)をテンプレートに埋めこみたいときに使います。自作の機能なら、ショートコードを経由せず関数を直接呼ぶほうがシンプルです。

ウィジェットや抜粋で動かないとき

  • 抜粋——ショートコードは処理されず、記述が取り除かれます(仕様)
  • テキストウィジェット——最近のWordPressでは動作します
  • メールの本文など——do_shortcode()を自分で通す必要があります

名前の付け方の注意

  • 短すぎる汎用名を避ける[box] [button]はプラグインとぶつかりやすい)
  • 接頭辞を付けると安全([shimaenaga_box]
  • ハイフンよりアンダースコアが無難

同じ名前を後から登録したほうが勝つため、衝突すると意図しない出力になります。

ブロックエディタの時代にどう使う?

ブロックエディタでは、再利用ブロックや同期パターンで似たことができます。ショートコードが今も有効なのは、こういう場面です。

  • 属性で内容を変えたい(件数・色・IDなど)
  • PHPの処理が必要(投稿を取得する・計算する)
  • 記事本文以外でも使いたい(ウィジェット・テンプレート)

逆に「決まったHTMLを貼るだけ」なら、パターン機能のほうが編集する人にやさしいです。

まとめ

  1. add_shortcode('名前', '関数名')だけで作れる。関数は必ずreturnで文字列を返す
  2. 属性はshortcode_atts()で既定値を決めて受け取る。囲み型は第2引数$content
  3. HTMLが長いときはob_start()ob_get_clean()で組み立てる
  4. 長く使う機能は自作プラグインに置く——テーマを変えても消えない

「編集する人がHTMLを書かずに部品を置ける」状態は、運用のしやすさに直結します。

よくある質問

ショートコードはどこに書きますか?
functions.phpまたは自作プラグインにadd_shortcode('名前', '関数名')を書きます。テーマを変えても使い続けたい機能はプラグインに置くのがおすすめです(テーマを変えるとショートコードが文字列のまま表示されてしまうため)。
ショートコードが記事にそのまま文字で表示されます
そのショートコード名が登録されていない状態です。関数名のスペル、add_shortcodeの実行タイミング(initなど早い段階で登録)、テーマやプラグインを切り替えていないかを確認してください。
ショートコードの中でechoしてもいいですか?
いけません。ショートコードは「文字列を返す」約束なので、returnで返します。HTMLが長い場合はob_start()とob_get_clean()で出力を文字列として受け取ってからreturnします。
テンプレートファイルの中でショートコードを使えますか?
echo do_shortcode('[myform]'); で使えます。ただし自作の機能なら、ショートコードを経由せず関数を直接呼ぶほうがシンプルです。