How To Exclude Certain Categories From Your Home Page Or Blog Index

in WordPress Tutorials

A common query from WordPress users is ‘How do I exclude certain categories from my home page’. There are many reasons why a user would want to do this. Perhaps you don’t want reviews published on your home page or maybe you want to only show posts from your news category.

To do this you need to change what posts are called in the WordPress loop. The default WordPress themes Twenty Ten and Twenty Eleven use the function the_post() to call all blog posts.

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

The function the_post() uses WP_Query. We can use the WP_Query function itself to customise what posts are called and subsequently displayed on our home page, blox index or archives (e.g. category, date and tag archives).

Alternatively, we can use the function query_posts to alter the main loop. This is arguably the best function to use for excluding categories as you don’t have to edit the while statement that calls your posts. I will however show you both methods and you can decide which one is the most suitable for you.

Using The Function WP_Query

If you want to change the posts that are displayed on your home page you need to edit your themes index.php page. Most themes use archive.php for category, date and tag archives so that’s the template you need to edit if want to change what is displayed on any archive pages (though some good themes have dedicated templates for them such as category.php, date.php and tag.php).

Most themes document the start of the loop e.g. ‘Start the Loop’. The while statement that actually starts the loop follows this comment. For example, in the Twenty Eleven theme the start of the loop looks like this:

<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>

You need to replace this with the following:

// The Query
$query = new WP_Query( $args );
// The Loop
while ( $query->have_posts() ) : $query->the_post();

To control what posts are displayed in the loop, you need to define the parameters in the
WP_Query function i.e. modify $query = new WP_Query( $args );.

There are 5 category parameters however the two that are used most often are cat and category_name.

To show your news category, which has an id of 1, you could use the parameter cat:

$query = new WP_Query( 'cat=1' );

Alternatively, you could achieve the same result using the parameter category_name:

$query = new WP_Query( 'category_name=news' );

Additional categories can be added easily by simply adding them to the end of the parameter list (separated by commas).

$query = new WP_Query( 'cat=1,7,121' );


$query = new WP_Query( 'category_name=news,reviews,tutorials' );

You can display all posts except those from a certain category by adding a minus sign before the category id you want to exclude. Note, you can’t use the category_name parameter to exclude categories:

$query = new WP_Query( 'cat=-1' );

I mentioned before that there are 5 category parameters. I have discussed the first two: cat and category_name. Those are to include and exclude certain categories from your post list.

The other three are category__and, category__in and category__not_in.

category__and displays posts that are in multiple categories i.e. posts will only be displayed if they are attached to all categories listed:

$query = new WP_Query( array( 'category__and' => array( 1, 7 ) ) );

category__in works like an OR statement. It will display posts from any category that are listed:

$query = new WP_Query( array( 'category__in' => array( 7, 127 ) ) );

Multiple categories can be excluded using the category__not_in parameter, though it’s much easier to use the cat parameter and list categories you want to exclude using the minus sign:

$query = new WP_Query( array( 'category__not_in' => array( 2, 6 ) ) );

WP Query is a very versatile function. Categories are just one of the many parameter types that can be used with the function to customise what posts are displayed in the loop. You can also use:

  • Author Parameters – Display posts by author or multiple authors and exclude defined authors from the post list.
  • Tag Parameters – Display and exclude certain tags from the post list.
  • Taxonomy Parameters – Display posts from one or several custom taxonomies.
  • Post & Page Parameters – Display specific posts or pages using IDs or page slugs.
  • Type & Status Parameters – Display posts from certain post types or posts with certain status’s such as draft or pending. You can also display all posts with attachments.
  • Pagination Parameters – Determine how many posts per page are displayed.
  • Offset Parameter – Number of posts to offset post list by.
  • Order & Orderby Parameters – Change the order that posts are ordered in your list.
  • Sticky Post Parameters – Include or exclude sticky posts from your post list.
  • Time Parameters – Display posts from within a certain time scale.
  • Custom Field Parameters – Display posts associated with defined custom fields.
  • Permission Parameters – Display published and private posts.

The WP_Query documentation page gives examples of every parameter that can be used.

Here are a few examples to illustrate how these parameters can be used. If you only want to display your full time authors on a page, you could simply list the ids of your full time staff (this would therefore exclude guest posters etc):

$query = new WP_Query( 'author=1,8,25' );

Displaying random posts is easy using the orderby parameter. The example below will show 5 random posts from your blog:

$query = new WP_Query( array ( 'orderby' => 'rand', 'posts_per_page' => '5' ) );

If you use tags more than categories, you could use one of the 7 available tag parameters such as tag:

$query = new WP_Query( 'tag=news,sitenews' );

Using the post__in parameter you can define the exact posts you want to display on a page:

$query = new WP_Query( array( 'post__in' => array( 2, 6, 7, 10, 15 ) ) );

I recommend reading the WP_Query documentation page for a full list of the parameters that you can use with the function. There are lots of great examples on the page, which should help you customise the loop exactly as you want.

Using The Function query_posts

The query_posts is an incredibly easy way to customise the posts that are displayed on a page. You don’t have to change your existing loop code, query_posts simply alters it for you.

query_posts( $args );

To use the function, all you have to do is call it before the start of your loop. For example:

// The Query
query_posts( $args );
// The Loop
while ( have_posts() ) : the_post();

If you plan on calling a second loop on your page, make sure that you reset the loop after the while statement using wp_reset_query(). For example:

// The Query
<?php query_posts( $args ); ?>
 <?php /* Start the Loop */ ?>
   <?php while ( have_posts() ) : the_post(); ?>
    <?php get_template_part( 'content', get_post_format() ); ?>
   <?php endwhile; ?>
<?php wp_reset_query(); ?>

Changing the parameters for query_posts() works in a similar fashion to WP Query. To only show posts from certain categories you use the cat parameter and list the categories you want to show posts from:

  <?php query_posts( 'cat=1,5,6' );  ?>

Similarly, to show all posts but exclude some categories, you use the same parameter but add a minus sign to the category ids you don’t want to show:

 <?php query_posts( 'cat=-3,-5' );  ?>

It can also be used to retrieve specific posts:

query_posts( 'p=2' );

To override the default number of posts per page that you have set in your settings/reading area, you can use the posts_per_page parameter:

query_posts( 'posts_per_page=5' );

Check out the query_posts documentation page for more information on using the function and details about the parameters that you can use.

Exclude Categories Using A WordPress Plugin

As always, there are WordPress plugins available for those of you who aren’t comfortable editing your theme templates. Two that I recommend are Simply Exclude and Ultimate Category Excluder.

Simply Exclude

Simply Exclude lets you exclude or include categories, authors, tags and pages from your home page, archives, search results and RSS feed.

The plugin is very easy to use and works with other plugins such as Google XML Sitemaps and Search Unleashed.

Simply Exclude

Ultimate Category Excluder

Ultimate Category Excluder lets you easily exclude categories from your home page, archives and RSS feed. Unlike Simply Exclude, it only works with categories and doesn’t allow you to exclude authors, tags or pages.

Ultimate Category Excluder


Customising that posts are displaying on your home page, archives or custom page is very straight forward. If you feel comfortable editing templates I recommend customising your loop manually as it only requires a few minor edits. Though the category exclusion plugins Simply Exclude and Ultimate Category Excluder work very well and are worth using if you are concerned about overwriting your template edits whenever you update your theme.

As always, if you are unsure about any of the steps in this tutorial, please leave a comment here or post a thread in the WordPress forums and I’ll do my best to help :)

Good luck,

Comments (9)

  • Comment by amir

    Hello my friends
    I have a problem with viper and same theme
    i use viper wordpress theme, that is ECommerce theme and free .
    When a product is finish in store, I can not delete product page for Google indexing .
    So , i should remove the product only of home page .
    But plugins not support to ‘product’ and ‘department’ options
    Because it is “taxonomy-department”.
    this plugins (wp-exclude-from-homepage.1.1.2 and wp-exclude-from-homepage.1.1.2 ) support for normal category but not support ‘department and other taxonomy ‘ !!!
    I want for example the products in “finish” categories are not displayed on my home page
    Purpose of “categories” is “product > department > finish” in my theme .

    Dear friends can you suggest a way for help me ?
    Please explain to me as a beginner.

    thank you

  • Comment by arronryweethy

    Keep functioning ,remarkable job!

    | The Nitty-Gritty On Significant Issues In Juicer Reviews

  • Comment by Nick

    Thanks for the help. I ended up going with simply exclude. It seems to work very well.

  • Comment by John B
    John B

    I use WP in my site too and it works well.

  • Comment by elletis01

    nice article but i found this article very usefull:

  • Comment by Kevin Muldoon
    Kevin Muldoon

     @MAJ3STIC No problem. Sorry I couldn’t help more.
    With the last WP Mods design I displayed featured posts at the top and bottom of every page so used query_posts a lot. I only wanted to show posts that were in the featured category so didn’t run into the same problem as you.

  • Comment by MAJ3STIC

     @Kevin Muldoon  Thanks for the reply, it’s actually for a client of mine and I’ve been trying to figure it out it was working perfectly until I added the Special Features -1359 into the query_posts, now the post column shows everything in that column whether it has video or not, but is excluding Specialy Features only. Thanks for your quick reply. 

  • Comment by Kevin Muldoon
    Kevin Muldoon

     @MAJ3STIC Mmmm. I’m not 100% sure. This is something I’ve not had to deal with as I only attach posts to one category. I only break this rule when I assign a post to the featured category.
    By the looks of it, you may have problems trying to achieve what you want if most of your posts are attached to two or more categories. I’m sure there is a way round this through coding but I’m not personally aware of it.
    I’m not sure how many posts you have in each category but a quick fix could be to view all of your posts in the videos and special features and make sure they are only attached to one category.

  • Comment by MAJ3STIC

    I’m excluding the following categories but it’s still showing them in the loop if they’re in multiple categories.<?php  query_posts(‘cat=-60,-1359′. $category .’&paged=’.$paged);  ?> ie: cat=60 videos cat=1359 special features, however if they’re categorized in video and news cat=10 they’re showing up in the loop still, any thoughts?