Super Loop: Exclude Specific Categories and Display any Number of Posts

[ Image: Detail view of a series of mechanical gears (black and white photo) ] Readers occasionally ask for help with their WordPress loops. Usually, these requests involve modifying the loop with some customized functionality. Frequently, such customization involves one of these popular behaviors:

  • Exclude a specific category
  • Exclude multiple categories
  • Display only one post or excerpt
  • Display some fixed number of posts
  • Play nice with additional loops on the same page

In this article, I present the swiss-army knife of WordPress loops. This highly versatile, “super” loop is standard WordPress code, easily implemented, and fully equipped to handle all of the custom behaviors mentioned above. Further, the PHP employed is self-contained, making it ultra-easy to pimp it up tough with your own (X)HTML markup. This tight little loop is perfect for “latest-post” excerpts, “aside” posts, news/headlines, site updates, urgent messages, and so much more. And since it plays well with multiple loops, the configurational possibilities are simply endless. Ready? Let’s get on with it..

The Complete Code

As is our custom here at Perishable Press, we present the full code offering right up front. Some sites make you wade through fields of copious copy and tedious text before delivering the full-meal deal. Not here. We save the tedious tutorial and long-winded explanations for the proceeding discussion. So, for those of you dropping in for a quick copy/paste fix — here you go:

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

<?php static $count = 0;
if ($count == "n") { break; }
else { ?>

<?php if ( in_category('x') && !is_single() ) continue; ?>
<?php if ( in_category('y') && !is_single() ) continue; ?>
<?php if ( in_category('z') && !is_single() ) continue; ?>

<div class="post">
<?php the_content(); ?>
</div>

<?php $count++; } ?>
<?php endwhile; ?>
<?php endif; ?>

The Breakdown

Now let’s take a look under the hood, one chunk at a time, and translate the loop to meatspeak:

// if everything is in place and ready, let's start the loop

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



// to display 'n' number of posts, we need to execute the loop 'n' number of times
// so we define a numerical variable called '$count' and set its value to zero
// with each iteration of the loop, the value of '$count' will increase by one
// after the value of '$count' reaches the specified number, the loop will stop
// *USER: change the 'n' to the number of posts that you would like to display

<?php static $count = 0;
if ($count == "n") { break; }
else { ?>



// to exclude all posts from categories 'x', 'y', 'z' unless in single-post view
// create an 'if' statement for each of the three specified categories as follows:
// if the post is in category 'x' and this is not a single-post view, exit the loop
// if the post is in category 'y' and this is not a single-post view, exit the loop
// if the post is in category 'z' and this is not a single-post view, exit the loop
// if no conditions are met, continue the loop; otherwise restart loop with next post
// if none of these conditions are met, run the loop; otherwise restart at the next post
// *USER: change the 'x', 'y', 'z' to the numbers of the categories you want to exclude

<?php if ( in_category('x') && !is_single() ) continue; ?>
<?php if ( in_category('y') && !is_single() ) continue; ?>
<?php if ( in_category('z') && !is_single() ) continue; ?>



// now, if all conditions have been satisfied, the post is displayed
// for CSS styling and layout purposes, we wrap the post content in a div
// we then display the entire post content via the 'the_content()' function
// *USER: change to '<?php the_excerpt(); ?>' to display post excerpts instead

<div class="post">
<?php the_content(); ?>
</div>



// here, we continue with the limiting of the number of displayed posts
// each iteration of the loop increases the value of '$count' by one
// the final two lines complete the loop and close the if statement

<?php $count++; } ?>
<?php endwhile; ?>
<?php endif; ?>

The Throwdown

Usage

Using this loop is theoretically simple. First, copy and paste the complete code into your WordPress document. Then, edit each of the three items according to the instructions provided via the “*USER:” comments in the code above. And that should do it. Save, upload, and check it out. If correctly implemented, any non-single page/post view will display only the specified number of posts from categories that have not been excluded.

Tweaks

Multiple Views

One of the great things about WordPress code is that there are so many ways to tweak, hack, and bend it to obey your will. As it is currently written, the loop will ignore any/all posts from categories ‘x’, ‘y’, and ‘z’ when not displayed as a single-view post. Thus, for archive views, category views, home views, and every other non-single view for that matter, the loop will not display the posts from the specified categories. Of course, if our “super loop” is used in a location where the excluded posts are not required, such as the home page, then everything is just peaches. However, if the loop is used to view the category archive of one of the excluded categories, no posts will be displayed. To fix this, simply replace each instance of this:

<?php if ( in_category('x') && !is_single() ) continue; ?>

with one of these:

// use this to display posts from category 'x' in single and archive views only
<?php if ( in_category('x') && !is_single() && !is_archive() ) continue; ?>

// use this to display posts from category 'x' in single and category views only 
<?php if ( in_category('x') && !is_single() && !is_category() ) continue; ?>

// use this to display posts from category 'x' in single, category, and archive views only
<?php if ( in_category('x') && !is_single() && !is_category() && !is_archive() ) continue; ?>

Excerpts Only

Another useful tweak is using this loop as a front-page “Freshest Loaf” type of stunt. To do this, it would be cool to show only a teaser of the full article, an excerpt, if you will. To do this, replace this:

<?php the_content(); ?>

..with this:

<?php the_excerpt(); ?>

No Exclusions

To use the loop without excluding any categories from the displayed posts, simply remove (or comment out) the following lines:

<?php if ( in_category('x') && !is_single() ) continue; ?>
<?php if ( in_category('y') && !is_single() ) continue; ?>
<?php if ( in_category('z') && !is_single() ) continue; ?>

No Restrictions

To use the loop without limiting the number of posts that are displayed, remove (or comment out) each of the following lines:

<?php static $count = 0;
if ($count == "n") { break; }
else { ?>

[ ... ]

<?php $count++; } ?>

The loop will then return the default number of posts, as specified via the WP Admin Options/Reading panel.

Wrap it up..

— Phew! I am like, so totally out of time now. I hope this article has somehow helped the open-source community. Here at Perishable Press, I operate independently — no sponsors, no ads, no gimmicks. I share this information as a way to give back to all the extremely kind and generous free-information peeps out there. Without all of you, I would not be online today. If you benefit from freely available, open-source information, remember to give back to the developers, authors, and designers who have helped reshape the commercial web into something a little more accessible to the rest of us. Thanks and God bless! </soapbox>