While back Brian Krogsgard had tweeted a variation of quite common question. How to best handle WordPress loop, when you need to output posts differently or otherwise split it?
https://twitter.com/Krogsgard/status/540954397422129154
His idea wasn’t wrong, but indicative as typical jump to more complicated solution than it needs be. Loops are used so much they are treated as ritualistic monolithic snippet of code. Which they are actually not.
What is loop looping?
So if there was a championship in WordPress copy/paste the loop would probably take the first place confidently. This is how it usually looks and it doesn’t serve understanding well.
while ( have_posts() ) : the_post();
// 10 posts
endwhile;
Let’s adjust it a bit. It becomes more clear what is the block and what is inside the block.
while ( have_posts() ) {
the_post();
// 10 posts
}
So while we have posts we do… Something? What is that something. Let’s write it out. It doesn’t look precisely like that in source, I am paraphrasing what happens.
while ( have_posts() ) {
$post = $wp_query->next_post();
$wp_query->setup_postdata( $post );
// 10 posts
}
We are moving to the next post and setting it up as current data for template tags. Wait, what does moving implies?
while ( have_posts() ) {
$wp_query->current_post ++;
$post = $wp_query->posts[ $wp_query->current_post ];
$wp_query->setup_postdata( $post );
// 10 posts
}
Ah, we are finally deep enough to grasp what is really going on:
- Counter for number of current post
- Array of all available posts
- We are moving to the next post in array every time
There are plenty of techniques which rely on checking value of the counter. It works fine for something like outputting content between the posts, but even that is needlessly complicated for splitting a loop.
Custom loop ticks
Now look at this.
the_post();
// 1 post
while ( have_posts() ) : the_post();
// 9 posts
endwhile;
We don’t have to only make loop ticks inside the block. It’s perfectly optional. We don’t have to run through all of loop either. It’s fine to work through several posts, stop, and pick up at another point in template.
Example
If you look at front page of the site the “Latest” and “Earlier” blocks are pretty different. But in fact they run off the same boring main loop.
{{ the_post() }}
<h3>Latest</h3>
<h4><a href="{{ the_permalink() }}">{{ the_title() }}</a></h4>
{{ the_content() }}
<h3>Earlier</h3>
{% loop %}
<ul>
<li><a href="{{ the_permalink() }}">{{ the_title() }}</a></li>
</ul>
{% endloop %}
It’s Twig rather than PHP, but you can see the application of the idea. Just “take” as many posts out of the loop as you need, stop and continue as you need. Profit.