Multiple Loops on your Main Page – Why and How

First, a definition of “The Loop” from the WordPress Codex:

“The Loop” is a term that refers to the main process of WordPress. You use The Loop in your template files to show posts to visitors. You could make templates without The Loop, but you’d only be able to display data from one post.

Why would I want more than one loop?

  • To have a “Featured” post that is always above all other posts
  • To show a post (or two, or three) of a specific category, or categories on the main page
  • To break the blogging mold and make your theme unique

How do I do it?

This was for a project I’m involved with called Show in a Box. I wanted two loops, the first showing one post from a selected category, and the other looping through all posts while excluding the previously displayed post. I am using the Sandbox theme as a base and will be working with the index.php file specifically. This should work on any theme in theory, but please know that all themes are different, so your code may contain more, or less code than referenced here. As a matter of course, always backup your files before changing anything. Oh, and did I mention that you should backup, backup, backup!

Here goes…so in the original index.php file, you’ll find “The Loop”. This is the chunk of code that WP uses to “loop” through all the posts and display them.

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

<?php endwhile ?>

Now, this is the entire code of the index.php file. You’ll see a bunch of code inside “The Loop”, all of that stuff tells WordPress what things to display inside each post. Basically, this small bit of code says “loop through each post and display all of this information inbetween until I find no more posts”.

<?php while ( have_posts() ) : the_post() ?>
<div id="post-<?php the_ID() ?>" class="<?php sandbox_post_class() ?>">
<h2 class="entry-title"><a href="<?php the_permalink() ? rel="nofollow">" title="<?php printf(__('Permalink to %s', 'sandbox'), wp_specialchars(get_the_title(), 1)) ?>" rel="bookmark"><?php the_title() ?></a></h2>
<div class="entry-date"><abbr class="published" title="<?php the_time('Y-m-dTH:i:sO'); ?>"><?php unset($previousday); printf(__('%1$s &#8211; %2$s', 'sandbox'), the_date('', '', '', false), get_the_time()) ?></abbr></div>
<div class="entry-content">
<?php the_content(''.__('Read More <span class="meta-nav">&raquo;</span>', 'sandbox').''); ?>

<?php wp_link_pages('before=<div class="page-link">' .__('Pages:', 'sandbox') . '&after=</div>') ?>
</div>
<div class="entry-meta">
<span class="author vcard"><?php printf(__('By %s', 'sandbox'), '<a class="url fn n" href="'.get_author_link(false, $authordata->ID, $authordata->user_nicename).'" title="' . sprintf(__('View all posts by %s', 'sandbox'), $authordata->display_name) . '">'.get_the_author().'</a>') ?></span>
<span class="meta-sep">|</span>
<span class="cat-links"><?php printf(__('Posted in %s', 'sandbox'), get_the_category_list(', ')) ?></span>
<span class="meta-sep">|</span>
<?php the_tags(__('<span class="tag-links">Tagged ', 'sandbox'), ", ", "</span>nttttt<span class="meta-sep">|</span>n") ?>
<?php edit_post_link(__('Edit', 'sandbox'), "ttttt<span class="edit-link">", "</span>nttttt<span class="meta-sep">|</span>n"); ?>
<span class="comments-link"><?php comments_popup_link(__('Comments (0)', 'sandbox'), __('Comments (1)', 'sandbox'), __('Comments (%)', 'sandbox')) ?></span>
</div>
</div><!-- .post -->

<?php comments_template() ?>
<?php endwhile ?>

Now, in order to tell this loop to only show one post, we have to tell it what category to look in and how many posts from that category to display. So we change that loop code from this:

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

…to this…

<?php $my_query = new WP_Query('category_name=featured&showposts=1');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate = $post->ID; ?>

All of the code inbetween goes here

<?php endwhile; ?>

You can see in the code above, I have specified the category “featured” and set it to show 1 post. This could be any category we choose, and further, we could display as many posts from that category as we want.

So, at this point we still only have one loop on the main page, and if we were to view our site now, we would see only one post from the featured category on the main page. But wait, we want to display the rest of the posts underneath this right? So, what do we do? Add another loop on the same page. Here’s the code for the second loop:

<?php if (have_posts()) : while (have_posts()) : the_post();
if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?>

Some more inbetween code stuff here.

<?php endwhile; endif; ?>

So the post above is the standard WP Loop with some extra parameters. Those extra parameters say “don’t duplicate the post I already have shown in the first loop”, and “update the post cache as you loop through the posts.”

So, that’s it (in a nutshell). I found most of this information here http://codex.wordpress.org/The_Loop#Multiple_Loops and by following some of the links there. I also used some good ‘ole trial and error;) I hope this helps, and if it does, please take a moment to comment and let me know.

What are your favorite WordPress hacks?