2026年5月20日
2026年5月20日
WordPressのショートコードが表示されない・文字のまま出るときの原因と直し方
フォームやボタンのプラグインが用意しているショートコード(角かっこで囲んだ [my_form id="123"] のような記述)を記事に書いたのに、ページにその文字がそのまま表示される。この状態は、WordPress がそのショートコードを知らない(登録されていない)か、表示している場所でショートコードの処理が行われていないかのどちらかです。
この記事では、どちらに当たるかを切り分け、場所ごとの直し方を説明します。動作は WordPress 7.1.4(2026年10月時点の最新版)で確認しています。
症状から原因の見当をつける
| 症状 | 主な原因 | 見る手順 |
|---|---|---|
| どの記事でも特定のショートコードだけ文字のまま | 登録元のプラグインが無効、名前の書き間違い | 手順1・手順6 |
| 自作テーマのページだけ、すべてのショートコードが文字のまま | テンプレートが本文を the_content フィルターに通していない |
手順2 |
| サイドバーなどのウィジェットだけ文字のまま | 旧式の「カスタムHTML」ウィジェットを使っている | 手順4 |
| 記事一覧の抜粋だけ消える・文字のまま | 抜粋ではショートコードが処理されない仕様 | 手順5 |
| 出力が本文の一番上に出る・レイアウトが崩れる | 自作ショートコードが echo で出力している |
手順6 |
表示を直したのに変わらないときは、キャッシュ系プラグインやサーバーのページキャッシュに古いページが残っていないかも確かめてください。
手順1:ショートコードが登録されているか確かめる
WP-CLI が使える場合は、登録済みのショートコード名を一覧で確認できます。
# 登録済みのショートコード名を1行ずつ表示する
wp eval 'global $shortcode_tags; echo implode( "\n", array_keys( $shortcode_tags ) ), "\n";'
# 特定の名前が登録済みか(true なら登録済み)
wp eval 'var_dump( shortcode_exists( "contact-form-7" ) );'
false になる、または一覧に名前が無い場合は、次を確認します。
- 登録元のプラグインが有効か(
wp plugin list --status=activeで確認できます) - 名前の綴りが合っているか。ショートコード名は大文字と小文字を区別します
- 角かっこや引用符が全角になっていないか。
[contact-form-7]のような全角の角かっこは認識されません。属性の値を囲む引用符も半角の"か'にします
プラグインによっては、特定の画面や条件でだけショートコードを登録するものがあります。WP-CLI の一覧に出なくても、そのページを開いたときには登録されている場合があるため、結果が食い違うときはプラグインの説明書で登録の条件を確認してください。
手順2:テーマのテンプレートが本文を正しく出力しているか確かめる
投稿本文のショートコードは、the_content フィルターの中で処理されます(WordPress 本体が do_shortcode をこのフィルターに登録しています)。テンプレートで the_content() を使っていれば処理されます。
<?php
// single.php や page.php のループ内
while ( have_posts() ) :
the_post();
the_content(); // ブロックとショートコードが処理される
endwhile;
次のように本文を直接出力していると、ショートコードもブロックも処理されません。
<?php
// 処理されない書き方の例
echo get_the_content();
echo $post->post_content;
本文を変数で扱いたい場合は、the_content フィルターを通してから出力します。
<?php
$content = get_the_content();
echo apply_filters( 'the_content', $content );
カスタムフィールドの値など、本文以外の文字列に含まれるショートコードを処理したいときは do_shortcode() を使います。テンプレートに直接ショートコードを書きたい場合も同じです。
<?php
// カスタムフィールド notice の値に含まれるショートコードを処理する
echo do_shortcode( get_post_meta( get_the_ID(), 'notice', true ) );
// テンプレートにショートコードを直接書く
echo do_shortcode( '[my_form id="123"]' );
ブロックテーマ(サイトエディターで編集するテーマ)では、テンプレートに「ショートコード」ブロックを置けば処理されます。WordPress はブロックテンプレートの出力にも do_shortcode をかけています。
手順3:ブロックエディターでは「ショートコード」ブロックに入れる
ブロックエディターでは、ブロックの追加(「+」ボタン)から「ショートコード」ブロックを選び、その中にショートコードを書きます。
段落ブロックに書いても本文全体が the_content を通るため処理はされますが、出力が段落(p タグ)の中に入り、フォームなどの表示が崩れることがあります。ショートコードは「ショートコード」ブロックに分けて書くほうが安全です。
ショートコードを処理せずに文字として見せたいときは、角かっこを二重にして [[my_button]] と書きます。ページには [my_button] と表示されます。
手順4:ウィジェットで使う
ウィジェットの種類によって扱いが違います。
| ウィジェット | ショートコード |
|---|---|
| ブロックウィジェット(WordPress 5.8 以降の標準) | 処理される。「ショートコード」ブロックに書く |
| クラシックウィジェットの「テキスト」 | WordPress 4.9 以降は処理される |
| クラシックウィジェットの「カスタムHTML」 | WordPress 本体の設定では処理されない |
クラシックウィジェット(Classic Widgets プラグインなどで旧画面を使っている場合)の「カスタムHTML」でショートコードを使いたいときは、テーマの functions.php か自作プラグインに次を追加します。
<?php
// クラシックの「カスタムHTML」ウィジェットでショートコードを処理する
add_filter( 'widget_custom_html_content', 'do_shortcode' );
「テキスト」ウィジェット用に add_filter( 'widget_text', 'do_shortcode' ); を追加する古い方法は、現在の WordPress では不要です。本体が widget_text_content フィルターで処理しています。
手順5:抜粋ではショートコードが処理されない
記事一覧などで使う抜粋は、ショートコードの扱いが本文と違います。
- 抜粋欄が空で本文から自動で作られる抜粋:ショートコードは取り除かれます(
wp_trim_excerpt()がstrip_shortcodes()を呼びます) - 抜粋欄に手で書いた抜粋:ショートコードは処理されず、文字のまま表示されます
抜粋欄のショートコードも処理したい場合は、次のフィルターを追加します。
<?php
// 手書きの抜粋に含まれるショートコードを処理する
add_filter( 'the_excerpt', 'do_shortcode' );
記事のタイトルも、ショートコードは処理されません。
手順6:自作ショートコードの書き方を確かめる
自分で登録したショートコードが動かない、または表示がおかしいときは、次の点を確かめます。
- 名前に使えない文字がないか。
<>&/[]=、空白などを含む名前は登録できません(WordPress が警告を出して登録しません)。英小文字とアンダースコアだけにしておくと無難です - コールバック関数が出力を
returnで返しているか。echoすると、ショートコードを書いた位置ではなく本文の前に出力されます - 出力する値を
esc_html()・esc_url()・esc_attr()でエスケープしているか
正しく書いた例です。
<?php
// functions.php または自作プラグイン
add_action( 'init', function () {
add_shortcode( 'my_button', 'my_button_shortcode' );
} );
function my_button_shortcode( $atts, $content = null ) {
$atts = shortcode_atts(
array(
'url' => home_url( '/' ),
'color' => 'blue',
),
$atts,
'my_button'
);
$label = ( null !== $content && '' !== $content ) ? $content : 'クリック';
// 出力は echo せず return で返す
return sprintf(
'<a href="%1$s" class="btn btn-%2$s">%3$s</a>',
esc_url( $atts['url'] ),
esc_attr( sanitize_html_class( $atts['color'] ) ),
esc_html( $label )
);
}
使い方は [my_button url="/contact/" color="red"]お問い合わせ[/my_button] です。
長い HTML を出力したい場合は、ob_start() で出力をため、ob_get_clean() の戻り値を return します。
ショートコードの作り方の基本はWordPressのショートコードの作り方でも説明しています。
手順7:プラグインの競合を切り分ける
登録元のプラグインは有効なのに動かない場合は、他のプラグインとの競合を疑います。WP-CLI では次の順で確かめます。本番サイトで全プラグインを無効にすると表示に影響するため、ステージング環境で行うのが安全です。
# 1. いま有効なプラグインを記録しておく
wp plugin list --status=active --field=name > active-plugins.txt
# 2. すべて無効にし、ショートコードの登録元だけ有効にする
wp plugin deactivate --all
wp plugin activate contact-form-7
# 3. 表示を確認したら、記録した一覧から1つずつ有効にして確かめる
# (例)wp plugin activate akismet
# 4. 最後に元の状態に戻す
wp plugin activate $(cat active-plugins.txt)
本番で確かめるしかない場合は、Health Check & Troubleshooting プラグインのトラブルシューティングモードを使うと、自分のログイン中の表示だけプラグインを無効にして確かめられます。詳しい進め方はプラグインの競合を診断する方法を参照してください。
まとめ
- まず
shortcode_exists()などで、ショートコードが登録されているかを確かめる - 自作テーマでは、本文を
the_content()かapply_filters( 'the_content', … )で出力する。本文以外の文字列はdo_shortcode()を使う - ブロックエディターやブロックウィジェットでは「ショートコード」ブロックに書く
- クラシックの「カスタムHTML」ウィジェットと手書きの抜粋は、本体の設定では処理されない。必要ならフィルターを追加する
- 自作ショートコードは
returnで返し、出力をエスケープする