WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to exclude posts from a certain category from being displayed on my home.php.

The code that is in my theme is as follows:

query_posts(array('post__not_in' => $featured_posts_array));
                if (have_posts()) :
                    while (have_posts()) : the_post(); ?>
                        <div <?php post_class() ?> id="post-<?php the_ID(); ?>">
                            <div class="categories">
                                <h3><?php the_categories_excerpt(); ?></h3>

I tried adding the following before the query_posts ( function but it does nothing.

function exclude_category( $query ) {
    if ( is_feed() ) {
        $query = set_query_var( 'cat', '-1' );  

    return $query;

add_filter( 'pre_get_posts', 'exclude_category' );

Is there some kind of format I need to follow?

share|improve this question
So would this be the right format then? pastebin.com/cLpGvnRD And in the home.php, i'll be replacing the query_post section with this: filter_pre_get_posts() – Sledge81 Jun 15 '12 at 15:14
No. Your Pastebin code isn't what I've got in my answer. And you don't ever need to call query_posts(), anywhere. (I'll update my answer to incorporate your featured posts function.) – Chip Bennett Jun 15 '12 at 15:19
Alright.. got it now. had to remove that piece of line query_posts(array('post__not_in' => $featured_posts_array)); – Sledge81 Jun 15 '12 at 15:25
up vote 3 down vote accepted

First, don't use query_posts(). Just get rid of the call entirely. It will break things.


I tried adding the following before the query_posts ( function but it does nothing.

Callbacks and add_action() calls belong in functions.php, not in the template file. If you've put it directly in home.php, remove it from there, and put it in functions.php.


Your pre_get_posts() filter uses the if ( is_feed() ) conditional. The is_feed() conditional returns true when an RSS feed is being output, not on the blog posts index (which is what is output via home.php). Try using is_home() instead.


Don't call set_query_var() inside your callback. Use $query->set() instead.

Putting it all together

Use the following in functions.php

function wpse55358_filter_pre_get_posts( $query ) {
    // Let's only modify the main query
    if ( ! is_main_query() ) {
        return $query;
    // Modify the blog posts index query
    if ( is_home() ) {
        // Exclude Category ID 1
        $query->set( 'cat', '-1' );

        // Build featured posts array
        $featured_posts_array = featured_posts_slider();

        // Exclude featured posts
        $query->set( 'post__not_in', $featured_posts_array );
    // Return the query object
    return $query;
add_filter( 'pre_get_posts', 'wpse55358_filter_pre_get_posts' );


What category are you trying to exclude? Are you sure the ID is 1?

share|improve this answer
Another thing to note - you will almost always want to also check for $query->is_main_query() right away when altering the query via pre_get_posts. Otherwise you might affect secondary queries unintentionally (e.g. a nav menu). – helenhousandi Jun 15 '12 at 14:37
I've updated the answer to incorporate featured_posts_slider(). – Chip Bennett Jun 15 '12 at 15:20

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.