ACF(Advanced Custom Fields)の繰り返しフィールドで、「最後のサブフィールドだけを表示したい」という場面に出くわすことがあります。以前、逆に最初のサブフィールドだけを表示する方法を解説しましたが、今回はその反対のパターンです。
結論から言うと、サブフィールドの総数をcount()で数え、ループ中のカウンターが総数と一致したとき(=最後の1件)だけif文で表示することで実現できます。この記事では、そのサンプルコードと仕組みを解説します。
<?php if (have_rows('repeater')) : ?>
<?php $repeaterCount = count(get_field('repeater')); // サブフィールドの数を数える ?>
<?php $i = 1; ?>
<?php while (have_rows('repeater')) : the_row();
// vars
$subField = get_sub_field('subField');
?>
<?php if ($i == $repeaterCount) : // 最後のサブフィールドのときだけ表示 ?>
<?php echo $subField; ?>
<?php endif; ?>
<?php ++$i; ?>
<?php endwhile; ?>
<?php endif; ?>
やっていることは大きく2つです。
まず、count(get_field('repeater'))で繰り返しフィールドのサブフィールドの総数を数え、$repeaterCountに入れておきます。get_field()は繰り返しフィールド全体を配列として返すので、その要素数がそのまま件数になります。
次に、ループの中でカウンター$iを1ずつ増やしていき、$iが総数$repeaterCountと一致したとき=最後の1件のときだけ、if文で値を表示しています。カウンターと総数を突き合わせるだけのシンプルな仕組みです。
ポイントは、$iを増やす++$i;をif文の外(ループの最後)に置くことです。表示するかどうかにかかわらず毎回カウントを進めることで、常に「今が何件目か」を正しく保てます。もし加算をif文の中に入れてしまうと、カウントがずれて最後の1件を正しく判定できなくなるので注意してください。
この「総数を数えて、現在の位置と突き合わせる」という考え方は、ACFに限らずループ処理全般で応用が利きます。最初の1件・最後の1件・偶数番目だけ、といった条件も、カウンターと総数の比較で自在に表現できます。
ちなみに、手動でカウンター$iを用意する代わりに、ACFが備えているget_row_index()を使う方法もあります。これはループ中の現在の行番号(1始まり)を返す関数なので、if (get_row_index() == $repeaterCount)と書けば、カウンターを自前で管理せずに最後の1件を判定できます。コードが少し短くなるので、好みに応じて使ってみてください。
「最後の1件を取り出すだけ」であれば、ループを使わず配列で受け取る方法もあります。get_field()は繰り返しフィールドを配列で返すので、PHPのend()で末尾の要素を直接取得できます。
<?php
$rows = get_field('repeater');
if ($rows) {
$last = end($rows); // 配列の最後の要素を取得
echo esc_html($last['subField']);
}
?>
カウンターを使うwhileループに比べて記述が短く済むのが利点です。一方、最後の1件に至るまでの各行でも処理をしたい(途中も表示しつつ最後だけ装飾を変える、など)場合は、カウンターを使うループのほうが柔軟に対応できます。目的に合わせて選ぶとよいでしょう。
最後の1件だけを表示する場面はそう多くありませんが、たとえば「更新履歴の中で最新(=末尾)の1件だけを別枠で見せたい」「一覧の最後の項目だけ扱いを変えたい」といったときに役立ちます。実際の案件で使う機会があったので、備忘も兼ねてまとめました。
なお、「最後の項目だけスタイルを変える」だけであれば、CSSの:last-childで済むこともあります。表示そのものを制御したい(出力するかどうかを分けたい)場合は、今回のようにPHP側で判定するのが確実です。見た目だけの調整か、出力の制御かで使い分けましょう。
count()で総数を数える$iが総数と一致したときだけif文で表示するif文の外に置き、毎回進める:last-child、出力制御ならPHP判定と使い分けるカウンターと総数を突き合わせる考え方は、最後の1件に限らず「特定の順番の項目だけを扱いたい」場面全般に応用できます。ACFの繰り返しフィールドを扱うときの引き出しとして覚えておくと便利です。