This article introduces one of the most important topics in WordPress development: the WordPress loop, or more commonly simply “the loop.” If you’re interested in under more of the key concepts of developing WordPress themes, check out our free course on getting started with WordPress themes.
This content is great, because it’s not just one of our normal articles: It’s a sample chapter from our “learn WordPress development” guide Up and Running, now in its revised and expanded 3rd Edition.
If you like this chapter, check out Up and Running. There’s about 40 more chapters where this one came from. It’s the best guide to WordPress development out there.
The Best Way to Learn WordPress Development
Get Up and Running Today!

Up and Running is our complete "learn WordPress development" course. Now in its updated and expanded Third Edition, it's helped hundreds of happy buyers learn WordPress development the fast, smart, and thorough way.
Here's what one of them had to say:
"I think anyone interested in learning WordPress development NEEDS this course. Watching the videos was like a bunch of lights being turned on." -Jason, WordPress developer
Key Takeaways:
- The Loop is an extremely important topic in WordPress theme development: it is how WordPress renders a bundle of posts fetched from the database into an HTML webpage.
- The Loop is a PHP
while
-loop that runs once per fetched post. Inside it, theme developers set repeated rules for how each post should display, primarily using WordPress’s template tags. - The Loop should exist in every theme file that is part of the WordPress template hierarchy. Customizing this Loop is a major way in which themes create different views and layouts for webpages that display different kinds of posts (for example, Posts and Pages).
The Loop is perhaps the key concept of WordPress theme development, so you’ll definitely want to wrap your head around it. Fortunately, it’s not that complicated! 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.
WordPress’s Loop Exists in the PHP Template Files
As we covered in the last chapter, a theme is made up, first and foremost, of its PHP template files. The WordPress template hierarchy dictates which webpages (and post bundles) to associate with which template files: for example, 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 in WordPress
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.
The WordPress Loop is how WordPress processes any bundle of fetched posts.
Inside The Loop, you specify how you want each post in the fetched bundle to be laid out. WordPress will “loop through” the bundle, and reuse the specified 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 the site’s “About” page—WordPress will still use the core concept of The Loop to display the (single) post on the webpage.
WordPress’s 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 inside home.php
‘s Loop. (We cover template tags later, in The Magic of the_()
and get_the_()
Post Template Tags—they’re cool!)
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()
.
Being able to dictate these differences is a lot of what WordPress theme development is all about.
An Example of a WordPress 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.

MARKDOWN_HASH6ce624532346493b7a0d1a63ecfc68ceMARKDOWN_HASH
.So that’s a Loop in the wild. Now let’s leave Twenty Fifteen alone and talk about the general anatomy of a Loop in any theme.
The Minimal Version of The 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 “punctuating” PHP, and they mean the same thing. We prefer the second way of writing it, so we’ll be sticking with that one through the rest of the chapter.
How The Loop Works in WordPress
The Loop really is a loop, in the programming sense.
In this section, we’ll offer a line-by-line explanation of 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() ) :
Since we’ve passed inside the initial if
-statement, we know 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.
In English, 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 now inside the 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 in the rest of this chapter.
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 while
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 a 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_excerpt(); ?>
</article>
<?php endwhile;
endif;
What This Loop Outputs for WordPress Themes
For each post in the bundle, this Loop first creates an HTML <article>
tag. Inside that, it displays first the title, and then a short excerpt—by default, the first 55 words followed by […]
—of the current post.
So taking some Posts from the blog of our site Press Up as examples, the Loop above outputs:
<article class="full-article">
<h2>What Your Minimum Viable Product Should Be Measuring</h2>
<p>In our last article we introduced you to the idea of the Minimum Viable Product (MVP), and covered some of the internal challenges that often arise when you prepare to share a beta version of your idea. An MVP isn't just a quick, cheap version of your product that you're releasing because it's easy. On […]</p>
</article>
<article class="full-article">
<h2>Starting Small: Creating a Minimum Viable Product</h2>
<p>A common mistake entrepreneurs make is to start with a very specific idea and grind as hard as possible to make it work. This might work out great—but as many entrepreneurs learn, it's far too easy to rush through, or entirely overlook, the process of refining our initial ideas into something people truly want. Not […]</p>
</article>
<article class="full-article">
<h2>How to Plan a Successful Web Project</h2>
<p>It's too easy to plan out a web project in terms of technologies rather than solutions. Too many web projects don't meet their goals. The project could be the wrong solution for the right goal, the right solution for the wrong goal—or, perhaps worst of all, a shiny solution for no goal. The problem is […]</p>
</article>
// (And so on for many more articles)
Patterns to Notice about The Loop
A couple of things to notice in this Loop example:
- 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_excerpt()
, which prints out the beginning of the post’s content. We cover template tags in detail in The Magic ofthe_()
andget_the_()
Post Template Tags.
If you made a theme whose only template hierarchy file was index.php
, and pasted the above Loop into that index.php
file, it would work. Your site’s homepage would display all the titles and excerpts of your most recent Posts, your site’s “About” page would display the title and excerpt of that Page’s copy, and so on.
You’re Now WordPress-Loop-Literate
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.
Again, you’ll learn more about programming the innards of The Loop with template tags like the_content()
in The Magic of the_()
and get_the_()
Post Template Tags. For now, though, you’re Loop-literate, and that’s a great thing! This is one of the most important parts of WordPress theme development.

Summary Limerick
The Loop is a loop that runs while
There are still unworked posts in the pile.
Each post, and its sequels,
Are marked-up as equals
To form the HTML file.
Quiz Time!
- The Loop is present in:
- Files in the template hierarchy like
single.php
andpage.php
functions.php
- “Always-used” WordPress templates like
header.php
andfooter.php
- Files in the template hierarchy like
- The Loop typically does not contain:
- A PHP
for
loop - A PHP
while
loop - A PHP
if
-statement
- A PHP
- The WordPress Loop runs:
- Once
- Once per fetched post
- Once per post in the database
Answers and Explanations
A.
The files in the WordPress template hierarchy should always include The Loop; other theme files generally don’t.A.
Nofor( ) {}
logic is used in a regular version of The Loop.B.
The Loopwhile
s through each post that has been fetched to build the current page—not once for each post in the whole database. That’d be crazy: a WordPress site can have hundreds or even thousands of posts in its database, and building a page often requires fetching only one of those posts, or a handful.
Jim,
I know your comment is old, did you ever fix your issue? I went through a couple pages on your pagination and didn’t see any duplicates. I like the design/layout of your site. If you still need help, let me know, gratis of course.
Chris
That’s a short and sweet introduction to WordPress’s loop. Every WordPress theme designer and developer needs to understand this concept.
Great post David.
Hi, David
this is great post. Very informative, I’ve enjoyed reading it. However, I have a question. Do we really need if statement here?
if ( have_posts() ) :
while ( have_posts() ) :
I would think that only while would be enough? If there are no posts, then have_posts() will return false, and while will complete immediately. Is this correct?
I’m not sure if I can format code here, so I’ve just used plain font :-).
If there are no posts you will display something else (front-page, other page) so the user wont get an error. Therefore you need the if (+ else) statement.
Great work David.
Fantastic post keep posting the post like this in future.