A Comprehensive Beginners Guide to the WordPress Loop

Wordpress_blogheader

The WordPress Loop is the code used to display main content and excerpts of content on WordPress sites. Often times the loop is used to “loop” through and display a number of posts titles and excerpts like on a blog listing page.

A screenshot showing a number of blog posts being listed on the Treehouse blog

The loop is also the same code used to display the content and comments on a single post or main content on a single page such as the About page for a site.

The loop displaying a single page on the Smashing Magazine site

When sites use custom post types and custom fields, the loop is also used to display the data.

We can see that the WordPress Loop is quite versatile and used to display a range of content on WordPress sites. The code used to create the loop is at its core quite simple, however, it can be customized to a very great extent.

The Basic Logic Behind the Loop

The loop starts with code that checks to see if the current page is supposed to display a listing of multiple posts or a single post or page. If the page is supposed to list blog posts then it will list out a title and excerpt for each post (this can be customized to display featured images or other content). If the page is a single page or single post then the loop will just display the content for that page.

If no posts are available or someone accesses a page that does not exist, the loop has an option to display a custom message informing the visitor there are no posts or the page does not exist (similar to what a 404 page does except customized to specific types of content).

Thanks to WordPress templates, the loop can be customized for just about every page or type of content on your site.

There are also ways that you can use multiple loops on one page to display different types of content or format content in different ways. For example, you can have the latest blog post with a featured image display larger at the top of the site and then have older posts listed below with just a title and excerpt.

Two Simple Examples of the Loop Explained

Here is what a simple example of the loop looks like to display a listing of blog posts.

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

	<h2><?php the_title() ;?></h2>
	<?php the_post_thumbnail(); ?>
	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, no posts to list</p>

<?php endif; ?>

Lines 1, 7, and 11 are the basic logic that separate the code for when there are blog posts and no blog posts. Lines 3, 4, 5 do the actual work of displaying the title, featured image, and excerpt.

In line 1, the part of code that reads while ( have_posts() ) : the_post(); is what programs the process of repeating for as many times as there are posts.

Note: Using pagination on a site is a way of limiting the number of posts that are looped through on a page. After the loop reaches the default number of posts to display (set under Settings > Reading > Blog pages show at most) it will show how many more pages are available.

Example of Pagination from the Treehouse Blog

When you use the loop to display a single post or page instead of list multiple ones, interestingly the loop doesn’t change much.

Here is what a simple loop looks like for displaying a title and the main content for a page.

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

	<h1><?php the_title() ;?></h1>	
	<?php the_content(); ?>

<?php endwhile; else: ?>

	<p>Sorry, this page does not exist</p>

<?php endif; ?>

You’ll notice that the only things that really changed was the thumbnail and excerpt became the main content. The reason the same loop works for multiple posts and for single ones is because of the while statement while ( have_posts() ) : the_post(). Depending on what template the loop is used in and what page is accessed, the while statement will determine how many times to loop through the code.

What the Loop Can Display

There are a number of elements that the loop can display, such as the title, excerpt, main content. Below you can see a list of these common functions along with a short description and a link to more information about each function.

  • next_post_link – Displays a link to the post published chronologically after the current post
  • previous_post_link – Displays a link to the post published chronologically before the current post
  • the_category – Displays the category or categories associated to the post or page being viewed
  • the_author – Displays the author of the post or page
  • the_content – Displays the main content for a post or page
  • the_excerpt – Displays the first 55 words of a post’s main content then with a [...] or read more link that goes to the full post. The length of excerpts can be controlled by using this slightly advanced method or by using the Excerpt field on the post edit page.
  • the_ID – Displays the ID for the post or page
  • the_meta – Used to display custom fields
  • the_shortlink – Displays a link to the page or post using the url of the site using the ID of the post or page
  • the_tags – Displays the tag or tags associated with the post
  • the_title – Displays the title of the post or page
  • the_time – Displays the time or date for the post or page. This can be customized using the standard php date function formatting

The loop can also use conditional statements to display different content based on a number of factors.

  • is_home() – Returns true if the current page is the homepage
  • is_admin() – Returns true if admin is logged in and visiting the site
  • is_single() – Returns true if page is displaying a single post
  • is_page() – Returns true if page is displaying a single page
  • is_page_template() – Can tell you if page is using a specific template. i.e. is_page_template(‘about-page.php’)
  • is_category() – Returns true if page or post has a specified category. i.e. is_category(‘news’);
  • is_tag() – Returns true if page or post has a specified tag
  • is_author() – Returns true if a specific author is logged in and visiting the site. i.e. is_author(‘zgordon’)
  • is_search – Returns true if page is a search results page
  • is_404() – Returns true if page does not exist
  • has_excerpt() – Returns true if post or page has an excerpt

You can find a full list of all the WordPress Conditional Tags on the WordPress Codex.

Advanced Loop Example

Here is an example of an advanced loop using a number of the functions and conditional statements listed above. We won’t go into detail on every part of the loop since most of the elements are described in detail above.

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

<article id="post-<?php the_ID(); ?>" <?php if(is_category('featured')): ?>class="featured-post"<?php endif; ?>>
	<h1><?php the_title() ;?></h1>		

	<p>
		Published on <?php the_time('M j, Y'); ?> 
		by <?php the_category(', '); ?>
		in <?php the_category(', '); ?>
	</p>

	<?php the_content(); ?>

	<?php comment_form(); ?>

	<div class="prev-next-links">
		<ul>
			<li><?php next_post_link(); ?></li>
			<li><?php previous_post_link(); ?></li>
		</ul>

	</div>

</article>

<?php endwhile; else: ?>

	<p>Sorry, this post does not exist</p>

<?php endif; ?>

Multiple Loops

In some situations you may need to use multiple loops on one page. In order to do this you will have to use the rewind_posts() function before using a second, third or fourth time (you can do as many loops on a page that you want, but each loop will require another request to the database, which can begin to slow down the load time of your pages.

Here is what the rewind post function looks like in action for listing blog posts.

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

	<h1><?php the_title() ;?></h1>		

	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

<?php rewind_posts(); ?>

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

	<h1><?php the_title() ;?></h1>		

	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

Notice the rewind_posts() function on line 13.

The problem with this specific code is that each loop will output the exact same thing. In order to have the two loops display different things, we will have to give the loops some parameters telling each loop exactly what we want to display.

We can set parameters for loops using the query_posts() function. This function gives us a large number of parameters we can choose from to control what posts WordPress loops through. We’ll look at some of these in detail in the next section, so for now let’s just look at the code needed to display latest post in one format and then list the next three posts below it.

<?php query_posts('showposts=1&post_type=post'); ?>

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

	<h1><?php the_title() ;?></h1>		
	<?php the_post_thumbnail(); ?>
	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

<hr>

<?php rewind_posts(); ?>

<?php query_posts('showposts=3&offset=1&post_type=post'); ?>

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

	<h2><?php the_title() ;?></h2>		

	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

The magic here is happening on lines 1 and 19. Line 1 is telling WordPress to only display 1 post, which will automatically be the most recent one. On Line 19 we are telling WordPress to offset the posts by 1, which means it will not repeat the post output in the first loop. We are also limiting it to only displaying 3 posts.

The WP_Query Function

The function we used in the last section to set parameters for the is part of a very powerful WordPress function called WP_Query. This function can be used to make very specific WordPress loops based on a large number options.

The WP_Query function is placed before the loop. A nice aspect of this function is that all you have to do is place it before the loop and you don’t have to change anything about the loop itself.

Here are a few of the most common WP_Query options:

  • author – Filters loop by author id
  • author_name – Filters author by user_nicename
  • cat – Filters loop by category id
  • category_name – Filters loop by category slug
  • tag – Filters loop by tag slug
  • p – Filters loop by page or post id
  • name – Filters loop by post slug
  • pagename – Filters loop by page slug
  • page_id – Filters loop by page if
  • post_parent – Filters loop by id of parent page
  • post_type – Filters loop by post type, including custom post types
  • posts_per_page – Determines how many posts are looped through
  • offset – Determines how many posts to offset the loop by
  • order – Determines whether the posts display in ascending or descending order
  • orderby – Filters what factor the posts are sorted by. Default is date, but can be changed to things like title or author
  • year – Filters loop by posts in a given year
  • monthnum – Filters loop by a month numner. i.e. 1 = January
  • day – Filters loop by a specific day of the month

Usually all of the parameters are passed to the WP_Query function as an array.

Here is an example of using the WP_Query function to display the content for a specific page.

<?php 

	$args = array( 
		'pagename' => 'about-us'
	);
	$the_query = new WP_Query( $args );

?>

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

	<h1><?php the_title() ;?></h1>			
	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

For a more complex example, we can look at how to display all of the posts published by a specific author in a custom post type called workshops. We will also filter the loop so that it orders the posts by the title and only displays workshops published in the year 2012.

<?php 

	$args = array( 
		'author_name' => 'zgordon',
		'orderby' => 'title',
		'post_type' => 'workshops'
		'year' => 2012
	);
	$the_query = new WP_Query( $args );

?>

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

	<h1><?php the_title() ;?></h1>			
	<?php the_excerpt(); ?>

<?php endwhile; else: ?>

	<p>Sorry, there are no posts to display</p>

<?php endif; ?>

You can find out more about working with the WP_Query on the WordPress Codex.

Conclusion

You can’t build a dynamic WordPress site without using the WordPress loop. At it’s core the loop is very powerful. However it can also be greatly customized using a range of tags, conditionals and the WP_Query function.

If you have tips and tricks for working with the loop, please share with the community!

Free Workshops

Watch one of our expert, full-length teaching videos. Choose from either HTML, CSS or Wordpress.

Start learning

Zac Gordon

Zac is the WordPress teacher at Treehouse. Before coming to Treehouse, Zac taught web design and development at the high school and then college level. In addition to teaching web design, he owns a web design company and teaches Yoga.

Comments

5 comments on “A Comprehensive Beginners Guide to the WordPress Loop

  1. So useful. This has the clearest guide to using multiple loops from multiple custom post types I found anywhere online. Thank you thank you thank you!

  2. Hi Zac, I am trying to figure something out with a latest posts widget i have. It displays just the way I like but I would like to add a next/back button which shows further posts in one direction or the other without refreshing page but only the widget. My website is http://Muslimbodybuilding.com

  3. This article is so good…I had difficulty understanding the WordPress codex page, this makes it so easy to understand. Thanks Zac :)

  4. This is the first article I’v read on the WP Loop that was easy to understand and makes sense. Thanks.

  5. Hello, and thanks for this article.
    Do you know whether it is possible to query odd or even posts based on their IDs with wp_query function?
    Actually I want to get a cat page into two columns each containing half of the posts..