We recently released Up and Running, our multimedia guide to WordPress development. We think it’s the best way to learn the technical side of WordPress: we don’t skip steps, and we make learning each subject as simple and intuitive as possible. If that sounds good to you, check it out!
This week, we’re presenting a crucial chapter from Up and Running, on WordPress’s posts-processing engine: The Loop.
The Loop is maybe the key concept of WordPress theming, so you’ll definitely want to wrap your head around it. Fortunately, it’s not that complicted! Our goal here is to make the concept clear first, and then to move on and show you how the code works.
The Loop in Plain English
In this section, no programming. We’ll just go over basic concepts.
The Loop Exists in WordPress PHP Template Files
A theme is made up, first and foremost, of its PHP template files. The WordPress template hierarchy tells which webpages (and post bundles) to associate with which template files: page.php
for a request that pulls a site’s “About” page, home.php
for a request that pulls the site’s blog index page, and index.php
as a universal fallback if something higher up in the hierarchy isn’t triggered.
Once we know which template file we’re working with, it’s time to get into the guts of the file itself, and that’s where we’ll find The Loop.
The Loop is What Processes Posts
You specify formatting inside The Loop, and WordPress applies that formatting to every post in the fetched bundle—which is why it’s called The Loop.
WordPress is a factory for taking your stored posts—the “Posts,” “Pages,” and other post types you create inside the WordPress admin area—and processing those posts into webpages to display to the world.
The WordPress Loop is the way WordPress processes those posts. Inside The Loop, you specify how you want each post in the fetched bundle to be laid out. WordPress will reuse that format for every post in the bundle—which is why it’s called The Loop.
So The Loop is most obvious on, for example, your blog index page, where WordPress cycles through lots of blog posts, reusing the format we’ve specified for each one.
However! If there’s only one post on the webpage—when someone requests, say, a single blog post or a site’s “About” page—WordPress will still use the core concept of The Loop to display the (single) post on the webpage.
The Loop is the Customizable Heart of Template Files
Changing Loop contents is a primary way to make your template files behave differently.
The Loop is the engine of any template file, and it’s highly customizable; it varies file-by-file. Changing Loop contents is a primary way to make your template files behave differently.
For example, you might want to make your blog index page (controlled by your theme’s home.php
) show only one-paragraph excerpts of your blog posts, instead of the whole content. To do this, you’ll use the the_excerpt()
template tag in the Loop inside home.php
.
At the same time, you still want the webpages for your individual blog posts (controlled by single.php
) to display the entire article contents, not just an excerpt. So inside the single.php
Loop, you’ll use the the_content()
template tag instead of the_excerpt()
.
An Example Loop
Some template files are very little but The Loop.
Below you’ll see the single.php
file for WordPress’s popular Twenty Fifteen theme. The Loop is on lines 15 to 43. We won’t scare you yet with what’s inside The Loop itself (so lines 18 to 39 are hidden)—but notice that single.php
isn’t much but The Loop! In other words, The Loop is doing almost all the work that makes this template file display its contents.

single.php
.The Minimal Loop
Here we’ll look at the bare-bones PHP code that makes up The Loop. This code can be written two ways, and both do exactly the same thing. Either:
<?php
/* Environment: We're inside a theme template file in the WordPress template hierarchy */
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// (Loop contents will go here)
} // end while
} // end if
Or…
<?php
/* Environment: We're inside a theme template file in the WordPress template hierarchy */
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
// (Loop contents will go here)
endwhile;
endif;
Don’t get too hung up on there being two ways to write The Loop—they’re just two ways of saying the same thing in PHP. They’re just “punctuated” differently.
We prefer the second way of writing it, so we’ll be sticking with that one through the rest of this article.
How The Loop Works
The Loop really is a loop, in the programming sense.
In this section, we’ll be analyzing, line-by-line, the second Loop example above (the one with the endwhile
in it).
The first thing to notice is that The Loop really is a loop, in the programming sense. In other words, it iterates (loops) over a set of WordPress posts—and doesn’t stop until it runs out of posts. Here’s how that works, line-by-line:
if ( have_posts() ) :
The Loop first asks of the broader WordPress environment, “Have any posts been fetched for me to process?” It asks this using a WordPress function called have_posts()
; that function return
s (gives back) either true
, if there are posts to process, or false
, if there aren’t.
If the answer we get back from have_posts()
is true
, then what’s inside the if
-statement—which is The Loop itself—will operate. If not, then our PHP engine skips right over The Loop, because there’s nothing to loop through!
while ( have_posts() ) :
On the last line, we learned that we do indeed have posts to loop through. So this line is where The Loop’s actual loop starts. It’s a PHP while
loop: something that keeps iterating as long as (“while”) a condition is true.
This line says “While we still have posts to process: ” In other words, this loop will execute the code inside it once per post, while
there are still posts to act on. When there are no more posts, The Loop will stop, and the page will move on to the next thing in this PHP template.
the_post();
Remember, we’re still inside the “While we’ve got a post to work on: ” while
loop described above. This line says, “Since we’ve got a post to work on, let’s begin by queueing up the current post.”
the_post()
is what does the “queueing up”—it basically sets up the next fetched post object to be worked on by the WordPress processes available to us within The Loop. The Loop requires this function, but we don’t have to know too much more about it than this.
// (Post content will go here)
This section is the main contents of The Loop. It’s where we’ll get to be creative—where we’ll actually write code to work with each fetched post, one by one. Since it’s the section that we’ll write ourselves, it’s currently empty except for a placeholder PHP comment. We’ll explore this section further below.
endwhile;
This is PHP’s way of saying: “We’re done with the while
loop we were in.” Anything between while () :
and endwhile;
is inside that loop; anything after is outside it, and will only be run once the loop itself is finished.
endif;
This is PHP’s way of saying: “We’re done with the if
-statement we were in.” Anything between if () :
and endif;
only executes if the if
-statement is true; anything after it isn’t affected by the if
-statement itself.
An Example of The Loop in Action
Now that we understand the basic “skeleton” syntax of The Loop, here’s a very simple Loop that actually does something:
<?php
/* Environment: We're inside a theme template file in the WordPress template hierarchy */
if ( have_posts() ) :
while ( have_posts() ) :
the_post(); ?>
<article class="full-article">
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</article>
<?php endwhile;
endif;
What This Loop Outputs
For each post in the bundle, this Loop first creates an HTML <article>
tag. Inside that, it displays first the title, and then the full content, of the current post.
So taking some recent posts from our site Press Up as examples, the Loop above outputs:
<article class="full-article">
<h2>Why Software Becomes a Big Ball of Mud</h2>
<p>"Big ball of mud" is one of the more common pejoratives thrown at "legacy" code. Systems suffering from a wide variety of [and the rest of the post content]
</article>
<article class="full-article">
<h2>How Not to Talk to Nontechnical People</h2>
<p>Software engineers and other technical people often struggle to be understood by people who don't share their technical knowledge. Their frustration is [and the rest of the post content]
</article>
<article class="full-article">
<h2>Ternary Operators Considered Harmful</h2>
<p>Conditionals are, if we're honest, an embarrassingly large part of most programs deployed in the world. I say "embarrassingly" because [and the rest of the post content]
</article>
(Just so we’re clear: [and the rest of the post content]
is just a placeholder we made for the example above. This Loop, in action, really would spit out all 1,000 or more words of each post in the bundle.)
How It Works
A couple of things to notice:
- Notice how we move in between plain HTML and PHP. Remember, anything not inside
<?php ?>
is pure HTML: in our case, that’s the<h2>
and<article>
tags. Those get printed out directly to the webpage every time The Loop iterates over a new post. - The real meat here—and where we’re getting deep into the magic of WordPress—is the two PHP template tags we’re using:
the_title()
, which, when used inside The Loop, prints out the current post’s title; andthe_content()
, which prints out the current post’s content.
If you plunked this Loop inside your theme’s index.php
file, your site’s homepage would display, by default, all the titles and contents of your most recent Posts.
And That’s The Loop
We hope that this explanation of The Loop makes its core principles clear. Most real themes’ Loops will be more complicated—but this is a real start. You’re now Loop-literate!