応用編
📝 カスタムフィールド
投稿や固定ページに独自の情報を追加できるカスタムフィールドの実装方法を学びます。価格、住所、評価など、標準にはない項目を自由に追加できるようになります。
難易度: ★★☆☆☆ 中級カスタムフィールドとは?
カスタムフィールド(メタデータ)は、投稿や固定ページに標準の「タイトル」「本文」以外の情報を追加する機能です。
💡 カスタムフィールドの活用例
- 不動産サイト: 家賃、間取り、築年数、最寄り駅
- 商品サイト: 価格、在庫数、メーカー、型番
- イベントサイト: 開催日時、会場、参加費、定員
- レストラン: 営業時間、予算、ジャンル、駐車場
- 書籍レビュー: 著者、出版社、ISBN、評価
基本的な実装方法
方法1: WordPressの標準機能を使う
最もシンプルな方法は、WordPress標準のカスタムフィールド機能を使うことです。
-
カスタムフィールドを有効化
投稿編集画面の右上「︙」→「設定」→「カスタムフィールド」をオンにします。
-
フィールドを追加
編集画面下部の「カスタムフィールド」セクションで、名前と値を入力します。
-
テンプレートで表示
テーマファイルで
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>
まとめ
カスタムフィールドを使うと、以下のことができるようになります:
- ✅ 投稿に独自の情報を追加できる
- ✅ 構造化されたデータ管理が可能
- ✅ 高度な検索・絞り込み機能を実装できる
- ✅ より専門的なサイトが構築できる
🚀 次のステップ
カスタムフィールドとカスタムポストタイプを組み合わせることで、非常に強力なコンテンツ管理システムを構築できます。