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.


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.


(bool) True if a row exists.


  • Added in version 4.3.0


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...
else :
    // no rows found

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');
            <?php echo wp_get_attachment_image( $image, 'full' ); ?>
            <p><?php the_sub_field('caption'); ?></p>
    <?php endwhile; ?>
<?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');
                <?php echo wp_get_attachment_image( $image['ID'], 'full' ); ?>
                <figcaption><?php echo $image['caption']; ?></figcaption>
        <?php endif; ?>
    <?php endwhile; ?>
<?php endif; ?>

Nested loops

This example shows how to loop through a nested Repeater field.


 * 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');
                        <?php echo wp_get_attachment_image( $image['ID'], 'full' ); ?>
                        <h4><?php the_sub_field('name'); ?></h4>
                <?php endwhile; ?>
            <?php endif; ?>
    <?php endwhile; ?>
<?php endif; ?>


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.


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.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.