2026年5月24日
2026年5月24日
WordPressのCarbon Fieldsでカスタムフィールドをコード管理する方法
Carbon Fields は、カスタムフィールドを管理画面ではなく PHP のコードで定義するライブラリです。Composer で読み込み、Container::make() と Field::make() で入力欄を組み立て、carbon_get_post_meta() などの専用関数で値を取り出します。この記事では、導入からフィールド登録、テンプレートでの表示、保存形式の注意点、運用上の判断材料までを順に説明します。
Carbon Fields が向いているケース
ACF のように管理画面でフィールドを作る方式は手軽ですが、設定がデータベースに入るため、環境間の差分管理やレビューがしにくくなります。Carbon Fields はフィールドの定義がすべて PHP ファイルに書かれるので、Git で履歴を追え、ステージングと本番で同じ定義を揃えやすくなります。開発者がテーマやプラグインを管理しているサイトで、編集者はフィールドに入力するだけ、という体制に向いています。
逆に、エンジニアがいない体制で運用担当者がフィールドを追加・変更したい場合は、GUI のある ACF などのほうが適しています。また Carbon Fields は以前は WordPress.org のプラグインとしても配布されていましたが、現在は Composer で読み込む使い方が中心です。更新の頻度は時期によって差があるため、採用前に GitHub のリリース状況と、使っている WordPress・PHP のバージョンで動作報告があるかを確認してください(2026年10月現在)。
導入する場所を決める
フィールド定義はテーマではなく、サイト専用のプラグインか mu-plugin に置くことを勧めます。テーマに書くと、テーマを変えたときに入力欄が消え、保存済みのデータが管理画面から見えなくなるためです。ここでは wp-content/mu-plugins/site-fields/ に置く例で進めます。作業前にデータベースのバックアップを取り、ステージング環境で試してください。
mkdir -p wp-content/mu-plugins/site-fields
cd wp-content/mu-plugins/site-fields
composer require htmlburger/carbon-fields
mu-plugins はサブディレクトリ内のファイルを自動では読み込まないため、直下に読み込み用のファイルを置きます。
<?php
// wp-content/mu-plugins/site-fields-loader.php
require_once __DIR__ . '/site-fields/fields.php';
ライブラリを起動してフィールドを登録する
Carbon Fields は after_setup_theme で起動し、carbon_fields_register_fields フックの中でコンテナとフィールドを登録します。ここでは「book」という投稿タイプに書籍情報の入力欄を付ける例です。
<?php
// wp-content/mu-plugins/site-fields/fields.php
use Carbon_Fields\Container;
use Carbon_Fields\Field;
require_once __DIR__ . '/vendor/autoload.php';
add_action( 'after_setup_theme', function () {
\Carbon_Fields\Carbon_Fields::boot();
} );
add_action( 'carbon_fields_register_fields', function () {
Container::make( 'post_meta', '書籍情報' )
->where( 'post_type', '=', 'book' )
->add_fields( array(
Field::make( 'text', 'book_isbn', 'ISBN' )
->set_help_text( 'ハイフンなしの13桁で入力' ),
Field::make( 'date', 'book_release_date', '発売日' ),
Field::make( 'select', 'book_format', '形態' )
->add_options( array(
'paper' => '紙',
'ebook' => '電子書籍',
) ),
Field::make( 'complex', 'book_authors', '著者' )
->add_fields( array(
Field::make( 'text', 'name', '名前' ),
Field::make( 'text', 'role', '役割' ),
) ),
) );
Container::make( 'theme_options', 'サイト設定' )
->add_fields( array(
Field::make( 'text', 'site_contact_email', '問い合わせ先メール' ),
) );
} );
Container::make() の第1引数でどこに入力欄を出すかを決めます。投稿の post_meta のほか、ターム用の term_meta、ユーザー用の user_meta、独自の設定画面を作る theme_options などがあります。where() で表示条件を指定でき、投稿タイプ以外に固定ページのテンプレートや投稿 ID でも絞り込めます。
フィールド名は英小文字とアンダースコアで付け、ほかのプラグインと衝突しない接頭辞を付けておくと安全です。一度データが入ったあとで名前を変えると、既存の値は新しい名前からは読めなくなります。
テンプレートで値を表示する
値の取得には Carbon Fields の関数を使い、出力時にエスケープします。
<?php
// single-book.php のループ内
$isbn = carbon_get_the_post_meta( 'book_isbn' );
$authors = carbon_get_the_post_meta( 'book_authors' );
$email = carbon_get_theme_option( 'site_contact_email' );
if ( $isbn ) {
echo '<p>ISBN: ' . esc_html( $isbn ) . '</p>';
}
if ( ! empty( $authors ) ) {
echo '<ul class="book-authors">';
foreach ( $authors as $author ) {
printf(
'<li>%s(%s)</li>',
esc_html( $author['name'] ),
esc_html( $author['role'] )
);
}
echo '</ul>';
}
if ( $email && is_email( $email ) ) {
echo '<a href="' . esc_url( 'mailto:' . $email ) . '">' . esc_html( $email ) . '</a>';
}
ループの外や別の投稿の値は carbon_get_post_meta( $post_id, 'book_isbn' ) のように投稿 ID を指定します。タームやユーザーには carbon_get_term_meta()、carbon_get_user_meta() があります。
保存形式と get_post_meta の違い
ここが Carbon Fields で最もつまずきやすい点です。単純なフィールドは、メタキーの先頭にアンダースコアが付いた形(例: _book_isbn)で保存されます。そのため get_post_meta( $id, 'book_isbn', true ) では値が取れません。
complex フィールドはさらに独特で、1つの配列としてではなく、行番号や子フィールド名を含む複数のメタキーに分けて保存されます。WP_Query の meta_query で並べ替えや絞り込みをしたい値は、complex の中に入れず、単独のフィールドにしておくほうが扱いやすくなります。正確なキーの形はバージョンによって変わりうるため、必要なときは wp post meta list <投稿ID> で実際の保存内容を確認してください。
また、Carbon Fields の取得関数は、フィールドの登録が終わる前に呼ぶと期待した値を返しません。init より早いタイミングや、carbon_fields_register_fields より前に実行されるコードから値を読む場合は、carbon_fields_fields_registered アクション以降に処理を回します。
ブロックエディターと REST API での扱い
post_meta コンテナはブロックエディターでは、本文の下のメタボックス領域に表示されます。サイドバーのパネルとしては出ないため、編集者には「入力欄は下にある」と案内しておくと混乱が減ります。Carbon Fields には独自ブロックを作る Block::make() もあり、入力欄とサーバー側の描画関数を組み合わせて簡単なブロックを作れます。
ヘッドレス構成などで REST API から値を読みたい場合は、フィールドごとに REST API への公開を設定する方法が用意されています。公開すると誰でも読める状態になりうるので、個人情報や内部用のメモを含むフィールドは公開しないでください。
運用で確認しておくこと
- 更新前の確認: Composer で Carbon Fields を更新する前にステージングで管理画面の保存と表示を確認する。保存処理が壊れると入力内容が失われることがある
- ACF との併用: 同じメタキー名を両方で使わない。片方の保存が他方の値を上書きする
- データの移行: 別の仕組みに乗り換えるときは、保存形式の違いを踏まえて移行スクリプトを書く必要がある。特に
complexの値は変換の手間が大きい - 権限: 入力欄の表示・保存の権限は投稿の編集権限に従う。設定画面(
theme_options)は管理者だけが触れる前提で設計する
まとめ
- Carbon Fields はフィールド定義を PHP で書くライブラリで、Git での差分管理や環境間の統一に向く
- 定義はテーマではなく mu-plugin かサイト専用プラグインに置き、
after_setup_themeで起動、carbon_fields_register_fieldsで登録する - 値は
carbon_get_the_post_meta()などで取得し、esc_html()/esc_url()でエスケープして出力する - 保存キーの先頭にアンダースコアが付き、
complexは複数のメタキーに分かれる。並べ替えに使う値は単独フィールドにする - 更新状況を確認してから採用し、更新はステージングで保存と表示を確かめてから行う