The Loop is the basis of dynamic content in WordPress. Joe Casabona explains what it does, how to use it, and resolves the most common Loop-related queries.
- Knowledge needed: Intermediate PHP, Basic CSS, Basic WordPress
- Requires: WordPress
- Project Time: 1-2 hours
As a WordPress developer, there are quite a few things you need to understand. Things like themes and plug-ins, actions and filters, tags and more. But none of these are more important than the world-famous WordPress Loop.
Oh, The Loop. It's a living, breathing thing. It's the backbone of WordPress – the part that makes everything tick. Without The Loop, there would be no dynamic content (very little, anyway). Using The Loop, we can print any content, in any format we want. And who better to describe it than its creators? Here's what the WordPress Codex has to say about it:
The Loop is used by WordPress to display each of your posts. Using the Loop, WordPress processes each of the posts to be displayed on the current page and formats them according to how they match specified criteria within the Loop tags. Any HTML or PHP code placed in the Loop will be repeated on each post.
Essentially, WordPress has a set of tags to: (a) make sure that we have posts to display, and (b) display those posts. The tags, called Template Tags, enable us to fully customise how we display the information from each post.
01. Getting started
We start off The Loop this way:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
Three things are happening here:
- have_posts() is making sure there are posts to display.
- The same function will continually keep track of if we still have posts, which is why it's used as the while condition.
- the_post() unpacks the next post in the queue.
WordPress automatically grabs the posts by querying the database based on the URL. You could also overwrite the original query by using WP_Query() or query_posts() to get your own information. In any case, as long as that query returns posts, have_posts() returns true and we enter The Loop. We end The Loop in this way:
<?php endwhile; else: ?>
<?php _e(‘No posts were found. Sorry!'); ?>
<?php endif; ?>
We have a simple fallback here: in the case that have_posts() returns false, it tells the user we have no posts for them. Inside The Loop, we can do all kinds of things to completely customise the post display. While I won't go through all of the Template Tags, I will point out some of the most commonly used ones. All of the following functions print out their value by default. Some of these functions also accept Boolean values, which determine if the value should be printed or returned.
- the_title(): Gets the title of the post or page. It accepts three arguments: an HTML tag for before the title (named $before), an HTML tag for after the title (named $after), and $echo, the actual title itself.
- the_time(): Gets the date the post or page was published. The only argument it accepts is the format in which the date should be printed. These arguments are the same ones that the PHP date function accepts. The default whatever is listed in the WordPress admin panel, under Settings > General.
- the_content(): This will display the content of the post or page (that is, whatever you entered as the body text in the visual editor of the WordPress admin. It accepts two arguments, the first of which tells WordPress what to display as the 'more' text. I'll talk about this at length in the next section. The second argument, called $stripteaser, is simply documented as a Boolean that will "strip teaser content before the 'more' text". There are no examples on the Codex, and there is some debate over what it actually does.
- the_excerpt(): Gets the first 55 words of the post, appending [...] to the end of the string. It accepts no arguments. Both the number of words and the ellipsis can be changed within the functions file using filters.
- the_category(): Gets the category (or categories) in which the posts are listed. For arguments, it accepts the separator, which will be printed in between categories; how to handle displaying parent categories; and the post_id, which of course defaults to the current post.
- the_tags(): Gets the tags added to the post. The arguments it accepts are what to print before the list of tags, how to separate each tag, and what to print after each tag.
- the_permalink(): Gets the post's or page's URL in the format defined by the WordPress admin panel in Settings > Permalinks.
- the_author(): This displays the post author's name. You could also use the_author_link(), which would display the author's name with a link to his or her other posts. If you do use the latter, I'd recommend you make at least an author.php page to display the posts nicely!
It's also worth noting that most of these functions have accompanying 'get' functions – that is, get_the_title() – which would simply return the the value instead of printing it. You can see all of the Template Tags and whether they belong inside or outside The Loop here.
Now, I know what you're thinking: that one burning question you have...
02. Where can I use The Loop?
And it's a very good question. While theoretically you can use The Loop anywhere, there are several places where it is commonly used. The first place, and probably the most obvious, is in index.php. Since the index page is by default your blog's homepage template, The Loop is used to display the most recent blog posts. The other common templates you'll see The Loop in are single.php and page.php.
However, the beauty of WordPress is that you can overwrite just about any default functionality. That means if you want to have a custom display for a specific category, you can create a category-$id.php template (where $id is the ID of the category; slug can also be used) and throw The Loop on that page to gain a custom template for just that category. If you don't have any of the other templates, index.php will be used. The WordPress Codex actually has a very nice chart showing the drill-down of theme templates, all of which are common places for using The Loop, which you can view here.
Of course, you don't need to use it on one of these standard templates. You can use The Loop anywhere you want, as long as you have the proper hooks – just wp_head(); – in place. If you want to do something like display the thumbnail of the most recent post in the sidebar, you can do that too. I'm going to show you how to display a 'breaking news' title and link to story in your header.
Since everyone's template is different, I'll let you handle placement. Just open up your header.php file and place this code where you'd like:
if ( have_posts() ) : while ( have_posts() ) : the_post();
<h3>BREAKING: <a href="<?php the_permalink();?>"><?php the_title(); ></a></h3>
<?php endwhile; endif; wp_reset_query(); ?>
There are a few things here to note. First of all, we're using the built-in function query_posts() to get posts other than those that would normally show up on the page. According to our query, we want one post (the most recent one) from the category 'breaking-news', which is the slug of a category I set up for this demonstration. You can use any category slug you'd like: just remember that if you want to call a category by slug, you need category_name in the query string. (Just using category requires the category's ID.) You can ready more about query_posts() here.
One thing to keep in mind is that query_posts() modifies the main Loop. I'll show you how to fix that, and later on, I'll tell you about other functions you could use that will not modify the main Loop.
After we get the posts we want, we start off The Loop, as discussed earlier:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
We then call two template tags, the_permalink() and the_title(), wrapping them in a div with a class I created called .breaking. Our Loop ends the usual way with endwhile; endif;
However, I included one more function: wp_reset_query(). You can read about it here.
It is imperative you call this function right after the end of the custom Loop because it will reset the query, grabbing the information that should be on the page. For example, if a user goes to the 'About' page, wp_reset_query() will grab that page's information, which was overwritten by the query_posts() call we just made. Without it, any subsequent loops will not display properly; and since this code is in the header, any loops for that page's template will be rendered useless. In short, wp_reset_query() is pretty important.
This is the result:
03. Can I use more than one Loop in a template?
Another great question! The short answer is yes, most definitely. You've probably seen this in action on sites like CNN, National Geographic and Forbes, all of which make use of multiple Loops on their homepage (or at least, it looks that way). As a matter of fact, in our last example, we were using more than one Loop for a template, even if the two Loops were in different files. Just be aware that when you are using several Loops, you need to be mindful of where and how you are using them, as well as the scope of your template tags.
04. Querying posts
Earlier, I mentioned that there are several ways to generate a list of posts to display in your theme. The first (and main) way is to use the function query_ posts(), which we used in our previous example. It is the primary method because this is how WordPress generates the original post or page information when you go to a section of a WordPress site. Consequently, when you use query_posts(), it will alter the main Loop information.
That means if we do something like this...
<?php the_title(); ?>
<?php query_post($someArguments); ?>
<?php the_title(); ?>
...we will get two different titles. Because of this, we want to be mindful of using query_posts(), especially when we’re generating several different Loops in a single template. A better option might be get_posts(), which allows us to generate multiple Loops in a single template without changing the page's main query. (You can find more information here.) The only difference is that we’ll have to set up our Loop a little differently.
Here is some sample code:
$custom_posts= get_posts(array('numberposts' => 4, 'category'
=> 3, orderby => 'title'));
foreach ($custom_posts as $custom_post) : setup_postdata($custom_post); ?>
<h3><?php the_title(); ?></h3>
<?php the_excerpt(); ?>
<?php endforeach; ?>
There are a couple of things to be aware of here. The first is obviously that this isn’t the normal Loop setup we’ve been writing. That’s because this line:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
...is reserved for whatever is retrieved from query_posts(), which is usually the default information for the page. Instead, get_posts() will return an array of posts that we store in our own variable, which we’ll traverse using a foreach loop.
To use the regular template tags that we now know and love, we call the function setup_postdata(), passing to it the current post information (which is now in the variable $custom_post). Then we proceed as normal, using all of the regular template tags.
There is also WP_Query, which is the class used to query posts, create the Loop, and more. While it’s worth mentioning here and checking out on The Codex, I won’t go into too much detail, since we already have two ways to get post information, which will be fine nine times out of ten. The WP_Query Codex page has all of the parameters you can pass in an query string for posts, whether you're using WP_Query, query_posts() or get_posts().
And that's it for this article. Phew! We've covered quite a lot of ground here, and it might seem a bit overwhelming if you're just getting started, but persevere, and soon you will be working productively with WordPress' bread and butter: The Loop!
You can learn more about The Loop and building WordPress themes, plug-ins and custom post types in my new book, Building WordPress Themes from Scratch.
Joe Casabona is a web developer, teacher and author of the book Building WordPress Themes from Scratch. He absolutely loves WordPress and is unapologetically nerdy!