Description
This function checks to see if a parent field (such as Repeater or Flexible Content) has any rows of data to loop over. This is a boolean function, meaning it returns either true
or false
.
This function is intended to be used in conjunction with the_row()
to step through available values.
Using have_rows()
together with the_row()
is intended to feel native much like the have_posts() and the_post() WordPress functions.
Parameters
have_rows( $selector, [$post_id = false] );
$selector
(string) (Required) The field name or field key.$post_id
(mixed) (Optional) The post ID where the value is saved. Defaults to the current post.
Return
(bool) True if a row exists.
Changelog
- Added in version 4.3.0
Examples
Basic loop
This example shows how to loop through a repeater field called "parent_field" and load a sub field value.
if( have_rows('parent_field') ):
while ( have_rows('parent_field') ) : the_row();
$sub_value = get_sub_field('sub_field');
// Do something...
endwhile;
else :
// no rows found
endif;
Display a slider.
This example shows how to loop through a repeater field and generate HTML for a basic image slider.
<?php if( have_rows('slides') ): ?>
<ul class="slides">
<?php while( have_rows('slides') ): the_row();
$image = get_sub_field('image');
?>
<li>
<?php echo wp_get_attachment_image( $image, 'full' ); ?>
<p><?php the_sub_field('caption'); ?></p>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
Display layouts.
This example shows how to loop through a Flexible Content field and generate HTML for different layouts.
<?php if( have_rows('content') ): ?>
<?php while( have_rows('content') ): the_row(); ?>
<?php if( get_row_layout() == 'paragraph' ): ?>
<?php the_sub_field('paragraph'); ?>
<?php elseif( get_row_layout() == 'image' ):
$image = get_sub_field('image');
?>
<figure>
<?php echo wp_get_attachment_image( $image['ID'], 'full' ); ?>
<figcaption><?php echo $image['caption']; ?></figcaption>
</figure>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
Nested loops
This example shows how to loop through a nested Repeater field.
<?php
/**
* Field Structure:
*
* - locations (Repeater)
* - title (Text)
* - description (Textarea)
* - staff_members (Repeater)
* - image (Image)
* - name (Text)
*/
if( have_rows('locations') ): ?>
<div class="locations">
<?php while( have_rows('locations') ): the_row(); ?>
<div class="location">
<h3><?php the_sub_field('title'); ?></h3>
<p><?php the_sub_field('description'); ?></p>
<?php if( have_rows('staff_members') ): ?>
<ul class="staff-members">
<?php while( have_rows('staff_members') ): the_row();
$image = get_sub_field('image');
?>
<li>
<?php echo wp_get_attachment_image( $image['ID'], 'full' ); ?>
<h4><?php the_sub_field('name'); ?></h4>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
Notes
Infinite Loops
Because the have_rows()
function does not step through each row by itself, using this function without the_row()
will create an infinite loop resulting in a white screen.
Scope
The scope of a have_rows()
loop is limited to the current row. This means that any sub field function such as get_sub_field()
or the_sub_field()
will only find data from the current row, not from parent or child rows.
Supercharge Your Website With Premium Features Using ACF PRO
Speed up your workflow and unlock features to better develop websites using ACF Blocks and Options Pages, with the Flexible Content, Repeater, Clone, Gallery Fields & More.