べんりワザ・WordPressのカスタムフィールド(ACF・SCF)

ACFのグループフィールドの出し方

ACF(SCF)のグループフィールドをテンプレートに出す方法。配列で取り出す書き方とhave_rowsを使う書き方、くり返しフィールドとの違い、値が取れないときの原因をまとめました。

ACF(SCF)のグループフィールドは、関連するフィールドを1つの箱にまとめる機能です。取り出し方は「配列で受けてキーを指定する」のが基本——get_field('company')['tel']の形です。

<?php $company = get_field('company'); ?>
<p>電話:<?php echo esc_html($company['tel']); ?></p>
べんりワザACFとSCF、どっちを入れればいい?ACFとSCF、どちらを入れるかで迷っている人はこちら1

グループフィールドは「入力欄をまとめる箱」

グループは、バラバラになりがちなフィールドを意味のあるかたまりにするためのものです。会社情報を例にすると、こうなります。

会社情報(グループ:company)
├── tel      03-1234-5678
├── address  東京都…
└── hours    10:00〜19:00

見た目のメリットは、管理画面で見出し付きにまとまること。もう1つ実用上うれしいのは、フィールド名がぶつからなくなることです。telという名前を店舗情報とお問い合わせ先の両方で使いたいとき、グループで分けておけばshopの中のtelcontactの中のtelとして共存できます。

べんりワザACFの繰り返しフィールドの出し方何個でも増やしたいときはくり返しフィールドの出し方へ

書き方1:配列で受け取る(おすすめ)

グループはget_field()連想配列として返ってきます。キーはサブフィールドの名前です。

<?php $company = get_field('company'); ?>
<?php if ($company) : ?>
  <table class="company">
    <tr><th>電話</th><td><?php echo esc_html($company['tel']); ?></td></tr>
    <tr><th>住所</th><td><?php echo esc_html($company['address']); ?></td></tr>
    <tr><th>営業時間</th><td><?php echo esc_html($company['hours']); ?></td></tr>
  </table>
<?php endif; ?>

変数に1回受けてから何度も使えるので、同じグループの値をいくつも出すページではこの書き方がいちばん短くなります。

サブフィールドが空の可能性があるときは、個別にifを添えます。

<?php if (!empty($company['tel'])) : ?>
  <p>電話:<?php echo esc_html($company['tel']); ?></p>
<?php endif; ?>

書き方2:have_rowsでループに入る

グループは「1行だけのくり返し」とも見なせるので、have_rows()でも扱えます。この形なら中身はget_sub_field()で取り出せます。

<?php if (have_rows('company')) : ?>
  <?php while (have_rows('company')) : the_row(); ?>
    <p>電話:<?php the_sub_field('tel'); ?></p>
    <p>住所:<?php the_sub_field('address'); ?></p>
  <?php endwhile; ?>
<?php endif; ?>

くり返しフィールドと書き方をそろえられるのが利点です。配列のキーをタイプミスして気づかない、という事故も減ります。好みで選んでかまいませんが、1ページの中では書き方をどちらかにそろえると読みやすくなります。

グループの中の画像

グループの中に画像フィールドを置いた場合も、取り出し方は同じです。返り値の設定に合わせて使い分けます。

<?php $hero = get_field('hero'); ?>
<?php if ($hero) : ?>
  <section class="hero">
    <?php echo wp_get_attachment_image($hero['image'], 'full'); ?>   <!-- 返り値=画像ID -->
    <h1><?php echo esc_html($hero['catch']); ?></h1>
  </section>
<?php endif; ?>

返り値が画像配列の場合は$hero['image']['url']のように、配列をもう1段たどります。

べんりワザACFで画像を表示する方法画像フィールドの返り値(ID・URL・配列)の使い分けはこちら

入れ子のグループ

グループの中にグループを入れたときは、配列を続けてたどるだけです。

<?php $s = get_field('shop'); ?>
<p><?php echo esc_html($s['sns']['twitter']); ?></p>

have_rows()の書き方なら、内側でもう一度have_rows('sns')に入ります。階層が深くなるとテンプレートが読みづらくなるので、入れ子は2段までに抑えるのが実務での目安です。

くり返しフィールドの中のグループ

くり返しの行の中にグループがある場合は、get_sub_field()で受けた結果が配列になります。

<?php while (have_rows('staff')) : the_row(); ?>
  <?php $profile = get_sub_field('profile'); ?>
  <p><?php echo esc_html($profile['name']); ?><?php echo esc_html($profile['role']); ?>)</p>
<?php endwhile; ?>

まとめ

  1. グループフィールドは関連する入力欄をまとめる箱。フィールド名の衝突も避けられる
  2. 取り出しはget_field('箱')['中身']が基本。have_rows()get_sub_field()でも書ける
  3. 1セットならグループ、何個も増やすならくり返し——個数で選ぶ
  4. サブフィールド名を直接get_field()に渡しても取れない。箱を開けてから中身

管理画面が整理されると、更新をお願いする相手にも親切なサイトになります。

よくある質問

グループフィールドの中の値はどう取り出しますか?
$g = get_field('group_name'); のあと $g['sub_name'] で取り出します。またはhave_rows('group_name')でループに入り、get_sub_field('sub_name')でも取れます。get_field('sub_name')のように中の名前を直接指定しても取れません。
グループフィールドとくり返しフィールドの違いは?
グループは同じセットを1つだけ持つ入れ物(返り値は連想配列)、くり返しは同じセットを何個でも増やせる入れ物(返り値は配列の配列)です。会社情報のように1組しかないものはグループ、スタッフ紹介のように増えるものはくり返しを使います。
グループフィールドで「Array」と表示されます
グループ自体は配列なので、the_field('group_name')では表示できません。中のサブフィールドを名前で取り出して出力してください。
グループの中にグループを入れられますか?
入れられます。取り出すときは$g['inner']['key']のように配列を続けてたどるか、have_rows()を入れ子にします。