【WordPress】カスタムフィールドのテキストを表示する方法|get_post_meta完全ガイド

【WordPress】カスタムフィールドのテキストを表示する方法|get_post_meta完全ガイド WordPress

WordPressのカスタムフィールドは、投稿やページに独自のデータを追加できる強力な機能です。「価格」「著者名」「評価」など、標準の投稿フォームにはない情報を柔軟に管理できます。

この記事では、カスタムフィールドに入力されたテキストを記事のフロントエンドに表示する方法を、基本から実務レベルのセキュリティ対策・応用パターンまで体系的に解説します。

💡 この記事でわかること

  • get_post_meta() の基本的な使い方と引数の意味
  • テーマテンプレートに表示するコードの書き方
  • 出力時のセキュリティ対策(エスケープ処理)
  • テキスト・URL・画像・日付などデータ型別の表示パターン
  • 条件分岐・ショートコード・WP_Queryによる実務テクニック
  • 表示されないときのトラブルシューティング
スポンサーリンク

カスタムフィールドの仕組み(wp_postmeta テーブル)

カスタムフィールドのデータは、データベースの wp_postmeta テーブルに保存されます。この構造を理解すると、取得関数の動作がスムーズに理解できます。

カラム名 説明
meta_id bigint(20) 自動採番のプライマリキー
post_id bigint(20) 紐づく投稿のID
meta_key varchar(255) フィールドの名前(キー)
meta_value longtext フィールドの値(テキスト・シリアライズ配列など)

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 )
引数 説明
$post_id int 投稿のID(投稿IDの取得方法はこちら
$key string 取得したいメタキー名。空文字の場合は全メタデータを返す
$single bool true: 単一の値(文字列)を返す
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.phppage.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() HTMLタグを無効化して文字として表示 タグ内テキスト表示(最もよく使う)
esc_attr() HTML属性値として安全に出力 title / alt / value 属性など
esc_url() URL として安全に出力 href / src 属性など
wp_kses_post() 投稿で許可されたHTMLタグのみ残す リッチテキスト(HTMLを一部許可したい場合)

実際のコード例

// ① テキストの表示 → 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() 投稿ID, キー, $single 文字列 or 配列 推奨
post_custom() キー名のみ 配列(常に) 非推奨(ループ内限定)
get_post_custom() 投稿ID(省略可) 全メタの連想配列 限定的(一括取得時のみ)
get_post_custom_values() キー, 投稿ID 配列(常に) 限定的(複数値取得時)
the_meta() なし HTML直接出力(ul/li) 非推奨(制御が困難)

ℹ️ 結論: 新規コードでは get_post_meta() を使いましょう。他の関数は古いテーマやプラグインとの互換性のために存在していますが、get_post_meta() が最も柔軟で安全です。

WP_Query でカスタムフィールドの値で記事を検索・ソートする

WP_Querymeta_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 パラメータの主なオプション

compare 意味 使用例
= 完全一致 ステータスが「公開中」の記事
!= 不一致 「下書き」以外の記事
LIKE 部分一致 タグに「PHP」を含む記事
EXISTS キーが存在する priceフィールドがある記事のみ
NOT EXISTS キーが存在しない priceフィールドがない記事のみ
BETWEEN 範囲内 価格が1000〜5000の記事
IN いずれかに一致 カラーが「赤」「青」「緑」のいずれか

カスタムフィールドを検索対象に含める方法は「カスタムフィールドを検索対象にする方法」で詳しく解説しています。

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 );

トラブルシューティング

カスタムフィールドの値が表示されない場合、以下のチェックリストを確認してください。

症状 原因 対処法
何も表示されない meta_keyの綴りが間違っている 管理画面で登録されているキー名を確認
「Array」と表示される $singlefalse のまま echo している 第3引数に true を指定する
空文字が返る 投稿IDが正しくない/ループ外で get_the_ID() を使っている 投稿IDを直接指定して確認する
管理画面にフィールドが表示されない 表示オプションでチェックが外れている 投稿編集画面の右上「表示オプション」を確認
ACFフィールドが取得できない get_post_meta() ではACFの加工後の値が取れない(ACFは内部的に _ プレフィックス付きのメタキーにフィールド設定を保存) ACFフィールドには get_field() を使う(画像・関連・リピーターなど加工が必要な型は特に)
シリアライズされた文字列が表示される 配列やオブジェクトが保存されている maybe_unserialize() で復元してから処理する

デバッグのコツ

// デバッグ: カスタムフィールドの値と型を確認する
$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>';

関連する記事

カスタムフィールドに関する以下の記事もあわせて参照してください。

記事 内容
カスタムフィールドを取得する方法 取得関数の詳細な使い分けガイド
URLを取得してリンクを貼る方法 URL型フィールドの実践的な活用法
入力有無で表示を切り替える方法 条件分岐パターンの詳細解説
チェックボックス型の選択肢を表示 チェックボックス型フィールドの実装
投稿一覧にカスタムフィールドを表示 管理画面のカスタマイズ方法
WP_Queryで複数条件ソート meta_queryの高度な使い方
関連投稿を表示する方法 カスタムフィールドで関連記事を自動表示
リビジョンを有効化する方法 カスタムフィールドの変更履歴管理
検索対象にする方法 カスタムフィールドの値をサイト内検索に含める
ループで記事を表示する方法 WP_Queryの基本と応用(メインループ解説)

まとめ

項目 内容
基本の取得関数 get_post_meta( $post_id, $key, true )
テキスト表示のエスケープ esc_html()(迷ったらこれ)
URL表示のエスケープ esc_url()
HTML属性のエスケープ esc_attr()
未入力チェック empty() または $value !== '' で判定
記事の絞り込み WP_Query + meta_query
REST API公開 register_meta() + show_in_rest => true

カスタムフィールドは WordPress の基本機能でありながら、セキュリティ対策WP_Query との連携まで押さえると非常に強力なツールになります。まずは get_post_meta() + esc_html() の基本パターンを覚え、必要に応じてデータ型別の表示パターンを活用してください。