Posts Tagged ‘custom_query’

Tip: Exclude Categories From Archive In WordPress

August 20th, 2009

While working on a recent project, I came across a task: exclude certain categories from the archive page. I went the usual way to the WordPress codex -> query_posts and thought the following would do it:

1
2
3
4
5
6
7
8
9
10
# Exclude categories | archive.php
if ( is_home() || is_category('one') || is_category('two') )
{
    $current_cat = get_query_var( 'cat' );
    $exclude_cat = 3;
    $current_page = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    query_posts("cat=$current_cat,-$exclude_cat&paged=$current_page");
}
//The Loop
if ( have_posts() ) : while ( have_posts() ) : the_post();

This, unfortunately, didn’t work. I then thought of filtering via custom queries. The problem with custom queries is that the filter is applied to each and every query on the page. If you do:

1
2
3
4
5
6
7
8
9
10
# Exclude categories | functions.php
function fd_remove_cat( $nada )
{
  global $wp_query;
  if ( is_home() || is_category('one') || is_category('two') )
  {
     $wp_query->query_vars['cat'] = '-3';
  }
}
add_action('pre_get_posts', 'fd_remove_cat' );

this will work, but it affects all other queries on the page as well. If you have some custom ‘query_posts’ in your theme, category 3 will be stripped out of all queries on the page.

I came up with this solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Exclude categories | archive.php
if ( is_category('one') || is_category('two') )
{
    global $wpdb;
    $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    query_posts(
        array_merge(
            array
            (
                'category__in' => array($cat),
                'category__not_in' => array(3,4),
                'paged' => $paged
            ), $wp_query->query
        )
    );
}
//The Loop
if ( have_posts() ) : while ( have_posts() ) : the_post();

The above code preserves the original query and adds/alter defined query variables (also see query_posts, ‘Preserving the Original Query’).

I hope this post keeps you from wasting time while trying to alter the wp_query.