/

Advanced Custom Fields PROで繰り返しフィールドが入れ子になるとき

Advanced Custom Fields PROで繰り返しフィールドが入れ子になるとき

Advanced Custom Fields はカスタムフィールドを作成したいときに便利なプラグインの一つです。開発者の人で全く触ったことない人はいないのではないでしょうか。

そんな「Advanced Custom Fields」の有料版「Advanced Custom Fields PRO」には「繰り返しフィールド」という非常に便利なフィールドが存在します。

投稿ごとに対象を可変に出来るので非常に便利な機能です。

今回はその「繰り返しフィールド」を入れ子にした際に若干時間をロスしたためその使い方をまとめてきます。

繰り返しフィールドの入れ子

最初の繰り返しフィールドを「repeat_1」とし、その中に「label」というフィールドと繰り返しフィールドの「repeat_2」を定義します。

「repeat_2」の中には「content」「style」の二つのフィールドを定義しています。

コードで繰り返しフィールドを呼び出す

基本的な繰り返しフィールドの呼び出し方は以下のようになります。WordPressの投稿を取得する形と似ているのでわかりやすいと思います。

if ( have_rows( 'repeat_1' ) ) :
    while ( have_rows( 'repeat_1' ) ) : the_row();
        $label = get_sub_field( 'label' );
    endwhile;
endif;

下記の画像のようにデータが入力されているとします。

その場合先ほどのコードで追っていくと

  • 「repeat_1」に項目が存在する
  • 「repeat_1」の項目を上から順に取得
  • 取得した項目をカレントとして展開
  • $labelに代入($labelの値は「ハンバーグ」「ステーキ」「ラーメン」の順に変化する)

という感じになります。

「repeat_1」内の繰り返しフィールドにも項目を追加した形でデータを取得します。

データは以下の画像の通りです。

繰り返しフィールドの中に繰り返しフィールドがある形ですね。

こちらを取得してみます。

if ( have_rows( 'repeat_1' ) ) :
    while ( have_rows( 'repeat_1' ) ) : the_row();
        $label = get_sub_field( 'label' );

        if ( have_rows( 'repeat_2' ) ) :
            while ( have_rows( 'repeat_2' ) ) : the_row();
                $content = get_sub_field( 'content' );
                $style = get_sub_field( 'style' );
            endwhile;
        endif;
    endwhile;
endif;

ループの流れを追ってみます。

  • 「repeat_1」に項目が存在する
  • 「repeat_1」の項目を上から順に取得
  • 「repeat_1」の取得した項目をカレントとして展開
  • $labelに「ハンバーグ」を代入
  • 「repeat_2」に項目が存在する
  • 「repeat_2」の項目を上から順に取得
  • 「repeat_2」取得した項目をカレントとして展開
  • $contentに「デミグラス」、$stlyeに「row」が代入される
  • 「repeat_2」の次の項目に移り$contentに「ケチャップ」、$stlyeに「column」が代入される
  • 「repeat_1」の次の項目に移り$labelに「ステーキ」が代入される
  • 「repeat_2」は存在しない
  • 「repeat_1」の次の項目に移り$labelに「ラーメン」が代入される
  • 「repeat_2」は存在しない

基本的にはループ一つの場合と変わりません。

ポイントはカレントに展開するところです。「repeat_1」の項目を展開中に当然ながら「repeat_2」の内容は取得できません。「repeat_2」の項目を展開中に「repeat_1」の項目を取得することもできないので注意してください。(「repeat_2」のループ中にget_sub_field( ‘label’ )はできない。)

どうしても二つ目のループ途中に一つ目のループの項目が取得したい場合にはどうしたら良いでしょうか。(あまりないとは思いますが…)

ACFではカレントを設定する方法以外にも配列により取得することも可能です。

繰り返しフィールド内に繰り返しフィールドがある例を配列の形で書き直してみます。

$repeat_1 = get_field( 'repeat_1' );
if ( $repeat_1 ) {
    foreach ( $repeat_1 as $r_1_row ) {
        $label = $r_1_row['label'];

        $repeat_2 = $r_1_row['repeat_2'];
        if ( $repeat_2 ) {
            foreach ( $repeat_2 as $r_2_row ) {
                $content = $r_2_row['content'];
                $style = $r_2_row['style'];
            }
        }
    }
}

この形であれば$labelをループ内で定義することも可能です。(今回の例では明らかに無駄なのでやりませんが必要となるケースもあるかもしれません。)