2026年5月20日
2026年5月20日
WordPressにカスタムフィールドをメタボックスで追加する方法
はじめに
WordPressの標準「カスタムフィールド」UIより使いやすい専用の入力フォームを、add_meta_box() で作成できます。記事に独自のデータ(価格・住所・外部URLなど)を追加する際に使います。
症状・原因
- 記事に独自の項目(価格・電話番号・外部URL)を追加したい
- カスタムフィールドUIが使いにくい
- 特定の投稿タイプにだけ入力欄を追加したい
- 入力値を安全にデータベースに保存したい
解決手順
ステップ1:メタボックスを登録する
// functions.php
add_action('add_meta_boxes', function(): void {
add_meta_box(
'my_product_info', // メタボックスID(ユニーク)
'商品情報', // タイトル
'render_product_meta_box', // コールバック関数
'product', // 対象投稿タイプ(配列も可)
'normal', // 位置: normal / side / advanced
'high' // 優先度: high / default / low
);
});
function render_product_meta_box(WP_Post $post): void {
// ノンスフィールド(CSRF対策)
wp_nonce_field('save_product_meta', 'product_meta_nonce');
// 保存済みの値を取得
$price = get_post_meta($post->ID, '_product_price', true);
$url = get_post_meta($post->ID, '_product_url', true);
$featured = get_post_meta($post->ID, '_product_featured', true);
?>
<table class="form-table">
<tr>
<th><label for="product_price">価格(円)</label></th>
<td>
<input type="number" id="product_price" name="product_price"
value="<?php echo esc_attr($price); ?>"
min="0" step="1" class="regular-text">
</td>
</tr>
<tr>
<th><label for="product_url">商品URL</label></th>
<td>
<input type="url" id="product_url" name="product_url"
value="<?php echo esc_attr($url); ?>"
class="large-text">
</td>
</tr>
<tr>
<th>おすすめ</th>
<td>
<label>
<input type="checkbox" name="product_featured" value="1"
<?php checked($featured, '1'); ?>>
おすすめ商品として表示する
</label>
</td>
</tr>
</table>
<?php
}
ステップ2:保存処理を実装する
// functions.php
add_action('save_post', function(int $post_id): void {
// オートセーブ・AJAX時はスキップ
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (wp_is_post_revision($post_id)) return;
// ノンス検証
if (!isset($_POST['product_meta_nonce'])) return;
if (!wp_verify_nonce($_POST['product_meta_nonce'], 'save_product_meta')) return;
// 権限確認
if (!current_user_can('edit_post', $post_id)) return;
// 価格(整数に変換してサニタイズ)
if (isset($_POST['product_price'])) {
$price = absint($_POST['product_price']);
update_post_meta($post_id, '_product_price', $price);
}
// URL(URLとしてサニタイズ)
if (isset($_POST['product_url'])) {
$url = esc_url_raw($_POST['product_url']);
update_post_meta($post_id, '_product_url', $url);
}
// チェックボックス(送信されない場合は削除)
$featured = isset($_POST['product_featured']) ? '1' : '0';
update_post_meta($post_id, '_product_featured', $featured);
});
ステップ3:テンプレートでカスタムフィールドを使う
// single-product.php
$price = get_post_meta(get_the_ID(), '_product_price', true);
$url = get_post_meta(get_the_ID(), '_product_url', true);
$featured = get_post_meta(get_the_ID(), '_product_featured', true);
?>
<div class="product-info">
<?php if ($featured === '1'): ?>
<span class="badge-featured">おすすめ</span>
<?php endif; ?>
<h1><?php the_title(); ?></h1>
<?php if ($price): ?>
<p class="product-price">
¥<?php echo number_format((int) $price); ?>(税込)
</p>
<?php endif; ?>
<?php if ($url): ?>
<a href="<?php echo esc_url($url); ?>" class="btn-buy" target="_blank" rel="noopener noreferrer">
購入する
</a>
<?php endif; ?>
</div>
ステップ4:WP-CLIでカスタムフィールドを管理する
# カスタムフィールドを設定
wp post meta set 42 _product_price 19800
wp post meta set 42 _product_url "https://example.com/buy"
# カスタムフィールドを確認
wp post meta get 42 _product_price
wp post meta list 42 --format=table
# おすすめフラグが立っている記事を確認
wp post list --post_type=product --meta_key=_product_featured --meta_value=1 --format=table
注意事項
- カスタムフィールドのキー名はアンダースコア
_で始めるとWordPress標準のカスタムフィールドUIに表示されなくなります(プラグインが管理する内部データとして扱われます) save_postでは必ずノンス検証とcurrent_user_can()の権限チェックを行ってください- 大量のカスタムフィールドを管理する場合はAdvanced Custom Fields(ACF)プラグインの使用を検討してください
まとめ
add_meta_boxes アクションで add_meta_box() を呼び出してUIを追加し、save_post アクションでノンス検証・権限確認・サニタイズをした後 update_post_meta() で保存します。テンプレートでは get_post_meta() で取得して表示します。