Les champs répéteurs stockent des lignes ordonnées de sous-champs. Chaque ligne contient le même ensemble de sous-champs. C’est une fonctionnalité PRO idéale pour des listes structurées telles que les membres d’une équipe, les éléments FAQ, les niveaux de prix, les spécifications et tout autre modèle de données répétitives.
Boucle de Répéteur de Base
php
<?php if ( have_rows( 'team_members' ) ) : ?>
<div class="team-grid">
<?php while ( have_rows( 'team_members' ) ) : the_row(); ?>
<div class="team-card">
<?php $photo = get_sub_field( 'photo' ); ?>
<?php if ( $photo ) : ?>
<img src="<?php echo esc_url( $photo['url'] ); ?>"
alt="<?php echo esc_attr( $photo['alt'] ); ?>"
class="team-card__photo">
<?php endif; ?>
<h3><?php the_sub_field( 'name' ); ?></h3>
<p class="position"><?php the_sub_field( 'position' ); ?></p>
<p class="bio"><?php the_sub_field( 'bio' ); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php else : ?>
<p>No team members found.</p>
<?php endif; ?>Mise en Page de Tableau
php
<?php if ( have_rows( 'specifications' ) ) : ?>
<table class="specs-table">
<thead><tr><th>Property</th><th>Value</th><th>Unit</th></tr></thead>
<tbody>
<?php while ( have_rows( 'specifications' ) ) : the_row(); ?>
<tr>
<td><?php the_sub_field( 'label' ); ?></td>
<td><?php the_sub_field( 'value' ); ?></td>
<td><?php the_sub_field( 'unit' ); ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
<?php endif; ?>Répéteurs Imbriqués
Les répéteurs peuvent contenir d’autres répéteurs. L’appel interne have_rows() est automatiquement limité à la ligne extérieure actuelle.
php
<?php
// A "departments" repeater with a nested "employees" repeater
if ( have_rows( 'departments' ) ) :
while ( have_rows( 'departments' ) ) : the_row(); ?>
<section class="department">
<h2><?php the_sub_field( 'department_name' ); ?></h2>
<?php if ( have_rows( 'employees' ) ) : ?>
<div class="employee-grid">
<?php while ( have_rows( 'employees' ) ) : the_row(); ?>
<div class="employee-card">
<h4><?php the_sub_field( 'employee_name' ); ?></h4>
<span class="role"><?php the_sub_field( 'role' ); ?></span>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</section>
<?php endwhile;
endif;
?>Modèle Accordéon/FAQ
php
<?php if ( have_rows( 'faq_items' ) ) : ?>
<div class="faq-accordion" itemscope itemtype="https://schema.org/FAQPage">
<?php while ( have_rows( 'faq_items' ) ) : the_row();
$id = 'faq-' . get_row_index();
?>
<div class="faq-item" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">
<h3 class="faq-question" itemprop="name">
<button aria-expanded="false" aria-controls="<?php echo $id; ?>">
<?php the_sub_field( 'question' ); ?>
</button>
</h3>
<div class="faq-answer" id="<?php echo $id; ?>" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
<div itemprop="text"><?php the_sub_field( 'answer' ); ?></div>
</div>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>Mises à Jour de Lignes Programmatiques
php
// Add a new row to a repeater
$members = get_field( 'team_members', 42 );
if ( ! is_array( $members ) ) {
$members = [];
}
$members[] = [
'name' => 'Jane Doe',
'position' => 'CTO',
'bio' => 'Experienced technology leader.',
];
$field_def = FIELDFORGE_Field_Groups::instance()->find_field( 'team_members', 42 );
FIELDFORGE_Field_Values::instance()->save_compound_field(
'team_members',
$members,
42,
$field_def
);
// Remove a specific row
$members = get_field( 'team_members', 42 );
array_splice( $members, 2, 1 ); // Remove the 3rd row (index 2)
$field_def = FIELDFORGE_Field_Groups::instance()->find_field( 'team_members', 42 );
FIELDFORGE_Field_Values::instance()->save_compound_field(
'team_members',
$members,
42,
$field_def
);Comptage des Lignes
php
$team = get_field( 'team_members' );
$count = $team ? count( $team ) : 0;
echo '<p>Team size: ' . $count . ' members</p>';
// Show "empty state" when no rows exist
if ( ! have_rows( 'testimonials' ) ) {
echo '<div class="empty-state"><p>No testimonials yet.</p></div>';
}—