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.
<?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
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.
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.
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 :)