WordPressのカスタムフィールドは、投稿やページに独自のデータを追加できる強力な機能です。「価格」「著者名」「評価」など、標準の投稿フォームにはない情報を柔軟に管理できます。
この記事では、カスタムフィールドに入力されたテキストを記事のフロントエンドに表示する方法を、基本から実務レベルのセキュリティ対策・応用パターンまで体系的に解説します。
💡 この記事でわかること
get_post_meta()の基本的な使い方と引数の意味- テーマテンプレートに表示するコードの書き方
- 出力時のセキュリティ対策(エスケープ処理)
- テキスト・URL・画像・日付などデータ型別の表示パターン
- 条件分岐・ショートコード・WP_Queryによる実務テクニック
- 表示されないときのトラブルシューティング
カスタムフィールドの仕組み(wp_postmeta テーブル)
カスタムフィールドのデータは、データベースの wp_postmeta テーブルに保存されます。この構造を理解すると、取得関数の動作がスムーズに理解できます。
1つの投稿に対して同じ meta_key で複数のレコードを持てるのがポイントです。例えば「関連URL」というキーに3つのURLを保存する、といった使い方ができます。
⚠ 注意: meta_key が _(アンダースコア)で始まるフィールドは「隠しフィールド」扱いとなり、管理画面のカスタムフィールドUIには表示されません。プラグインやテーマが内部的に使用しています。
get_post_meta() の基本的な使い方
カスタムフィールドの値を取得するための最も基本的な関数が get_post_meta() です。
関数のシグネチャ
get_post_meta( int $post_id, string $key = '', bool $single = false )
第3引数 $single による戻り値の違い
$single の指定により、戻り値の型が大きく変わります。これはよくあるハマりポイントなので注意してください。
// カスタムフィールド「price」に「1980」が保存されている場合 // $single = true → 文字列を返す $price = get_post_meta( get_the_ID(), 'price', true ); // → "1980"(文字列) // $single = false → 配列を返す $price = get_post_meta( get_the_ID(), 'price', false ); // → array( "1980" )(配列) // $key を省略 → 全メタデータの連想配列を返す $all_meta = get_post_meta( get_the_ID() ); // → array( "price" => array("1980"), "color" => array("red"), ... )
ℹ️ ポイント: テンプレートで値を表示するときは、第3引数に true を指定するのが基本です。配列のまま echo すると「Array」と表示されてしまいます。
テーマテンプレートに表示する基本コード
テーマファイル(single.php や page.php など)にカスタムフィールドの値を表示する基本パターンです。
パターン1: ループ内で表示する(最も一般的)
// single.php や page.php のループ内 if ( have_posts() ) : while ( have_posts() ) : the_post(); // カスタムフィールド「subtitle」を取得して表示 $subtitle = get_post_meta( get_the_ID(), 'subtitle', true ); if ( $subtitle ) : ?> <p class="post-subtitle"><?php echo esc_html( $subtitle ); ?></p> <?php endif; endwhile; endif;
パターン2: ループ外で投稿IDを直接指定
// サイドバーやフッターなど、ループ外で特定の投稿のカスタムフィールドを表示 $post_id = 42; $event_date = get_post_meta( $post_id, 'event_date', true ); if ( $event_date ) { echo '<p>開催日: ' . esc_html( $event_date ) . '</p>'; }
ループ内では get_the_ID() で自動的に現在の投稿IDを取得できます。ループ外では投稿IDを直接指定する必要があります(投稿IDの取得方法)。
セキュリティ対策(エスケープ処理)【重要】
カスタムフィールドの値を出力するときは、必ずエスケープ処理を行いましょう。エスケープを怠ると、XSS(クロスサイトスクリプティング)攻撃の脆弱性が生まれる可能性があります。
🚨 なぜエスケープが必要?
カスタムフィールドには管理画面から自由にテキストを入力できます。もし悪意のある <script> タグが入力された場合、エスケープなしで出力するとブラウザでJavaScriptが実行されてしまいます。echo する前には必ずエスケープする習慣をつけましょう。
エスケープ関数の使い分け
実際のコード例
// ① テキストの表示 → esc_html() $author_name = get_post_meta( get_the_ID(), 'author_name', true ); echo '<p>著者: ' . esc_html( $author_name ) . '</p>'; // ② 属性値として使う → esc_attr() $tooltip = get_post_meta( get_the_ID(), 'tooltip_text', true ); echo '<span title="' . esc_attr( $tooltip ) . '">ヒント</span>'; // ③ URLの表示 → esc_url() $link = get_post_meta( get_the_ID(), 'external_link', true ); echo '<a href="' . esc_url( $link ) . '">外部リンク</a>'; // ④ リッチテキスト(HTML含む) → wp_kses_post() $description = get_post_meta( get_the_ID(), 'rich_description', true ); echo wp_kses_post( $description );
✅ ベストプラクティス: 迷ったら esc_html() を使えば安全です。HTMLを許可する必要がある場合のみ wp_kses_post() を使いましょう。
入力値の有無で表示を切り替える(条件分岐)
カスタムフィールドが未入力の場合、空文字が返ります。条件分岐で入力がある場合だけ表示するのが基本パターンです(条件分岐の詳細はこちら)。
$price = get_post_meta( get_the_ID(), 'price', true ); // 値が存在する場合のみ表示 if ( ! empty( $price ) ) { echo '<p class="product-price">価格: ' . esc_html( $price ) . '円</p>'; } else { echo '<p class="product-price">価格: お問い合わせください</p>'; }
⚠ empty() vs isset() の違い: get_post_meta() は $single = true でキーが存在しない場合に空文字、$single = false の場合は空配列を返すため、isset() では正しく判定できません。empty() または $value !== '' で判定しましょう。
複数のフィールドをまとめて表示する
// 商品情報カードを表示する例 $fields = array( 'product_name' => '商品名', 'price' => '価格', 'manufacturer' => 'メーカー', 'release_date' => '発売日', ); echo '<table class="product-info">'; foreach ( $fields as $key => $label ) { $value = get_post_meta( get_the_ID(), $key, true ); if ( $value !== '' ) { echo '<tr>'; echo '<th>' . esc_html( $label ) . '</th>'; echo '<td>' . esc_html( $value ) . '</td>'; echo '</tr>'; } } echo '</table>';
データ型別の表示パターン
カスタムフィールドには様々な種類のデータを保存できます。ここではよくあるデータ型ごとの表示パターンを紹介します。
テキスト(プレーンテキスト)
// シンプルなテキスト表示 $subtitle = get_post_meta( get_the_ID(), 'subtitle', true ); if ( $subtitle ) { echo '<h2 class="subtitle">' . esc_html( $subtitle ) . '</h2>'; }
URL(リンクの表示)
カスタムフィールドにURLを保存してリンクとして表示するパターンです(URL取得とリンク表示の詳細はこちら)。
$url = get_post_meta( get_the_ID(), 'reference_url', true ); $text = get_post_meta( get_the_ID(), 'reference_text', true ); if ( $url ) { $link_text = $text ? $text : $url; printf( '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', esc_url( $url ), esc_html( $link_text ) ); }
画像(画像IDから表示)
ACFの画像フィールドなど、画像のアタッチメントIDをカスタムフィールドに保存しているケースと、画像URLを直接保存しているケースの2パターンを紹介します。
// 画像IDが保存されている場合 $image_id = get_post_meta( get_the_ID(), 'featured_banner', true ); if ( $image_id ) { echo wp_get_attachment_image( $image_id, 'large', false, array( 'class' => 'custom-banner', 'loading' => 'lazy', ) ); } // 画像URLが直接保存されている場合 $image_url = get_post_meta( get_the_ID(), 'banner_url', true ); if ( $image_url ) { printf( '<img src="%s" alt="%s" class="custom-banner" loading="lazy">', esc_url( $image_url ), esc_attr( get_the_title() ) ); }
日付(フォーマット変換して表示)
// "2026-03-04" のような形式で保存されている場合 $raw_date = get_post_meta( get_the_ID(), 'event_date', true ); if ( $raw_date ) { $timestamp = strtotime( $raw_date ); $formatted = date_i18n( 'Y年n月j日(D)', $timestamp ); echo '<time datetime="' . esc_attr( $raw_date ) . '">' . esc_html( $formatted ) . '</time>'; }
複数値(同じキーに複数の値がある場合)
// 「関連タグ」に複数の値を保存している場合 // $single = false で全ての値を配列として取得 $tags = get_post_meta( get_the_ID(), 'related_tag', false ); if ( ! empty( $tags ) ) { echo '<ul class="custom-tags">'; foreach ( $tags as $tag ) { echo '<li>' . esc_html( $tag ) . '</li>'; } echo '</ul>'; }
ショートコードでカスタムフィールドを表示する
テーマファイルを編集せず、記事本文中からカスタムフィールドを表示したい場合は、ショートコードが便利です。以下のコードを functions.php に追加します。
/** * カスタムフィールドの値を表示するショートコード * 使い方: [cf key="フィールド名"] * オプション: [cf key="フィールド名" default="未設定"] */ function codingls_cf_shortcode( $atts ) { $atts = shortcode_atts( array( 'key' => '', 'default' => '', ), $atts, 'cf' ); if ( empty( $atts['key'] ) ) { return ''; } $value = get_post_meta( get_the_ID(), $atts['key'], true ); if ( $value === '' ) { return esc_html( $atts['default'] ); } return esc_html( $value ); } add_shortcode( 'cf', 'codingls_cf_shortcode' );
記事のエディタから次のように使えます。
<!-- 基本的な使い方 --> この商品の価格は [cf key="price"] 円です。 <!-- デフォルト値を指定 --> 著者: [cf key="author_name" default="不明"]
カスタムフィールド取得関数の比較
WordPress には get_post_meta() 以外にもカスタムフィールドを取得する関数があります。それぞれの特徴を比較します(カスタムフィールド取得方法の詳細はこちら)。
ℹ️ 結論: 新規コードでは get_post_meta() を使いましょう。他の関数は古いテーマやプラグインとの互換性のために存在していますが、get_post_meta() が最も柔軟で安全です。
WP_Query でカスタムフィールドの値で記事を検索・ソートする
WP_Query の meta_query パラメータを使うと、カスタムフィールドの値を条件にして記事を絞り込んだり、並び替えたりできます(meta_queryの詳細はこちら)。
特定の値を持つ記事を取得する
// 「おすすめ」フラグが "yes" の記事だけを取得 $query = new WP_Query( array( 'post_type' => 'post', 'meta_query' => array( array( 'key' => 'recommend', 'value' => 'yes', 'compare' => '=', ), ), ) ); if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); the_title( '<h3>', '</h3>' ); endwhile; wp_reset_postdata(); endif;
カスタムフィールドの値で並び替える
// 価格の安い順に商品を表示 $query = new WP_Query( array( 'post_type' => 'post', 'meta_key' => 'price', 'orderby' => 'meta_value_num', 'order' => 'ASC', 'meta_query' => array( array( 'key' => 'price', 'type' => 'NUMERIC', 'compare' => 'EXISTS', ), ), ) );
compare パラメータの主なオプション
カスタムフィールドを検索対象に含める方法は「カスタムフィールドを検索対象にする方法」で詳しく解説しています。
REST API でカスタムフィールドを公開する
WordPress REST API を通じてカスタムフィールドの値を外部から取得したい場合は、register_meta() または register_rest_field() で公開設定を行います。
register_meta() で公開する方法
/** * カスタムフィールド「price」をREST APIで公開する * functions.php に追加 */ function codingls_register_meta_fields() { register_meta( 'post', 'price', array( 'type' => 'string', 'single' => true, 'show_in_rest' => true, 'description' => '商品の価格', ) ); } add_action( 'init', 'codingls_register_meta_fields' );
登録後、REST APIのレスポンス内の meta オブジェクトにフィールドが含まれるようになります。
// GET /wp-json/wp/v2/posts/42 のレスポンス(抜粋) { "id": 42, "title": { "rendered": "商品ページ" }, "meta": { "price": "1980" } }
register_rest_field() でカスタムレスポンスを追加
/** * REST APIに「product_info」フィールドを追加(加工した値を返す) */ function codingls_register_rest_fields() { register_rest_field( 'post', 'product_info', array( 'get_callback' => function( $post ) { return array( 'price' => get_post_meta( $post['id'], 'price', true ), 'color' => get_post_meta( $post['id'], 'color', true ), 'stock' => get_post_meta( $post['id'], 'stock', true ), ); }, 'schema' => array( 'type' => 'object', 'description' => '商品情報', ), ) ); } add_action( 'rest_api_init', 'codingls_register_rest_fields' );
管理画面にカスタムフィールドを表示する方法
投稿一覧画面でカスタムフィールドの値をカラムとして表示すると、管理がしやすくなります。詳しくは「管理画面の投稿一覧にカスタムフィールドの値を表示する方法」を参照してください。
// 投稿一覧に「価格」カラムを追加(functions.php に記述) function codingls_add_price_column( $columns ) { $columns['price'] = '価格'; return $columns; } add_filter( 'manage_posts_columns', 'codingls_add_price_column' ); function codingls_show_price_column( $column, $post_id ) { if ( $column === 'price' ) { $price = get_post_meta( $post_id, 'price', true ); echo $price ? esc_html( $price ) . '円' : '—'; } } add_action( 'manage_posts_custom_column', 'codingls_show_price_column', 10, 2 );
トラブルシューティング
カスタムフィールドの値が表示されない場合、以下のチェックリストを確認してください。
デバッグのコツ
// デバッグ: カスタムフィールドの値と型を確認する $value = get_post_meta( get_the_ID(), 'price', true ); // 値の型と内容を確認(開発環境のみ) if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { echo '<pre>'; var_dump( $value ); echo '</pre>'; } // 全メタデータを一覧表示 $all_meta = get_post_meta( get_the_ID() ); echo '<pre>' . esc_html( print_r( $all_meta, true ) ) . '</pre>';
関連する記事
カスタムフィールドに関する以下の記事もあわせて参照してください。
まとめ
カスタムフィールドは WordPress の基本機能でありながら、セキュリティ対策や WP_Query との連携まで押さえると非常に強力なツールになります。まずは get_post_meta() + esc_html() の基本パターンを覚え、必要に応じてデータ型別の表示パターンを活用してください。

