Prevent Posts in a Category From Displaying in WordPress’ Loop

By  on  

This code snippet has become a WordPress plugin!

Categories are obviously a major "classification" utility for websites and blogs that use WordPress.  Sometimes you want a category to represent more than just a basic post subject classification -- you may want a category of your blog to represent a link and writeup to an external site or may want to display their posts in a different way.  On this blog, I've added a "Quick Tips" category which are very short posts with tiny snippets of code that (quickly) detail how to do something simple.  I want those posts to display on listing pages, but not on the homepage.  I've seen some treacherous code to accomplish this feat, but luckily I've found a much cleaner way to prevent posts in a given category from displaying on a homepage.

The WordPress PHP

WordPress' API provides a pre_get_posts action which allows for additional pre-query logic:

// No "Quick Tips" on the homepage
function preventHomepageTips($query) {
	if($query->is_home() && $query->is_main_query()) {
		$query->set('cat', '-40'); // 40 is Quick Tips's category ID
	}
}
add_action('pre_get_posts', 'preventHomepageTips');

The custom function above is added as a WordPress action, usually within your functions.php file.  It's important you know the ID of the category or categories you don't want displaying in the main loop.  A dash is placed before said category ID.  To prevent multiple categories, separate them by commas:

$query->set('cat', '-40,-52');

If you simply want to prevent posts from displaying on the homepage but don't want to effect subsequent archive pages, you could add another hackish conditional:

if($query->is_home() && $query->is_main_query() && $_SERVER['REQUEST_URI'] == '/') {

This is an incredibly useful snippet that can be used for any number of purposes.  Chris Coyier, for example, uses a special category for his "Hot Links" posts (links to external websites) which he obviously doesn't displaying within the main loop.  There you have it though -- preventing posts in a category from displaying the loop!

Recent Features

  • By
    Designing for Simplicity

    Before we get started, it's worth me spending a brief moment introducing myself to you. My name is Mark (or @integralist if Twitter happens to be your communication tool of choice) and I currently work for BBC News in London England as a principal engineer/tech...

  • By
    7 Essential JavaScript Functions

    I remember the early days of JavaScript where you needed a simple function for just about everything because the browser vendors implemented features differently, and not just edge features, basic features, like addEventListener and attachEvent.  Times have changed but there are still a few functions each developer should...

Incredible Demos

  • By
    Check All/None Checkboxes Using MooTools

    There's nothing worse than having to click every checkbox in a list. Why not allow users to click one item and every checkbox becomes checked? Here's how to do just that with MooTools 1.2. The XHTML Note the image with the ucuc ID -- that...

  • By
    Create a Download Package Using MooTools Moousture

    Zohaib Sibt-e-Hassan recently released a great mouse gestures library for MooTools called Moousture. Moousture allows you to trigger functionality by moving your mouse in specified custom patterns. Too illustrate Moousture's value, I've created an image download builder using Mooustures and PHP. The XHTML We provide...

Discussion

  1. You the man.

  2. Hi there –

    I found your page while searching for something very similar to what you’ve done here, but instead of preventing a post from showing up on the homepage, I want to prevent it from showing up in a specific category.

    Here’s the thing: I have a category Cuisines and subcategories Italian, French, Spanish, etc. Each of those subcats has various recipes, as well as a post for the subcat itself (e.g., check out my Italian recipes!) I want the latter not to show up in the subcat, because obviously if you click them, they just link back to the same page you’re already on. I wonder if there’s an easy way to modify your code to accomplish this?

  3. Perfect! This is exactly what I was looking for! Thanks for sharing!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!