Advanced Custom Fields(ACF)は、カスタムフィールドを扱う定番プラグインです。管理画面で入力欄を作り、テンプレートで the_field() や get_field() を呼ぶだけで値を出力できます。ところが実際の制作では、「入力したのに表示されない」「空の値が返ってくる」という声がよく挙がります。
この記事では、ACFの値が出力されないときの原因を、パターン別に整理して解説します。原因が分かれば、ほとんどは数分で解決できます。
まず確認:正しい基本の書き方
最初に、基本の呼び出し方を確認します。
<?php
// 値を取得して変数に入れる
$text = get_field( 'catch_copy' );
if ( $text ) {
echo esc_html( $text );
}
// その場で出力する
the_field( 'catch_copy' );
?>
get_field() は値を返し、the_field() は値をそのまま出力します。出力前のチェックや加工が必要なときは、get_field()を使うのが基本です。この2つの使い分けを間違えて、echo the_field() と書いてしまうこともありますが、the_field() はそれ自体が出力するため、冗長です。
原因1:フィールド名とフィールドキーの取り違え
ACFには、フィールドの「ラベル」「名前」「キー」という3つの識別子があります。
- ラベル:管理画面に表示される名前(日本語でも可)。コードでは使えない。
- 名前:コードで指定する名前(例:
catch_copy)。 - キー:ACFが内部で使うID(例:
field_65a1b2c3d4e5f)。
get_field()には、ラベルではなく「名前」を渡します。日本語のラベルを指定していたり、スペルが1文字違っていたりすると、値は取得できません。フィールドグループの編集画面で、名前の欄をコピーして貼り付けるのが確実です。
原因2:投稿IDが合っていない
get_field()は、デフォルトでは「現在のループ中の投稿」の値を取得します。ループの外で使ったり、別の投稿の値が必要だったりするときは、第2引数でIDを指定する必要があります。
// 特定の投稿IDを指定する
$value = get_field( 'catch_copy', 123 );
// 固定ページ「トップ」の値をどこからでも取得する
$front_id = get_option( 'page_on_front' );
$value = get_field( 'catch_copy', $front_id );
よくあるのが、サブクエリのループ後に、ID指定なしで呼んでいるケースです。wp_reset_postdata() を忘れたままだと、サブクエリの最後の投稿の値が返ってきたり、空になったりします。また、アーカイブページでは、現在のページ自体は「投稿」ではないため、アーカイブ用の値は別途指定が必要です。
タームやユーザーの値を取得する場合
タクソノミーのターム、ユーザー、オプションページの値は、第2引数に専用の形式で渡します。
// タームのフィールド
$term = get_queried_object();
$value = get_field( 'term_color', $term );
// 別の指定方法
$value = get_field( 'term_color', 'category_5' );
// ユーザーのフィールド
$value = get_field( 'phone', 'user_1' );
// オプションページのフィールド
$value = get_field( 'footer_text', 'option' );
タームの場合の category_5 のような指定は、「タクソノミー名_ターム ID」の形式です。この形式を間違えると、空になります。
原因3:リピーターフィールドのループの書き方
リピーターフィールドは、通常のフィールドと取得方法が異なります。値を一括で取得するのではなく、行ごとにループします。
<?php if ( have_rows( 'staff_list' ) ) : ?>
<ul>
<?php while ( have_rows( 'staff_list' ) ) : the_row(); ?>
<li>
<?php the_sub_field( 'name' ); ?>
(<?php the_sub_field( 'role' ); ?>)
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
ここで、次の点に注意してください。
- ループの中では、
get_field()ではなくget_sub_field()/the_sub_field()を使う - 入れ子(リピーターの中のリピーター)では、内側も
have_rows()でループする - ループの外から子の値を取りたいときは、
get_field( 'staff_list' )で配列として取得してから、foreachで処理する
配列として取得する方法も覚えておくと、並べ替えや件数のカウントなど、柔軟な処理ができます。
$rows = get_field( 'staff_list' );
if ( $rows ) {
foreach ( $rows as $row ) {
echo esc_html( $row['name'] );
}
}
原因4:戻り値の形式が想定と違う
画像、ファイル、リンク、投稿オブジェクトなどのフィールドは、「戻り値」の形式を設定できます。この設定と、テンプレートでの扱い方が合っていないと、何も表示されません。
画像フィールドの場合
- 画像配列:配列で返る。
$image['url']のように使う。 - 画像URL:URL文字列で返る。そのまま
srcに使える。 - 画像ID:数値で返る。
wp_get_attachment_image()などと組み合わせる。
戻り値が「配列」なのに <img src="<?php the_field( 'photo' ); ?>"> と書くと、「Array」と出力されてしまいます。逆に、戻り値が「URL」なのに $image['url'] と書くと、PHPの警告やエラー(PHP 8以降は致命的エラー)になります。
$image = get_field( 'photo' ); // 戻り値:画像配列の場合
if ( $image ) {
echo '<img src="' . esc_url( $image['sizes']['medium'] ) . '" alt="' . esc_attr( $image['alt'] ) . '">';
}
フィールドグループの設定画面で「戻り値」を確認し、書き方を合わせてください。迷ったときは、var_dump( get_field( 'photo' ) ) で中身を見るのが早道です。
リンクフィールドの場合
リンクフィールドは、配列で返る場合は url・title・target の3つを持ちます。新しいタブで開く設定の target を忘れずに出力しましょう。
原因5:フィールドグループの表示条件が合っていない
編集画面で入力欄が表示されなければ、そもそも値を保存できません。フィールドグループの「表示条件」が、対象の投稿タイプ、テンプレート、カテゴリーなどと一致しているか確認してください。
- ページテンプレートを条件にしている場合、テンプレートを選択して保存するまで、入力欄が出ない
- カスタム投稿タイプを追加したのに、条件を更新していない
- フィールドグループが「無効」状態になっている
また、フィールド名を途中で変更すると、既存の投稿には旧名で保存された値が残るため、新しい名前では空になります。既存の投稿の値を入力し直すか、データを移行する必要があります。
原因6:プレビューや下書きで値が出ない
公開前のプレビューでは、保存済みの最新の値が反映されないことがあります。特に、リビジョン機能とACFの組み合わせでは、プレビュー時に過去の値が表示されたり、空になったりすることがあります。
この場合は、プレビューではなく、一度「更新」を押して公開状態で確認するか、ACFのバージョンを最新にして改善されるか試してください。
原因7:キャッシュと出力のエスケープ
最後に、意外と見落とすのがキャッシュです。
- ページキャッシュ系のプラグインが、古い表示を返している
- オブジェクトキャッシュ(Redisなど)が、古い値を保持している
キャッシュをクリアして表示が変わるなら、原因はACFではなくキャッシュです。また、値がHTMLタグを含む場合に esc_html() で出力すると、タグが文字として表示されます。WYSIWYGフィールドの値はHTMLを含むため、wp_kses_post() を通して出力するなど、フィールドの種類に合わせたエスケープを選んでください。なお、the_field() は echo get_field() と同じで、自動ではエスケープされません。
デバッグの進め方
原因が分からないときは、次の順番で確認します。
var_dump( get_field( 'フィールド名', 投稿ID ) )で、実際の戻り値を確認する- 値が
NULLやfalseなら、フィールド名・投稿IDを疑う - 値が
Arrayなら、戻り値の形式と、書き方が合っているか確認する - 管理画面の編集画面で、実際に値が保存されているか確認する
- キャッシュを無効にして、再度確認する
「何が返ってきているか」を見れば、原因の見当は、ほぼつきます。推測でコードを書き直す前に、まず値の中身を確認する癖をつけましょう。
まとめ
ACFの値が出力されない原因は、次の7つのどれかに当てはまることがほとんどです。
- ラベルではなく、フィールドの「名前」を指定する
- ループの外やサブクエリ後は、投稿IDを明示する(ターム・ユーザー・オプションは専用の形式で指定)
- リピーターは、have_rows()とget_sub_field()でループする
- 画像などは、戻り値の形式に合わせた書き方にする
- フィールドグループの表示条件を確認する
- プレビューでは、最新の値が出ないことがある
- キャッシュと、エスケープ関数の選び方を確認する
まずは var_dump() で中身を見る。この一手が、最短の解決につながります。


コメント