カスタムフィールドとは?

カスタムフィールド(メタデータ)は、投稿や固定ページに標準の「タイトル」「本文」以外の情報を追加する機能です。

💡 カスタムフィールドの活用例

  • 不動産サイト: 家賃、間取り、築年数、最寄り駅
  • 商品サイト: 価格、在庫数、メーカー、型番
  • イベントサイト: 開催日時、会場、参加費、定員
  • レストラン: 営業時間、予算、ジャンル、駐車場
  • 書籍レビュー: 著者、出版社、ISBN、評価

基本的な実装方法

方法1: WordPressの標準機能を使う

最もシンプルな方法は、WordPress標準のカスタムフィールド機能を使うことです。

  1. カスタムフィールドを有効化

    投稿編集画面の右上「︙」→「設定」→「カスタムフィールド」をオンにします。

  2. フィールドを追加

    編集画面下部の「カスタムフィールド」セクションで、名前と値を入力します。

  3. テンプレートで表示

    テーマファイルで get_post_meta() を使って値を取得・表示します。

テンプレートでの表示例

single.php など<?php // 価格を取得 $price = get_post_meta(get_the_ID(), 'price', true); // 値が存在する場合のみ表示 if ($price) : ?> <div class="product-price"> <strong>価格:</strong> ¥<?php echo number_format($price); ?> </div> <?php endif; ?>

💡 get_post_meta() の使い方

get_post_meta( $post_id, $key, $single );
  • $post_id: 投稿ID(通常は get_the_ID()
  • $key: フィールドの名前(例: 'price')
  • $single:
    • true - 単一の値を返す(文字列)
    • false - 配列で返す(複数値対応)

方法2: メタボックスをカスタマイズ

管理画面に専用の入力欄を作成して、より使いやすくします。

メタボックスの追加

functions.php// メタボックスを追加 function add_product_meta_box() { add_meta_box( 'product_details', // ID '商品情報', // タイトル 'product_meta_box_callback', // コールバック関数 'product', // 投稿タイプ 'normal', // 表示位置 'high' // 優先度 ); } add_action('add_meta_boxes', 'add_product_meta_box'); // メタボックスの内容を表示 function product_meta_box_callback($post) { // nonceフィールドを追加(セキュリティ対策) wp_nonce_field('product_meta_box', 'product_meta_box_nonce'); // 既存の値を取得 $price = get_post_meta($post->ID, 'price', true); $stock = get_post_meta($post->ID, 'stock', true); ?> <p> <label for="product_price">価格(円):</label> <input type="number" id="product_price" name="product_price" value="<?php echo esc_attr($price); ?>" style="width: 200px;"> </p> <p> <label for="product_stock">在庫数:</label> <input type="number" id="product_stock" name="product_stock" value="<?php echo esc_attr($stock); ?>" style="width: 200px;"> </p> <?php } // データを保存 function save_product_meta($post_id) { // nonce確認 if (!isset($_POST['product_meta_box_nonce'])) { return; } if (!wp_verify_nonce($_POST['product_meta_box_nonce'], 'product_meta_box')) { return; } // 自動保存時は処理しない if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // 権限チェック if (!current_user_can('edit_post', $post_id)) { return; } // データを保存 if (isset($_POST['product_price'])) { update_post_meta($post_id, 'price', sanitize_text_field($_POST['product_price'])); } if (isset($_POST['product_stock'])) { update_post_meta($post_id, 'stock', sanitize_text_field($_POST['product_stock'])); } } add_action('save_post', 'save_product_meta');

⚠️ セキュリティ対策は必須

  • wp_nonce_field(): CSRF攻撃を防ぐ
  • sanitize_text_field(): 入力値をサニタイズ
  • esc_attr(): 出力時にエスケープ
  • current_user_can(): 権限チェック

→ セキュリティ対策の詳細を学ぶ

方法3: ACF(Advanced Custom Fields)プラグイン

最も人気のあるカスタムフィールドプラグインです。GUIで簡単に設定できます。

💡 ACFの特徴

  • ✅ コードを書かずにフィールドを作成可能
  • ✅ 30種類以上のフィールドタイプ(画像、日付、リレーションなど)
  • ✅ 条件分岐で表示を制御
  • ✅ 繰り返しフィールド(Pro版)
  • ✅ フレキシブルコンテンツ(Pro版)

ACFでの値の取得方法

テンプレートファイル<?php // シンプルな取得 $price = get_field('price'); // 値が存在する場合のみ表示 if ($price) : ?> <p>価格: <?php echo esc_html($price); ?></p> <?php endif; // 画像フィールドの場合 $image = get_field('product_image'); if ($image) : ?> <img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>"> <?php endif; ?>

実践例:不動産物件情報

複数のカスタムフィールドを組み合わせた実装例です。

メタボックスの作成

functions.phpfunction add_property_meta_box() { add_meta_box( 'property_details', '物件情報', 'property_meta_box_callback', 'property', 'normal', 'high' ); } add_action('add_meta_boxes', 'add_property_meta_box'); function property_meta_box_callback($post) { wp_nonce_field('property_meta_box', 'property_meta_box_nonce'); $rent = get_post_meta($post->ID, 'rent', true); $layout = get_post_meta($post->ID, 'layout', true); $area = get_post_meta($post->ID, 'area', true); $station = get_post_meta($post->ID, 'station', true); $age = get_post_meta($post->ID, 'age', true); ?> <table style="width: 100%;"> <tr> <th><label for="rent">家賃(円):</label></th> <td><input type="number" id="rent" name="rent" value="<?php echo esc_attr($rent); ?>"></td> </tr> <tr> <th><label for="layout">間取り:</label></th> <td> <select id="layout" name="layout"> <option value="">選択してください</option> <option value="1K" <?php selected($layout, '1K'); ?>>1K</option> <option value="1DK" <?php selected($layout, '1DK'); ?>>1DK</option> <option value="1LDK" <?php selected($layout, '1LDK'); ?>>1LDK</option> <option value="2DK" <?php selected($layout, '2DK'); ?>>2DK</option> <option value="2LDK" <?php selected($layout, '2LDK'); ?>>2LDK</option> </select> </td> </tr> <tr> <th><label for="area">専有面積(㎡):</label></th> <td><input type="number" step="0.01" id="area" name="area" value="<?php echo esc_attr($area); ?>"></td> </tr> <tr> <th><label for="station">最寄り駅:</label></th> <td><input type="text" id="station" name="station" value="<?php echo esc_attr($station); ?>"></td> </tr> <tr> <th><label for="age">築年数:</label></th> <td><input type="number" id="age" name="age" value="<?php echo esc_attr($age); ?>"> 年</td> </tr> </table> <?php } function save_property_meta($post_id) { if (!isset($_POST['property_meta_box_nonce'])) return; if (!wp_verify_nonce($_POST['property_meta_box_nonce'], 'property_meta_box')) return; if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!current_user_can('edit_post', $post_id)) return; $fields = array('rent', 'layout', 'area', 'station', 'age'); foreach ($fields as $field) { if (isset($_POST[$field])) { update_post_meta($post_id, $field, sanitize_text_field($_POST[$field])); } } } add_action('save_post', 'save_property_meta');

テンプレートでの表示

single-property.php<div class="property-details"> <h2>物件情報</h2> <table> <tr> <th>家賃</th> <td>¥<?php echo number_format(get_post_meta(get_the_ID(), 'rent', true)); ?>/月</td> </tr> <tr> <th>間取り</th> <td><?php echo esc_html(get_post_meta(get_the_ID(), 'layout', true)); ?></td> </tr> <tr> <th>専有面積</th> <td><?php echo esc_html(get_post_meta(get_the_ID(), 'area', true)); ?>㎡</td> </tr> <tr> <th>最寄り駅</th> <td><?php echo esc_html(get_post_meta(get_the_ID(), 'station', true)); ?></td> </tr> <tr> <th>築年数</th> <td><?php echo esc_html(get_post_meta(get_the_ID(), 'age', true)); ?>年</td> </tr> </table> </div>

カスタムクエリでの絞り込み

カスタムフィールドの値を使って投稿を絞り込むことができます。

例: 家賃10万円以下の物件を表示

テンプレートファイル<?php $args = array( 'post_type' => 'property', 'meta_query' => array( array( 'key' => 'rent', 'value' => 100000, 'compare' => '<=', 'type' => 'NUMERIC', ), ), ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <article> <h3><?php the_title(); ?></h3> <p>家賃: ¥<?php echo number_format(get_post_meta(get_the_ID(), 'rent', true)); ?></p> </article> <?php endwhile; wp_reset_postdata(); endif; ?>

複数条件での絞り込み

2LDK以上、家賃15万円以下$args = array( 'post_type' => 'property', 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'layout', 'value' => array('2LDK', '3LDK', '4LDK'), 'compare' => 'IN', ), array( 'key' => 'rent', 'value' => 150000, 'compare' => '<=', 'type' => 'NUMERIC', ), ), ); $query = new WP_Query($args);

3つの実装方法の比較

方法 難易度 メリット デメリット おすすめ用途
標準機能 ★☆☆ 追加作業不要、シンプル 使いにくい、機能が限定的 簡単なメタ情報のみ
カスタムメタボックス ★★★ 完全カスタマイズ可能 コード量が多い 独自のUI・機能が必要な場合
ACFプラグイン ★☆☆ GUI操作、機能豊富 プラグイン依存 ほとんどのケースに最適

よくある使い方のパターン

チェックボックス(複数選択)

// 保存時 $features = isset($_POST['features']) ? $_POST['features'] : array(); update_post_meta($post_id, 'features', $features); // 表示時 $features = get_post_meta(get_the_ID(), 'features', true); if ($features && is_array($features)) { echo implode(', ', $features); }

日付フィールド

// メタボックス内 <input type="date" name="event_date" value="<?php echo esc_attr($event_date); ?>"> // 表示時 $event_date = get_post_meta(get_the_ID(), 'event_date', true); echo date('Y年n月j日', strtotime($event_date));

評価(星)

// メタボックス内 <select name="rating"> <option value="5" <?php selected($rating, '5'); ?>>★★★★★</option> <option value="4" <?php selected($rating, '4'); ?>>★★★★☆</option> <option value="3" <?php selected($rating, '3'); ?>>★★★☆☆</option> <option value="2" <?php selected($rating, '2'); ?>>★★☆☆☆</option> <option value="1" <?php selected($rating, '1'); ?>>★☆☆☆☆</option> </select>

まとめ

カスタムフィールドを使うと、以下のことができるようになります:

🚀 次のステップ

カスタムフィールドとカスタムポストタイプを組み合わせることで、非常に強力なコンテンツ管理システムを構築できます。