2026年7月27日

2026年7月27日

WordPressのショートコードが動かない・文字のまま表示されるときの原因と直し方

ショートコードは、本文に [my_shortcode] のような短い文字列を書くと、WordPressが表示のときにその部分を別の内容に置き換える仕組みです。これが置き換えられずに文字のまま表示される、または思った位置に出ない場合、原因は「ショートコードが登録されていない」「書き方が違う」「その場所ではショートコードが実行されない」のどれかであることがほとんどです。

この記事では、症状から原因を絞り、それぞれの直し方を説明します。内容は2026年10月時点のWordPress 6.8系のソースコードで確認しています。コードはテーマの functions.php か、自作のプラグインに追加します。

症状から原因を絞る

症状 主な原因
どこに書いても [my_shortcode] が文字のまま表示される ショートコードが登録されていない(提供するプラグインの停止、テーマの変更、名前の打ち間違い)
本文では動くが、ウィジェット・カスタムフィールド・テンプレートでは文字のまま その場所でショートコードを実行する処理が呼ばれていない
内容は表示されるが、本文の先頭など違う位置に出る ショートコードの処理が echo で出力している
属性の指定が効かない、一部だけ文字のまま残る 全角の括弧や引用符を使っている
コードブロックの中で文字のまま表示される ブロックエディターの「コード」ブロックは、例として見せるために意図的に実行しない

ショートコードが登録されているか確認する

文字のまま表示される場合は、まず登録されているかを確認します。SSHが使える場合はWP-CLIで確かめられます。

# 登録されていれば bool(true)
wp eval 'var_dump( shortcode_exists( "my_shortcode" ) );'

# 実際に置き換えた結果を表示する
wp eval 'echo do_shortcode( "[my_shortcode]" ), PHP_EOL;'

bool(false) の場合は、ショートコードを登録しているプラグインが無効になっていないか、テーマを変えたときに旧テーマの functions.php に書いたコードが使われなくなっていないかを確認します。ショートコードを提供するプラグインを停止すると、そのショートコードを書いた投稿にはすべて文字のまま表示されます。

どの投稿でそのショートコードを使っているかは、次のコマンドで探せます。

wp post list --post_type=any --s='[my_shortcode' --fields=ID,post_title,post_status

ショートコードを正しく登録する

自分でショートコードを作る場合は、次の形で登録します。

<?php
add_action( 'init', function () {
	add_shortcode( 'my_box', 'my_box_shortcode' );
} );

/**
 * 使い方の例: [my_box title="お知らせ" style="info"]本文[/my_box]
 */
function my_box_shortcode( $atts, $content = null, $tag = '' ) {
	// 属性の初期値を決め、指定された値と合わせる
	$atts = shortcode_atts(
		array(
			'title' => '',
			'style' => 'default',
		),
		$atts,
		$tag
	);

	$html  = '<div class="my-box my-box--' . esc_attr( sanitize_key( $atts['style'] ) ) . '">';
	if ( '' !== $atts['title'] ) {
		$html .= '<p class="my-box__title">' . esc_html( $atts['title'] ) . '</p>';
	}
	// 囲み型の中身に別のショートコードがあれば、それも実行する
	$html .= wp_kses_post( do_shortcode( (string) $content ) );
	$html .= '</div>';

	// echo せず、文字列を返す
	return $html;
}

守るべき点は次のとおりです。

  • 文字列を返す:処理の中で echo すると、置き換え位置ではなく本文の出力より前に表示されます。HTMLを組み立てて return します。テンプレートのように書きたい場合は ob_start() と ob_get_clean() で出力を受け取ってから返します
  • $atts に型を付けない:WordPress 6.4以前では、属性を何も書かずに使うと $atts に空の文字列が渡されます。array $atts のように型を指定すると、その場合にPHP 8でエラーになります。shortcode_atts() が配列に直して初期値と合わせるので、そのまま渡します
  • 値をエスケープする:属性は投稿を書ける人なら誰でも指定できるため、出力の前に esc_attr() や esc_html() を通します
  • init で登録する:WordPressの開発者向けドキュメントでも、add_shortcode() は init フックで呼ぶ例が示されています

ショートコードの作り方はWordPressのショートコードを自作する方法でも説明しています。

名前の付け方

ショートコードの名前には、空白と & / < > [ ] = は使えません。使うと登録されず、デバッグを有効にしていれば注意が表示されます。ハイフンも使えますが、my-box と my のように一方がもう一方の先頭と同じ名前があると区別に問題が出ることがあるため、英小文字とアンダースコアで、他と重ならない名前にしておくと無難です。

書き方の誤りを確認する

登録されているのに一部だけ動かない場合は、本文での書き方を確認します。

  • 全角の括弧:[my_box] のように全角の角括弧で書くと、ショートコードとして認識されません。半角の [ と ] で書きます
  • 全角や飾りの引用符:属性の値は、半角の " か ' で囲むか、空白を含まなければ囲まずに書きます。“お知らせ” のような飾りの引用符や全角の " で囲むと、値が正しく読まれません。ワープロソフトや日本語入力から貼り付けたときに起きやすい誤りです
  • 囲み型の閉じ忘れ:同じショートコードを、閉じタグのある使い方と無い使い方で混ぜると、どこまでが中身かを誤って解釈することがあります。閉じタグを使わない側は [my_box /] のように書くと区別できます
  • 同じショートコードの入れ子:[my_box] の中に [my_box] を入れる使い方は、ショートコードの仕組みでは正しく処理できません

使う場所ごとの対応

ショートコードは、WordPressが特定の場所でだけ実行しています。本文以外で使うときは、その場所で実行されるかを確認します。

場所 実行されるか 対応
投稿・固定ページの本文(段落、「ショートコード」ブロック、「カスタム HTML」ブロック) される そのまま使える
「コード」ブロック されない 例として見せるためのブロック。実行したいときは「ショートコード」ブロックを使う
ブロックウィジェット、クラシックの「テキスト」ウィジェット される そのまま使える
抜粋 されない(自動で作る抜粋からはショートコードが取り除かれる) 手で書いた抜粋で実行したい場合は下のコード
カスタムフィールド されない テンプレートで do_shortcode() を通す
テーマのテンプレート されない do_shortcode() を通して出力する
投稿の題名、メニューの項目名 されない ショートコードを使わない

テンプレートやカスタムフィールドで使う

テンプレートにショートコードを直接書いても実行されません。do_shortcode() を通して出力します。

<?php
// テンプレートの中でショートコードを実行して表示する
echo do_shortcode( '[my_box title="お知らせ"]営業時間が変わりました[/my_box]' );

// カスタムフィールドの値にあるショートコードを実行して表示する
$value = get_post_meta( get_the_ID(), 'notice', true );
echo do_shortcode( wp_kses_post( (string) $value ) );

カスタムフィールドの値は、wp_kses_post() で投稿本文と同じ範囲のHTMLだけに絞ってからショートコードを実行しています。

本文の出力方法を確認する

自作のテーマで、本文を echo $post->post_content; や echo get_the_content(); のように出力していると、ショートコードもブロックも処理されません。WordPressは本文を the_content フィルターに通すときにショートコードを実行するためです。本文は the_content() で出力します。

<?php
// ループの中では the_content() を使う
the_content();

// ループの外で本文を出力する場合は、the_content フィルターを通す
echo apply_filters( 'the_content', get_post_field( 'post_content', $post_id ) );

手で書いた抜粋で実行する

<?php
// 手で書いた抜粋の中のショートコードを実行する
add_filter( 'the_excerpt', 'do_shortcode', 11 );

自動で作られる抜粋は、作る段階でショートコードが取り除かれるため、このコードの対象にはなりません。

コードブロックで例として見せたい場合

記事の中でショートコードを「書き方の例」として見せたいときは、「コード」ブロックを使います。「コード」ブロックは [ を文字参照(&#91;)に置き換えて保存するため、実行されずにそのまま表示されます。段落の中で見せたい場合は、[[my_box]] のように角括弧を二重にすると、実行されずに [my_box] と表示されます。

まとめ

  • 文字のまま表示されたら、shortcode_exists() で登録を確認する。提供元のプラグインの停止やテーマの変更が多い原因
  • 登録の処理は文字列を return し、$atts に型を付けず shortcode_atts() に渡し、値をエスケープする
  • 括弧と引用符は半角で書く。同じショートコードの入れ子や、閉じタグの有無の混在は避ける
  • 本文・ウィジェット以外の場所では実行されない。テンプレートやカスタムフィールドでは do_shortcode() を通し、本文は the_content() で出力する
  • 例として見せたいときは「コード」ブロックか、二重の角括弧を使う

お気軽にご相談ください

お見積りへ お問い合わせへ
▲