One of the most basic (and yet powerful) features inside WordPress is The Loop, this small piece of code that we use over and over again. And yet, I find people who called themselves a WordPress expert and don’t know what it is, that’s… sad.

Recently the company I work on bought another company overseas, and they asked me to interview a few people to make sure they know a bit about WordPress, PHP, Frontend and so on. My first interview went quite well, until I asked “How do we start The Loop in WordPress?”, the answer shocked me. He didn’t know what the loop even was.

The Loop is a feature pretty easy to understand, so I decided to write a little bit about it.

What is a loop?

If you are a programmer, you surely know what a loop is, and if not… Really?

When we are writing code, sometimes we need some block of code to be used more than once, we could just write the same code over and over again but that’s just a waste of time, in those cases we use a loop, so basically, a loop only repeats stuff. For example, if we want to display the numbers from one to ten, we could do this:

echo "1\n";
echo "2\n";
echo "3\n";
echo "4\n";
echo "5\n";
echo "6\n";
echo "7\n";
echo "8\n";
echo "9\n";
echo "10\n";

Just so you know, I wrote all that, and it was tiring… Instead, I should have just done this:

for ( $number = 1; $number <= 10; $number++ ) {
    echo $number . "\n";

So much easier. BTW I used a for loop, there are several types of loops. WordPress, for instance, uses a whileloop.

What is “The Loop”?

Now we know what a loop is, but what makes WordPress’ loop so special that it makes it the loop? Well, without The Loop, WordPress wouldn’t show us what we want to see, that being our posts.

The Loop performs a ton of actions under the hood so that we only worry about how to display our posts, and not about how to retrieve our posts. A very basic loop (taken from Twentythirteen) looks like this:

<?php if ( have_posts() ) : ?>
    <?php /* The loop */ ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>
    <?php endwhile; ?>
    <?php twentythirteen_paging_nav(); ?>
<?php else : ?>
    <?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>

Let’s keep in mind that when we access any page in WordPress, there’s a global query taking place, that means WordPress already knows which page we are visiting and there’s already a $wp_query object with all the information we need, now let’s see what the loop does.

  • if ( have_posts() ): First of all, this functions checks the $wp_query object and returns true if the object has posts in it.
  • while ( have_posts() ): Now, this is the real start of the loop, as long as have_posts() is true, let’s run the rest of the code inside.
  • the_post(): Now that we are inside the loop, we need to populate our $post object, this function also fires setup_postdata() which checks for things like the number of pages inside the post.
  • get_template_part( 'content', get_post_format() ): Now, we have our $post object complete, it’s time to show it to the world, we could just insert the markup and functions like the_title() and the_content() right here, but it’s a good practice to keep things clean by including a template (I plan on talking about get_template_part in another post).
  • endwhile: We already included the template to display the posts, so we can just end the loop, remember, as long as there are posts in the query, the loop will be in action.
  • twentythirteen_paging_nav(): This function is specific to this theme, basically it just displays navigation links in case there’s more posts in the page.
  • else: If the query was empty, or if have_posts returned false, then we should let the user know by including a special template for these embarrassing situations.
  • endif: Finish the if statement, completely finish the loop

Using The Loop with custom queries

Usually we use The Loop along with the main query, or the $wp_query object, but what happens if by any reason we need to use a custom query?

We could modify the query by using query_posts, but I don’t recommend it because it in fact modifies the main query, and it usually brings more problems than solutions, the real solution is to just create a new query.

The get_posts method

The function get_posts is a way to create small custom loops, it accepts all the parameters of WP_Query and returns an array with the result, that way we can use a foreach loop to work with the posts:

$posts = get_posts( $args );
foreach ( $posts as $post ) :
    setup_postdata( $post );
    <h2><?php the_title(); ?></h2>
    <?php the_content(); ?>

Notice how we need to fire setup_postdata manually? That is because we don’t use the_post in this loop.

The “new query” method

In my personal experience, I have had issues when using get_posts in bigger loops, that is why in those cases I prefer to use a new WP_Query. This creates a new query completely independent of the main query, and we can use the WordPress loop without any worries.

$my_query = new WP_Query( $args );
if ( $my_query->have_posts() ):
    while ( $my_query->have_posts() ) : $my_query->the_post();
        <h2><?php the_title(); ?></h2>
        <?php the_content(); ?>

As you can see, it’s pretty much the same loop as the one we use with the main query, the difference being the constant use of $my_query, this is necessary because the functions have_posts and the_post are actually aliases that point to the $wp_query object, so when we call have_posts we are actually calling $wp_query->have_posts, that’s why we need to specify that we are calling the function in our new $my_query object.

Outside The Loop

When reading tutorials and articles about WordPress, you often see the phrases “inside the loop” or “outside the loop”, what do these mean?

Inside the loop must be pretty obvious right now, everything between the while and endwhile, or foreachand endforeach tags is inside the loop, that means it uses either the main query, or a custom query, and that our $post object is available.

Outside the loop, however, is everything outside those tags, it does not use any query and the $post object is not available. How could that be useful?

Well, let’s say you have a custom sidebar in your posts, this sidebar must display a specific custom field called “mood” that belongs to the current post. But the sidebar is outside the loop, how can I access the post data?

Before, when I said that $post is not available, I meant is not automatically available, remember, when we access any page in WordPress, there’s a main query taking place. Even if we don’t have a loop in the sidebar, we do have a $wp_query and a $post object somewhere, we just need to call them.

    global $post;
    $mood = get_post_meta( $post->ID, 'mood', true );
<p>I'm feeling <?php echo $mood; ?></p>

Since $post is a global variable, that means it’s always available for us to use, we just need to know how to call it, just like an old partner.


As you can see, The Loop is pretty easy to understand, and incredibly useful. You can be sure that no matter what page of WordPress are you in, there’s always a loop in action. So I hope this small article helped you to understand a little more about our friend The Loop.

Further reading

Mario Aguiar

Soy un Front-End developer, conferencista, y a veces escritor. Actualmente trabajo para 10up. Vivo en la hermosa ciudad de Aguascalientes, México. Puedes seguirme en Twitter @emeaguiar.

leer más