Problem: On my latest project there’s a WordPress post category that only ever displays in a sidebar. I never want it to display in a ‘main’ loop posts on an archive page (whether it be the blog home, date archives, author archive etc etc. Until now I’ve been using ‘query_posts()’ and doing something like this in the main templates like home.php and index.php:
<?php $catObj = get_category_by_slug('my-cat-slug'); query_posts( 'cat=-'.$catObj->term_id ); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <!-- Show stuff init! --> <?php endwhile; endif;?> |
This works… but I have to do it everywhere the loop is used, and when you dig into WordPress Templates that’s a lot of places.
Solution: There’s always a way to do something globaly in WordPress using Filters, Actions, or Classes in your theme’s functions.php file (or a plugin even). In this case we can use the ‘pre_get_posts’ action in functions.php to exclude the category for all main queries:
function banish_category( $query ) { if ( !is_admin() && $query->is_main_query() ) { $catObj = get_category_by_slug('my-cat-slug'); $query->set( 'cat', '-'.$catObj->term_id ); } } add_action( 'pre_get_posts', 'banish_category' ); |
Notes:
1) The ‘is_main_query()’ bit is important. Without it the code will work, but you’ll won’t be able to loop though the excluded category with ‘query_posts’ anywhere else on the site.
2) See the minus sign in the $query->set line? That’s the bit that excludes the cat. Important and easy to forget.
3) In the example above I’m using the categories slug to reference it (for portability), but if you are happy to use category ID then it’s even simpler. Just replace:
//etc... $catObj = get_category_by_slug('my-cat-slug'); $query->set( 'cat', '-'.$catObj->term_id ); //etc... |
With…
//etc... $query->set( 'cat', '-123' ); //etc... |
4) I don’t have a Cat Slug… but if they existed I might (looksee)
5) UPDATE on 29 Jan 2014: It’s important to add the ‘!is_admin()’ but to stop the categories also being hidden in the Admin area. Confused me for 10 mins when a load of posts went missing just now!
Please let me know if these snippets and notes were useful, just one click!