have_rows()

Description

This function checks to see if the field (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 a replacement for the has_sub_fields() function, however, it has some small but significant differences. The main difference is that this function does not step through the rows by itself, so to step through the rows, you must also use the the_row() function.

Using have_rows() together with the_row() is intended to feel native much like the have_posts() and the_post() WordPress functions.

Change Log

  • Added in version 4.3.0

Parameters

<?php have_rows($field_name, $post_id); ?>
  • $field_name: the name of the repeater / flexible content field to loop through. eg “gallery_images” (required)
  • $post_id: Specific post ID where your value was entered. Defaults to current post ID (not required). This can also be options / taxonomies / users / etc

Usage

Basic loop

if( have_rows('parent_field') ):

    while ( have_rows('parent_field') ) : the_row();

        // Your loop code
        the_sub_field('sub_field');

    endwhile;

else :

    // no rows found

endif;

Repeater field loop

<?php if( have_rows('repeater') ): ?>

	<ul class="slides">

	<?php while( have_rows('repeater') ): the_row(); 

		$image = get_sub_field('image');

		?>

		<li class="slide">

			<img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt'] ?>" />

		    <p class="caption"><?php the_sub_field('caption'); ?></p>

		</li>

	<?php endwhile; ?>

	</ul>

<?php endif; ?>

Flexible content loop

<?php if( have_rows('flexible_content') ): ?>

	<ul class="slides">

	<?php while( have_rows('flexible_content') ): the_row(); ?>

		<li class="slide">

			<?php if( get_row_layout() == 'image_slide' ): 

				$image = get_sub_field('image');

				?>
				<img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt'] ?>" />

			<?php elseif(get_row_layout() == 'video_slide' ): ?>

				<?php the_sub_field('iframe'); ?>

			<?php endif; ?>

		</li>

	<?php endwhile; ?>

	</ul>

<?php endif; ?>

Nested loop

This example shows a repeater field (locations) which holds some basic title and description data along with another repeater field (staff_members) containing the staff members.

The have_rows function will detect a change in $field_name and instantiate a new loop!

<?php // test loop #1 ?>
<?php if( have_rows('locations') ): ?>

	<div class="locations">

	<?php // start loop #1 ?>
	<?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 // test loop #2 (nested) ?>
			<?php if( have_rows('staff_members') ): ?>

				<ul class="staff-members">

					<?php // start loop #2 (nested) ?>
					<?php while( have_rows('staff_members') ): the_row();

						$image = get_sub_field('image');

						?>
						<li>
							<img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt'] ?>" />
							<h4><?php the_sub_field('name'); ?></h4>
						</li>

					<?php endwhile; ?>
					<?php // end loop #2 (nested) ?>

				</ul>

			<?php endif; ?>
			<?php // end test #2 (nested) ?>

		</div>

	<?php endwhile; ?>
	<?php // end loop #1 ?>

	</div>

<?php endif; ?>
<?php // end test #1 ?>

Notes

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 the_row function also returns the row data as an array if you wish to store it as a variable and use it.

Related