Exclude subcategories from archive pages

In standard WordPress setups the category archives will always show the posts from the selected category and all of its subcategories. Depending on how the categories are organised this can become unwieldy, as there will be a lot of duplication of posts in various category archives.

This short tutorial shows you how a short code snippet, added to your category archive template files, forces the archive to exclude posts assigned to subcategories of the selected category.

Category archive template file

The first step is to identify which of your theme template files is used to display the category archive. This will vary from theme to theme, but will generally be one of the following:

category.php
archive.php

If your theme has a category.php file, the following code modification will be made to this file. If your theme does not have a category.php then you should make the modification in your archive.php.

Modifying the template file

Loop as it most commonly appears in a typical category.php or archive.php file. For the sake of simplicity I have only left in the main elements of the Loop:

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

// various code eg title, author here
	
<?php the_content(); ?>
		
// various code eg post meta data, tags, categories etc
		
<?php endwhile; else: ?>

// various code to show a message if no posts found

<?php endif; ?>

I have left out all of the usual HTML markup and other Template Tags in order to keep things simple. However, your template file should look very similar to this.

Step 1: Replace the opening line of the Loop

Find this piece of code:

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

and replace it with this:

<?php $cat = intval( get_query_var('cat') ); 
if (have_posts()) : while (have_posts()) : the_post();
if (in_category($cat) ) : ?>

Step 2: Replace the end lines of the Loop

Find this piece of code:

<?php endwhile; else: ?>

// various code to show a message if no posts found

<?php endif; ?>

and replace it with this:

<?php endif; endwhile; else: ?>

// various code to show a message if no posts found

<?php endif; ?>

That’s it! If you now click a parent category from your main categories menu, your category archive page will exclude posts belonging to subcategories of this parent category.

Note that if you assign a post to a parent category and its subcategory, the post will still appear in both archives, ie the parent category archive and the subcategory archive.

Comments

  1. there is an issue when used with wp-pagenavi….

    it counts all the posts that return from the have_posts() function
    so it shows a blank page (or more) in pagenavi.

    i found this and its working.

    http://wordpress.org/extend/plugins/just-one-category/

    sorry for my english.

  2. @ Feedme

    Thanks for the comment and tip about wp-pagenavi.

    Ade.

  3. Very simple and well described tutorial! Works like a charm and just what I needed!
    Bookmarked! 🙂

  4. Thanks Viidar! Glad you liked it. 🙂

  5. Thanks so much for posting this. I’ve been looking for this for hours.

    One question – do you know how to avoid the “older entries” and “newer entries” links coming up despite no immediate posts in the active category? You can look at, for instance, “our views” on my site to see an example of the problem.

  6. @ Nicki,

    Glad you found it useful. 🙂

    I don’t get that behaviour here. I’m using posts_nav_link() for the next/previous posts.

  7. Thanks for the response. Can you tell me where you have the nav code? I tried the posts_nav_link() but this is the way that segment of code looks right now:

    See anything there that is grossly incorrect?

  8. Ok bummer, it wouldn’t post the code. If you are willing, I’d love to shoot it to you via email. Let me know if you have a sec to spare.

  9. Nikki,

    Post your question on my Forum, under the General section. You can post code there too, and I can take a look at it.

  10. This worked awesomely. Thanks!

  11. It worked for me.. thanx a lot for sharing!

  12. Thanks so much, it only took me about 2 days to find this and make it work – all the other versions posted are way too complicated for such a simple problem, this is a neat fix.

    • Thanks for the suggestion.

      I agree, that would be quite useful. I’ll have to give it some thought…

  13. Thank you for that, man! I’m using your code on my new wordpress-powered coupons page!

    Dominik

Leave a Reply to Nicki Cancel reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*


9 − = five