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.
Hi-
I’m very very green to wordpress. Any help would be greatly appreciated.
Would you mind explaining where I would enter my page ID’s at…and any information I would have to change by entering my own info ( what info exactly) to make to above code work.
So say ( for my category ) that my page ID = 22…would all i have to do is replace ‘category__not_in’ => array(3,4),..with ‘category__not_in’ => array(22)?
I copied and pasted code exactly and it didn’t work.
And I’m assuming this code would would go in the(archive.php) file.
Once again – I know to you it may be obvious, but im so new out the box with this :P. Thanks!
# 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();
I have been looking for something like this all over. I have tried all the other exclude categories tricks, hacks and plugins with no luck. Hopefully this will work for me. Thanks for sharing!
thank you for writing the phrases that always put people into the right direction
The 3 solution is the best one because it reconstruct the query, however, I can’t understand why the first option didn’t worked out for you as it is much shorter way.
I think
would have done the trick in the first block. ;-)
I have a parent/child category pair that I’d like to apply one css rule to, while I have another parent/child category pair that I’d like to apply a different css rule to in my archive file…
It is currently setup as:
Archives
<a href="” rel=”bookmark” title=”">
…etc
*What I’d like to do, is apply the above post css (div class) to most the first parent/child category pair, and apply a different div class to my second parent/child category…any ideas?
Ooops…I guess this form does not allow for html
My email is on the contact page. Send me the (zipped) HTML over & I’ll see what I can do for you ;-)