Celebrating 20 years online :)
Web Dev + WordPress + Security

Fruit Loop: Separate any Number of Odd and Even Posts from any Category in WordPress

[ Fruit Loop ] Recently, I discussed how to implement a horizontally sequenced display order for WordPress posts in two columns. In that tutorial, I explain how to separate odd and even posts using a dual-loop configuration and PHP’s modulus operator. Such technique serves well a variety of configurational scenarios, but is limited to the display of the default (admin-specified) number of posts from all categories. In this tutorial, we adapt this odd-and-even loop configuration to accommodate a much greater degree of customization. Specifically, we will focus on separating any number of odd and even posts from any specific category or group of categories. Several additional configurational customizations will also be covered.

The Problem

In that previous dual-loop article I was telling you about, the dual-loop configuration is based upon two “have_posts” queries:

<?php if(have_posts()) : while(have_posts()) : 
      $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_content(); ?>

<?php endif; endwhile; else: ?>
<!-- alternate content -->
<?php endif; ?>

<?php $i = 0; rewind_posts(); ?>

<?php if(have_posts()) : while(have_posts()) : 
      $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_content(); ?>

<?php endif; endwhile; else: ?>
<!-- alternate content -->
<?php endif; ?>

Unfortunately, this configuration does not allow us to easily customize additional parameters such as the number of posts displayed in each loop, the category/categories from which posts are displayed, the order in which posts are displayed, and many others. As-is, our dual-loop configuration separates odd posts from even posts using two loops; all posts are pulled from all available categories, and the total number of posts displayed is based upon the specified value in the “Reading” options page in the WordPress admin. For example, if your default number of displayed posts is ten, each loop would display five posts, depending on availability.

What we want to do in this tutorial involves adapting our even/odd, dual-loop setup to accommodate further customization of various loop parameters. By replacing the two if(have_posts()):while(have_posts()): queries with two query_posts() queries, we expand the functionality of our loop configuration to enable category filtering, post numbers, and much more.

The Solution

The solution is very straightforward; simply replace the first part of each loop:

if(have_posts()) :

With a query_posts() query:


Such that we arrive with this very similar dual-loop configuration:

<?php query_posts(); while(have_posts()) : ?>
<?php $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_content(); ?>

<?php endif; endwhile; ?>

<?php $i = 0; rewind_posts(); ?>

<?php query_posts(); while(have_posts()) : ?>
<?php $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_content(); ?>

<?php endif; endwhile; ?>

Having done that, our odd/even dual-loop setup will continue to function as before, with the default number of posts being called from all categories and subsequently divided into odd and even posts via the two loops. The only difference at this point is that our new loop configuration is a lean, mean, highly customizable machine. We can now specify any number of posts, filter any number of categories, and do all of the other wonderful things made possible by the query_posts() function.


Now that we have modified our loop to accommodate customization of various parameters, let’s configure a dual-loop function that accomplishes the following:

  1. display only posts from category "x" in both loops
  2. display only ten posts in each loop, for a total of twenty posts
  3. display only odd posts in the first loop
  4. display only even posts in the second loop

To do this, we will use our custom loop setup and add two parameters to each of two query_posts() functions. As defined at the WordPress Codex, there are many parameters available to the query_posts() function, including the two we will use for this example:

  • cat=x
  • showposts=10

These parameters are self-explanatory. The cat=x parameter defines the category (remember to replace "x" with your category!), and the showposts=10 parameter defines the number of posts to be shown. Here is how these two parameters look when included properly into each of the query_posts() functions:

<?php query_posts('cat=x&showposts=10'); while(have_posts()) : ?>

And with that, we have accomplished our previously defined loop configuration. Ten category-"x" posts will be displayed in each loop, with odd posts appearing in the first loop and even posts appearing in the second loop. Of course, by simply modifying either or both of these two parameters, any number of posts may be called from any category, or even group of categories, as explained more fully in the WordPress Codex.

By taking advantage of the many other parameters available to the query_posts() function, the configurational possibilities are virtually endless. Here are just a few examples of the different parameter-based modifications you make to any query_posts-based loop:

  • tag=chevy,monza — display specific tag content
  • author_name=fonzi — display specific author content
  • day=, monthnum=, year= — display time-specific content
  • showposts=7 — specify any number of posts
  • 'post__in' => array(1,2,3) — display specific posts

As you can see, just about anything is possible when it comes to customizing the WordPress loop! For more great tips and tricks on WordPress loops, check out the “Related articles” section at the end of this tutorial. I also invite you to subscribe to Perishable Press for a periodic dose of WordPress, Web Design, and much more! :)

Mad Shouts

Huge thanks to Tony Boswell for his work with the primary technique covered in this tutorial. While implementing the odd/even, dual-loop configuration on his site, Sound Check Enterprises, Tony discovered the secret to customizing the method presented in my previous loop article: query_posts()! The query_posts() function enables extensive control over many key loop parameters, thereby enabling the various techniques presented in this article. Thanks for the eye-opener, Tony! :)

About the Author
Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
SAC Pro: Unlimited chats.

14 responses to “Fruit Loop: Separate any Number of Odd and Even Posts from any Category in WordPress”

  1. Incredible! You guys always amaze me. I’ve been looking for solution to this for some time. Thanks again. Do you have paypal donation?

  2. Thanks David, as the sole proprietor and producer of all the content on this site, I am humbled by your generous feedback. It really inspires me to keep writing and sharing my ideas and techniques. No PayPal donation is available, but I certainly appreciate the sentiment. Thank you.

  3. so as long as you include the rewind_posts(); function between loop functions, you can have an unlimited number of loops

  4. Jeff Starr 2009/07/19 8:57 pm

    Hi jay, actually you don’t need to use rewind_posts(); in all situations. At the end of this article, I explain how to create a million WordPress loops using the query_posts(); method. No rewinds required! ;)

  5. Jeff,

    This is awesome! Everyday, I find more and more about your site that I love.

    What I’m hoping to do with this trick is to “zebra stripe” my posts, like many sites do with their comments. By that I mean, I want my posts to go “boy-girl-boy-girl” or “even-odd-even-odd” down the page. What I have so far, pretty much just a post dump: http://jacobdubail.com/portfolio.

    I’m wondering if I should do this with jQuery, or even rely on CSS nth-child selectors instead.


  6. I made this way harder than I needed to…

    $('#portfolioList li:even').addClass('even');
    $('#portfolioList li:odd').addClass('odd');

    Simple as that. I’m sure there’s a nicer way to do it, but that works for now…

    Thanks for letting me brainstorm on your comment thread…


  7. Jeff, this is great. Exactly what I was looking for… well, almost.

    I’m trying to get pagination to work with this loop, but can’t figure it out. The standard next_posts_link() isn’t working, just returns a 404.

    Any ideas?

  8. Jacob, WordPress’ built-in post-navigation works for one loop only. As far as I know nobody has found a solution for multiple-loop post-navigation, except for maybe using Ajax.. Not sure if that’s the issue or not, but it’s where a lot of people get stuck..

  9. Great post! Thanks, Jeff~

    One more question:

    can it work?

  10. Great post! Thanks, Jeff~

    One more question:

    <div class=box>
    <div class=left></div>
    <div class=right></div>

    <div class=box>
    <div class=left></div>
    <div class=right></div>

    can it work?

  11. Hi! Thank you so much for this code, is really great!, But. I would like to appear the next secuence in muy post.

    and the result is

    I don’t know why, I’m not good in scripts so, any ideas?.

  12. Great Post Jeff!
    I also dig reading your posts and creative ways to dig deeper into WP, etc.. !

    I cam across your page while trying to find a ‘clean’ way to list sub-cats of a specific cat, while showing the article tile (with link) for each of the posts within the sub-cats.. You willing to help me out on this??

    Here is what I am aiming for:

       post1 date
       post2 date
       post3 date

       post1 date
       post2 date
       post3 date

    I know it can be done.. but after spending this last few weeks on two other CMS’s… my brain is not switching into ‘WP’ mode !

    Thanks man!
    P.S. I dig the new site theme.. classy!

Comments are closed for this post. Something to add? Let me know.
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
The Tao of WordPress: Master the art of WordPress.
Crazy that we’re almost halfway thru 2024.
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.