WordPress at Your Fingertips

The Loop in WordPress

The Loop in WordPress is processing posts one by one that are in the current global data and output information about each post. The Loop gets an array of objects (posts), goes through the array, and displays information about each post. The loop uses special functions created for it, for example: the_title(), the_permalink(), the_date(), etc.

When it says "The function must be inside a The Loop" it means that the function should be used inside the loop without having to pass parameters to it because the function is designed to be used inside The Loop.

For example, the_title() is called without parameters, but the function will output the title of the current post when it used inside The Loop. The data for the output is taken from the global $post variable.

Most of the Template Tags functions designed to be used inside The Loop.

Using the Loop

The Loop should be placed in the Theme's index.php and in any other Template file used to display post information, for example category.php, archive.php.

Standard Loop begins with such code:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

and ends with such code:

<?php endwhile; else : ?>
	<p><?php esc_html_e( 'Sorry, no posts found.' ); ?></p>
<?php endif; ?>

Or it could look like this (braces are used here):

<?php
// check if there is any posts in global data of the current page
if ( have_posts() ) {

	// start the looping
	while ( have_posts() ) {
		the_post();

		// Post Content here

	}

}
?>

Loop Examples

The loop in WordPress looks like this:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
	<!-- The WordPress Loop -->
	<p>Output the post data. The functions for the loop work here, e.g., the_title() </p>
	<h2><?php the_title() ?></h2>
<?php endwhile; else : ?>
	<p>No posts.</p>
<?php endif; ?>

Or you could write it like this:

<?php if ( have_posts() ) { while ( have_posts() ) { the_post(); ?>
	<!-- The WordPress Loop -->
	<!-- Output of posts: the_title() etc. -->
<?php } } else { ?>
	<p>No posts.</p>
<?php } ?>

You can also write it this way (the "No posts" part can be deleted in this case):

<?php while ( have_posts() ){ the_post(); ?>
	<!-- The WordPress Loop -->
	<!-- Output of posts: the_title() etc. -->
<?php } ?>

<?php if ( ! have_posts() ){ ?>
	<p>No posts.</p>
<?php } ?>

All information about the post is stored in the global $post variable. Suppose the loop handles an array containing the data of 10 posts, then the loop will have 10 iterations and the variable $post will be changed 10 times, and at each repetition from the $post variable will be read out information about the post and displayed through the template tags: the_title(), the_content(). Thus, any PHP/HTML code placed in a WordPress Loop will be repeated as long as the loop works: 10 loop iterations - 10 repetitions.

A typical example of a Loop is the output of posts on a category page, on a tag page, on the home page.

menu

Full loop example

Here's an example of a WordPress loop, with comments embedded in the code (inside < --!-->)

<!-- Checking for entries in the loop -->
<?php if ( have_posts() ) : ?>

	<!-- Loop Start -->
	<?php while ( have_posts() ) : the_post(); ?>
		<! -- The WordPress Loop -->
		<!-- The $post variable is already defined here -->
		<!-- it will be the basis for further code. -->
		<!-- $post will be changed for each post while( have_posts() ). -->
		<!-- template tags work based on $post variable: in_category('3'), the_permalink(), etc. -->

		<!-- Check if this post is in category 3. -->
		<!-- If yes, set CSS class div="post-cat-three". -->
		<!-- If not, then the class will be post class="post". -->
		<?php if ( in_category('3') ) { ?>
				  <div class="post-cat-three">
		<?php } else { ?>
				  <div class="post">
		<?php } ?>

		<!-- Display the post title as a link to the post itself. -->
		<h2><a href="<?php the_permalink() ?>" title="Link to: <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>

		<!-- Display the date of the post and a link to the author's other posts. -->
		<small><?php the_time('F jS, Y') ?> Author: <?php the_author_posts_link() ?></small>

		<!-- Display the text of the post in the div tag. -->
		<div class="entry">
		   <?php the_content(); ?>
		</div>

		<!-- Display the post categories, separated by commas. -->
		<p class="postmetadata">Located in <?php the_category(', '); ?></p>
		</div> <!-- close the main div tag -->

		<!-- From here the loop starts repeating if there are more posts -->
		<!-- Stop the loop (endwhile), -->
	<?php endwhile; ?>
	<!-- The complete end of the cycle. -->

<!-- If there are no entries in the loop, the loop will not work,
and the following block of code will be executed -->
<?php else: ?>

	<p>No posts in the loop.</p>

<?php endif; ?>
menu

Other Loop Variants

The examples of the loop above, where have_posts() is used, get the data for enumeration from the global $wp_query variable into which WP automatically adds data according to current page we are on now, for example, on the home page and on the category page, the data will be differ.

But, we can get the data and then process it in the loop ourselves.

Loop using get_posts():

<?php
global $post;

$myposts = get_posts( 'numberposts=5&offset=1&category=1' );

foreach( $myposts as $post ){
	setup_postdata( $post );
	?>
	<!--
	This is where the output of the posts is generated,
	where the template tags related to the loop work, e.g. the_title()
	-->
	<?php
}
wp_reset_postdata();
?>

A Loop using wp_query():

// Set the criteria we need to select data from the database
$query = new WP_Query( [
	'posts_per_page' => 5,
	'orderby'        => 'comment_count'
] );

// Loop
global $post;

if ( $query->have_posts() ) {
	while ( $query->have_posts() ) {
		$query->the_post();
		<?php the_title() ?>
	}
} else {
	// No posts found
}

// Reset global $post variable. Return original data
wp_reset_postdata();
menu

Why is it necessary to understand whether we are inside The Loop or not?

Distinguishing where the WordPress Loop is used and where the code is outside of the loop is necessary because WordPress has certain template tags that don't work outside of the loop, such as the_title(), the_content(), the_excerpt(), etc. For each such template tag to work, there must be defined a global $post variable, which is unknown outside the WordPress loop (or the variable $post can be known outside the Loop, but it may contain bad data).

Nested Loops

Nesting loops means that you are running a second loop before finishing the first one. This can be useful to display a post of the category of the post inside the loop:

if ( have_posts() ) {

	// start the looping
	while ( have_posts() ) {
		the_post();

		// nesting loop

		$my_query = new WP_Query( 'cat=3' );
		if ( $my_query->have_posts() ) {
			while ( $my_query->have_posts() ) {
				$my_query->the_post();
				the_content();
			}
		}
		wp_reset_postdata();

	}
}
No comments
    Log In