Super Plugin Sale! Your Choice: BOGO or 30% Off »
Web Dev + WordPress + Security

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(); ?>

<?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(); ?>

// 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

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. Now let’s look at some cool tweaks that help to customize the loops as desired..

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.</soapbox>

Thanks and God bless!

About the Author
Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
WP Themes In Depth: Build and sell awesome WordPress themes.

26 responses to “Super Loop: Exclude Specific Categories and Display any Number of Posts”

  1. How can i display only current month posts (limited to only maybe 5 posts)?

    Thanks in advance.

  2. Can we exclude search category from search result ?

  3. I will like to tell in details :

    I have 3 category on my blog. I want to put search box on the every category home page. I want to display result for only one category.

    Is it possible ?


  4. Which file is this code in.

  5. I want to display result on any page.I am currently developing the site, so I can put any where.

  6. Perishable 2007/11/25 9:21 am


    This code can be used once in just about any .php file available in your WordPress theme. It is intended to be used to loop through posts. For more information, see the WordPress Codex. Thanks :)

  7. Thanks for the nice article.. cleared some doubts!

  8. Very nice so far

    I want to display Asides.

    So first I run a loop to include just asides category and then run the loop again to include just the other categories (or exclude asides here) ?

    Can the loop be made to work like this ? Multiple time and include, rather than excluding ?

  9. Happy to help, Arjun!

  10. unrulyasides 2007/12/11 12:36 am

    good going so far. however, i’ve got a situation where i have a category archive template (say, category-16.php), that, thru the steps listed on this post i created, causes all children of category 16 to inherit the parent category template.

    i placed your $count coding into the category-16.php file, and it works perfectly for when i’m viewing the archive for category 16.

    however, when i go view the archives for any of the child categories, it doesn’t register the $count function, and reverts back to the default number of posts indicated in the admin options panel.

    if you or anyone knew of a workaround for that, appreciation would be bountiful.

  11. Thank’s for this tutorial!!!

  12. Brillant! This is so much better than the examples I found in the WordPress codex.

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 »
Banhammer: Protect your WordPress site against threats.
All free plugins updated and ready for WP 6.6 dropping next week. Pro plugin updates in the works also complete :)
99% of video thumbnail/previews are pure cringe. Goofy faces = Clickbait.
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.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.