[wp-hackers] exclude category from main loops via plugin

Jeremy Clarke jer at simianuprising.com
Fri Dec 17 15:05:00 UTC 2010


On Mon, Dec 13, 2010 at 8:17 AM, Erick Hitter <ehitter at gmail.com> wrote:

>
> Here's a sample:
> function my_query( $query ) {
> $query->query_vars[ 'category_name' ] = 'mycategory';
>  return $query;
> }
> add_action( 'pre_get_posts', 'my_query' );
>
>
I recently struggled through this exact situation and will add that you
should be very careful to test any other queries in your theme and make sure
they aren't being affected. The code above will affect ALL posts queries
everywhere on your site because it is added to the general pre_get_posts
hook.

In my case this meant that my 'recent posts' in the sidebar and other
secondary loops were affected in ways I couldn't predict and didn't want.

To get around this I wanted the query var to only be added for the 'main'
query for any given page. My solution was to add the 'pre_get_posts' hook
during the 'parse_request' action because it runs only once per pageload at
the time when the main query and status of the current page is being
determined. Then, inside my manipulation callback the first thing I do is
run remove_action() on itself. This ensures that the manipulated query vars
only take effect once, on the first query run after parse_query, which in my
testing was always the 'main' query for the page.

The code, massively simplified, looks like this (
http://pastebin.com/B3YxmSGh )


function gv_query_manipulation_parse_request() {

     add_action('pre_get_posts', 'gv_query_manipulation_pre_get_posts');
}
add_action('parse_request', 'gv_query_manipulation_parse_request');

function gv_query_manipulation_pre_get_posts($wp_query){
    global $excluded_category;

    remove_action('pre_get_posts', 'gv_query_manipulation_pre_get_posts');

    if (is_admin() OR is_feed())
        return;

    $wp_query->query_vars['category__not_in'][] = $excluded_category;

    return;
}

Note that I've explicitly excluded is_admin and is_feed from being affected.
You should consider these other situations where pre_get_posts takes effect
and add negative checks as necessary.


Jeremy Clarke • jeremyclarke.org
Code and Design • globalvoicesonline.org


More information about the wp-hackers mailing list