ACFリピーターフィールド活用術【実案件パターン付き】 – NPC
ACFリピーターフィールド活用術 – 実案件での使い方
ACF(Advanced Custom Fields)の繰り返しフィールド(リピーターフィールド)は、WordPress制作で最も使用頻度の高い機能のひとつ。料金表、スタッフ紹介、FAQ、実績一覧——「同じ構造のデータを複数登録したい」という要望は、ほぼすべての案件で出てくる。
ただ、初めて触ると「どう設計すればいいの?」「出力コードはどう書くの?」と手が止まりがち。自分も最初はそうだった。
この記事では、2016年からWordPress制作をやってきた中で身についたリピーターフィールドの実践的な使い方を、実案件のパターンとあわせて紹介する。
リピーターフィールドとは? 基本をおさらい
ACFリピーターフィールドは、同じ構造の入力欄を「好きな数だけ繰り返し追加できる」カスタムフィールド。ACF Proに含まれる有料機能になる。
※「ACF Pro」とは、Advanced Custom Fields の有料版のこと。無料版では使えないリピーターフィールド・フレキシブルコンテンツ・ギャラリーフィールドなどの高度な機能が使えるようになる。年間ライセンス制で、クライアント案件に使う場合はライセンスの取り扱いを事前に確認しておくことが重要。
たとえば「料金プラン」を作りたい場合、以下のようなサブフィールド(繰り返しの中の各項目)を定義する。
※「サブフィールド」とは、リピーターフィールドの中に設定する個々の入力欄のこと。「プラン名」「月額料金」「説明文」など、1行分のデータを構成する部品のようなもの。
- プラン名(テキスト)
- 月額料金(数値)
- 説明文(テキストエリア)
- おすすめフラグ(真偽値)
リピーターフィールドをイメージしやすいたとえで言うと、Excelの表に近い。1行が1件分のデータ(例:1プラン分)で、列がサブフィールド(プラン名・料金・説明文)に対応する。Excelで行を追加するように、管理画面で「行を追加」ボタンを押すだけでデータを増やせる。違うのは、Excelと違って入力フォームが整備されているため、クライアントが直感的に操作できること。
これらのサブフィールドをまとめると、リピーターフィールドは次のような構造になっている。
- リピーター行(1行 = 1プラン)
- plan_name — プラン名(テキスト)
- monthly_price — 月額料金(数値)
- description — 説明文(テキストエリア)
- is_recommended — おすすめフラグ(真偽値)
クライアントは管理画面から「行を追加」ボタンを押すだけで、プランをいくつでも追加できる。投稿本文にベタ書きする必要がなく、構造化されたデータとして扱えるのが最大のメリットだ。
基本の出力コード
テンプレートファイルでの出力は、have_rows() と the_row() のループで書く。
<?php if ( have_rows( 'price_plans' ) ) : ?>
<div class="price-plans">
<?php while ( have_rows( 'price_plans' ) ) : the_row(); ?>
<div class="price-plan">
<h3><?php the_sub_field( 'plan_name' ); ?></h3>
<p class="price">月額 <?php the_sub_field( 'monthly_price' ); ?>円</p>
<p><?php the_sub_field( 'description' ); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
ポイントは3つ。
have_rows('フィールド名')でデータがあるか確認するthe_row()で現在の行に移動する(これを忘れると無限ループになる)- サブフィールドは
get_sub_field()(値を取得)やthe_sub_field()(そのまま出力)で呼び出す
※「have_rows()」とは、ACFのリピーターフィールドにデータが存在するかどうかを確認しながらループを回すための関数。「the_row()」は各繰り返し行に移動するために必ず呼び出す関数で、これを忘れると無限ループが発生する。
※「get_sub_field()」とは、リピーターの各行にあるサブフィールドの値を変数として取得する関数。「the_sub_field()」はそのまま画面に出力する関数。画像URLなど加工が必要な場合は get_sub_field()、テキストをそのまま表示する場合は the_sub_field() を使うのが基本的な使い分け。
実案件でよく使う3つのパターン
ここからは、自分が実際の案件でよく使っているリピーターフィールドのパターンを紹介する。
3つのパターンはそれぞれ用途と設計思想が異なる。選び方の目安は以下のとおり。
- サブフィールド2つだけのシンプル構成
- 質問と回答の対をセットで管理
- 構造化データ(JSON-LD)と組み合わせやすい
- 画像フィールドを含む中程度の構成
- 人数が10人以下ならリピーターが管理しやすい
- それ以上ならカスタム投稿タイプを検討
- 数値+テキストの二重対応が実用的
- 「要相談」など柔軟な表示に対応できる
- クライアントからの変更依頼が最も多いパターン
パターン1: FAQ(よくある質問)
ほぼ全案件で登場するのがFAQ。リピーターフィールドとの相性が抜群にいい。
サブフィールドの構成はシンプルに2つだけ。
question(テキスト)— 質問文answer(テキストエリアまたはWYSIWYG)— 回答文
※「WYSIWYG(ウィジウィグ)」とは、”What You See Is What You Get”(見たままが得られる)の略で、入力した内容が実際の表示に近い形でリアルタイムにプレビューされるエディターのこと。ACFのフィールドタイプとして選ぶと、管理画面でWordのような書式設定ができる入力欄が追加される。太字・リスト・リンクなどの書式が必要な回答文に向いている。
<?php if ( have_rows( 'faq_items' ) ) : ?>
<dl class="faq-list">
<?php while ( have_rows( 'faq_items' ) ) : the_row(); ?>
<dt><?php the_sub_field( 'question' ); ?></dt>
<dd><?php the_sub_field( 'answer' ); ?></dd>
<?php endwhile; ?>
</dl>
<?php endif; ?>
HTMLは <dl>(定義リスト)で書くのがおすすめ。意味的に「質問と回答の対」を表現でき、SEO的にも構造が伝わりやすい。アコーディオンのUIはCSSとJavaScriptで後から付ければいい。
FAQ構造化データ(JSON-LD)を自動生成する処理と組み合わせると、検索結果にFAQが表示される可能性も出てくる。
※「JSON-LD」とは、Googleなどの検索エンジンに向けてページの内容を構造化して伝えるためのデータ形式のこと。HTMLの <script> タグ内に記述することで、検索結果にFAQや評価星などのリッチリザルトが表示される可能性が高まる。
パターン2: スタッフ・チーム紹介
コーポレートサイトで定番のスタッフ紹介。カスタム投稿タイプで作る方法もあるが、人数が少ない(10人以下程度)場合はリピーターフィールドのほうが管理が楽。
サブフィールドの構成例はこんな感じ。
photo(画像)— 顔写真name(テキスト)— 名前position(テキスト)— 役職profile(テキストエリア)— 紹介文
<?php if ( have_rows( 'staff_members' ) ) : ?>
<div class="staff-grid">
<?php while ( have_rows( 'staff_members' ) ) : the_row();
$photo = get_sub_field( 'photo' );
?>
<div class="staff-card">
<?php if ( $photo ) : ?>
<img src="<?php echo esc_url( $photo['sizes']['medium'] ); ?>"
alt="<?php echo esc_attr( get_sub_field( 'name' ) ); ?>">
<?php endif; ?>
<h3><?php the_sub_field( 'name' ); ?></h3>
<p class="position"><?php the_sub_field( 'position' ); ?></p>
<p><?php the_sub_field( 'profile' ); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
画像フィールドの返り値形式を「画像配列」にしておくと、$photo['sizes']['medium'] のように必要なサイズを指定できる。フルサイズの画像をそのまま表示すると重くなるので、ここは意識しておきたいポイント。
パターン3: サービス・料金表
料金ページやサービス一覧も定番。冒頭で触れた料金プランの応用になる。
ここで一つ実務的なTipsを。料金が未定の項目や「要相談」のケースに対応するために、金額フィールドとは別に「表示テキスト」フィールドを用意しておくと便利。
<?php while ( have_rows( 'service_plans' ) ) : the_row();
$price = get_sub_field( 'price' );
$price_text = get_sub_field( 'price_text' );
?>
<div class="service-item">
<h3><?php the_sub_field( 'service_name' ); ?></h3>
<p class="price">
<?php
if ( $price_text ) {
echo esc_html( $price_text );
} elseif ( $price ) {
echo number_format( $price ) . '円〜';
}
?>
</p>
</div>
<?php endwhile; ?>
「数値で入力できるケース」と「テキストで自由に入力したいケース」の両方に対応しておくと、クライアントから「ここは”要相談”にしたいんだけど……」と言われたときに慌てなくて済む。
リピーターフィールド設計で気をつけていること
何十案件もリピーターフィールドを使ってきて、自分なりにルール化していることをいくつか共有する。
設計時に特に意識しているポイントをまとめると次のとおり。
have_rows() の条件分岐内に入れるのが安全。サブフィールドは5個以下に抑える
サブフィールドが多すぎると、管理画面での入力が大変になる。クライアントが「これどこに何を入れるの?」となったら設計ミス。目安としてサブフィールドは5個以下、どうしても増える場合はグループフィールドでまとめるか、そもそもカスタム投稿タイプに切り替えることを検討する。
フィールド名は英語・スネークケースで統一する
ACFのフィールド名は staff_members のように英語のスネークケースで統一する。日本語のラベルは「表示名」で設定すればいい。コードで呼び出すときに get_sub_field('スタッフ名前') とか書きたくない。
※「スネークケース」とは、単語と単語をアンダースコア(_)でつなぐ命名規則のこと。例:staff_members、monthly_price。プログラムのコードで変数名・関数名・フィールド名に使われることが多く、スペースが使えない場面での単語区切りとして広く採用されている。
リピーターの入れ子(ネスト)は1階層まで
リピーターの中にリピーターを入れる「ネスト」は、ACFの仕様上可能だが、コードが複雑になりすぎる。クライアントの管理画面も分かりにくくなる。自分のルールとして、ネストは1階層まで。それ以上必要な場合は設計を見直す。
最大行数を設定しておく
リピーターフィールドには「最大行数」を設定できる。これを設定しておかないと、クライアントが100行とか追加してしまい、ページが重くなったりレイアウトが崩れたりすることがある。FAQなら20件、スタッフなら30件など、現実的な上限を設定しておこう。
空の場合の表示を忘れない
リピーターフィールドに何も入力されていないケースは必ずある。have_rows() で分岐しているので表示はされないが、そのセクションの見出しだけが残って見た目がおかしくなることがある。セクション全体を have_rows() の条件分岐内に入れるのが安全。
まとめ: リピーターフィールドは「設計」が9割
ACFリピーターフィールドは、コードの書き方自体はシンプル。have_rows() → the_row() → get_sub_field() のパターンを覚えてしまえば、あとは応用するだけ。
むしろ大事なのは設計段階。「クライアントが迷わず入力できるか?」「将来データが増えても破綻しないか?」——ここを最初に詰めておくことで、納品後のトラブルが激減する。
リピーターフィールドの使い方で迷ったときは、以下の3点を思い出してほしい。
- サブフィールドはシンプルに保つ(5個以下)
- クライアントの管理画面での操作感を想像する
- 空データ・想定外のデータへの対応を忘れない
この記事が、リピーターフィールドを使いこなすきっかけになれば嬉しい。
※この記事はNPCの中の人の実務経験をもとに書いています。