7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Code
  2. WordPress

Mastering WP_Query: Using the Loop

Read Time: 9 mins
This post is part of a series called Mastering WP_Query.
Mastering WP_Query: An Introduction
Mastering WP_Query: Related Functions

As I outlined in the introduction to this series, the WP_Query class has four main elements:

  • the arguments for the query, using parameters which will be covered in detail in this series
  • the query itself
  • the loop, which will output post content, titles or whatever you want to display
  • finishing off: closing if and while tags and resetting post data

In this tutorial I'll show you how to use the loop with WP_Query, including the two main ways to structure your loop and how to use multiple loops.

Where the Loop Fits

Without a loop, nothing will be displayed on your page. After WordPress has run the query using the arguments you've defined, it then needs to be told what to output from the data that it's fetched. This is where the loop comes in.

So the loop comes after your query, and it uses three tags:

  • if( $query->have_posts() ) checks if there are any posts. It does so by checking that the value of the post_count property for our query is less than the value of current_post + 1.
  • while( $query->have_posts() ) repeats the loop for each post as long as there are posts to retrieve. As you can see, this have_posts() method is the same one that we called earlier to check if there are any posts. Keep in mind that this method does not increment the post counter. It simply lets us know if there are any posts in the loop or if we are at the end of the loop. It will also automatically rewind the loop once we reach the end.
  • $query->the_post() accesses that specific post. It does a few other things like retrieve the next post where it increases the post counter. It also sets up global post data for us to use.

You should not call the have_posts() method while you are inside the loop. This is because have_posts() will rewind the loop back to the beginning and you will be stuck in an infinite loop.

Now, this is where the loop fits in the WP_Query class:

After running the loop, all that's left to do is tidy things up using wp_reset_postdata().

Structure of the Loop

The way your loop is structured will depend on what data you want to display from your post. Here's an example loop which outputs the post title, the featured image, and an excerpt. You'd use a loop like this on an archive page.

This loop displays exactly what I've described above: the featured image, title, and excerpt.

Taking the Loop Further: Checking for Content

But sometimes you might want to add a heading before your list of posts, or you might want to enclose them all in a containing element. If you simply added this before your loop, it would be output regardless of whether the query actually returned any data, meaning you could have a heading with nothing beneath it, or some unnecessary markup.

This is very easy to get around by putting the enclosing element or the heading inside your if tag:

Here you can see I've checked if there are any posts retrieved by my query, and if there are I've opened a containing element and added a heading.

This is also useful if you want to output the results of your query as a list. Let's say I want to create a list of all posts in a given category. The ul element isn't inside my loop as it doesn't relate to one specific post, but I only want to output it if there are posts. So I use this:

This checks if the query has fetched any posts, and if so, it opens the ul element and then runs the loop.

Running Extra Loops

It's important to be aware that while you can use WP_Query to run more than one loop, you have to reset the post data and start a second instance of WP_Query to do this. This is because each of your loops will be outputting data based on different arguments.

This example displays the excerpt and featured image for the first post and then just the title of each subsequent post:

I've used two key arguments here:

  • 'posts_per_page' => '1', used with the first query, outputs just the most recent post.
  • 'offset' = '1', used with the second query, skips the first post, ensuring it's not repeated in the list below.

As you can see from the code above, the loop is slightly different for each query. The first one outputs the featured image, title, and excerpt, while the second checks if the query has posts and, if so, opens a ul element and encloses each post title in a li element and a link to its page.

You'll also notice that I used wp_reset_postdata() after both loops. If I hadn't done this, using template tags outside our secondary loops would have given me data about the last post within the loops. Calling this function resets the post data to the main query.

Accessing Post Information Inside the Loop

There are a lot of functions that you can call inside the loop in order to access information about the current post. You have seen some of them being used in this tutorial as well. In this section, I will give you a list of some common functions that you will probably use every now and then.

Get the Title

There are three functions that you can use to get the title of the post. These are the_title(), get_the_title(), and the_title_attribute(). The get_the_title() function simply retrieves the post title, while the_title() will either display or retrieve the title along with optional markup based on the passed arguments. You should use the_title_attribute() when you want to sanitize the title before displaying it.

Get the Excerpt or Full Content

There is a dedicated function called the_excerpt() to display the excerpt of the current post. It applies several filters to the provided excerpt so that it can be displayed properly to viewers. Not every post will have an excerpt provided by the author. In such cases, it will generate a trimmed-down version of the full post excerpt before displaying it.

You can display the full content of the post by using the function the_content().

Get Post Categories, Tags, and Other Metadata

Your WordPress posts will usually have some tags or categories assigned to them by you. You can display a list of those tags and categories within the loop by using the_tags() and the_category() functions. Use the the_author() function to display the author of the post. The ID of the post is also accessible with the function the_ID().

Get Publication or Modification Date and Time

There are dedicated functions in WordPress that you can use within the loop to display the publication date (the_date()) and time (the_time()) of a post. Two important points that you should keep in mind are that the_time() can also be used to just display the publication date of a post. Also, the output of the_date() is echoed only once for multiple posts that were published on the same day. This basically means that you will almost always want to use the_time() for greater flexibility and ease of use.


Without a loop, WP_Query doesn't really do very much. The loop is the code you use to display the data that WordPress has fetched from the database based on your query arguments.

As I've demonstrated, there are a few variations on the loop. A simple loop will just output all posts in the order you've specified in your query arguments (or by date in descending order by default). If you separate if( $query->have_posts() ) and while( $query->have_posts() ), you can insert additional markup outside your loop, but only if your query has returned data. And finally, by specifying alternative arguments and using wp_reset_postdata() after each loop, you can use WP_Query more than once to create multiple loops on your page.

This post has been updated with contributions from Nitish Kumar. Nitish is a web developer with experience in creating eCommerce websites on various platforms. He spends his free time working on personal projects that make his everyday life easier or taking long evening walks with friends.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Scroll to top
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.