Remove Several Categories from the Loop in WordPress
As Featured on: Smashing Magazine!

Here is a little trick to to remove categories from the main loop. Yes, you can display these elsewhere; in pages (view custom template), the sidebar, the footer… wherever you want them and I’ll show you how.
Complete code
<?php$themes = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'themes'");$plugins = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'plugins'");$posts = query_posts($query_string . 'cat=-' . $themes . ',-' . $plugins);if (have_posts()) : while (have_posts()) : the_post();?>
Explanation
Line 1:
Opening PHP Statement
Lines 2 and 3:
The $themes and $plugins are the variables I’ve set up to pull the category id’s by name from the WordPress database. WHERE slug = ‘themes’ and WHERE slug = ‘plugins’.
Why did I setup those queries like that?
It’s a lot easier to remember a category by name than ID number isn’t it?
You can quickly change which category to remove from the loop and not have to look up the category id.
Line 4:
The $posts variable is internal to WordPress and the rest of the statement tells query_posts() to remove the categories by cat id (which we pulled from lines 2 and 3).
Line 5:
Our familiar loop is executed.
Line 6:
End of php statement
How to Add your Removed Categories anywhere you want them!
So now that you’ve removed some categories from displaying in your main loop… where do you want to put them?
The following code is how to display posts from a single category that we removed… I’ll show you how to add additional categories if you removed 2 or more from the main loop like I did in the previous code.
Complete Code
<?php$themecat = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'themes'");$get_themes = new WP_Query('cat=' .$themecat. '&showposts=10&orderby=post_date&order=desc');while ($get_themes->have_posts()) : $get_themes->the_post();$do_not_duplicate = $post->ID; ?><h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3><?php the_content();?><?php endwhile; ?>
Explanation
Line 1:
Opening PHP statement
Line 2:
The $themecat variable retrieves the category id WHERE slug = ‘themes’. One of the categories I removed in the above code.
Line 3:
The $get_themes variable initiates our variables for posting, here I have it setup to show 10 posts ordered in DESC fashion by date.
Line 4:
While we have posts with the $get_themes ID then start our loop!
Line 5:
Tells $get_themes not to show duplicate posts (very important).
Line 6 and 7:
You can basically put anything in here that you want that relates to the inner workings of the loop. I personally decided to just list the title and the content for illustration purposes.
Line 8:
Ending our while loop.
In order to put multiple categories (that you’ve removed from the main loop in the first portion of this tutorial) you must duplicate line 2, and change $themecat and ‘themes’ to $categorynamecat and ‘category’.
Then within line 3 replace .$themecat. with:
.$themecat. ‘,’ .$categorynamecat.And you should now have 2 categories removed from the main loop and displayed anywhere else you’d like!













Mark, good article!
I knew that this could be done, but your use of category’s name instead of category id make the whole hack very “portable”. I mean that if I develop a theme locally on a “test” wp installation than I put it online often the category id is different and this require further tweaking online…
Just a question: is it “safe” to add so many db query? doesn’t slow down the blog too much?
Stefano
@Stefano,
that was the whole point, to make it portable. As for the “too many queries”… no, it’s not too many queries, you can test this yourself by starting a default blog and uncommenting the “xx number of queries in xx seconds” format in the footer.php of the default theme.
Glad I was able to help, I’m actually writing a plugin for this right now!
[...] Removing Several Categories from the Loop in WordPress There will be times when you want to take posts in a certain category out of the loop and show them someplace else. This tutorial shows you how. [...]
Hey Mark, thanks for the tips on this post. I’m thinking about taking some categories out of the loop and display them elsewhere. If I put that second loop in a page, will it work just as a second index.php? With the site pagination etc. Just like a second blog?
Simon,
As best as I can remember (i don’t have time to test it right now) but I believe if you use the code as shown you’ll essentially have JUST that category in the loop (on your new page). It will work like a category index only. Give me some more details on what you’re trying to do and I’ll do what I can to help.
Hey there Mark, thanks for replying so quickly. Hmm maybe I’m not seeing something here, might as well be.
I’m trying to get a something like a guest poster category that will not be shown in the main loop, but instead on another page (though displayed the way the blog posts are diplayed in the home (index.php) directory).
If any posts are any good, I would like to put them in another category and “promote” them to the main page…I hope I don’t have to set up another blog for that..?
@Simon,
I’ll detail the steps necessary to achieve this…
So, just to review, you want a guest poster category… we’ll call it “Guest Posts” as the name so the wordpress slug would be “guest-posts”. You don’t want this to show up in the main loop but displayed LIKE the main index loop.
To do this it’s very easy… basically we’ll remove the guest-posts category from the main loop.
<?php
$guestpostcat = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = ‘guest-posts’");
$posts = query_posts($query_string . ‘cat=-’ . $guestpostcat);
if (have_posts()) : while (have_posts()) : the_post(); ?>
Then since this guest-post category is removed from the main loop (your index.php) you can go about this one easy way…
find the category id of your guest-posts category then copy your index.php (before you modify it from above) to category-X.php where X = the category id of guest-posts. This will basically create a listing of JUST that category of posts.
If you have any other questions please let me know!
Genious. I’ll try this tomorrow. How can I call the categroy-x.php? What kind of slug will it be in? Just home.com/category-name?
no, simon, what i mean is after you remove the category from the main loop go to the admin page and look at your categories… hover over the “guest-posts” category and you’ll see something like this…
http://yoursite.com/wp-admin/categories.php?action=edit&cat_ID=224
that cat_ID would be the category id wordpress assigned to guest-posts so create, in this case, category-224.php
Yeah I know, I meant the slug structure where I’ll get the site. But now it’s getting clear, it’s just basically an archive page so I had it here ../category/guest-posts/.
Cheers
Pity the design for the archives is gone, but at least I kind of have now what I wanted
Simon what do you mean the design for the archives is lost… you can create i believe an “archives or archive.php” in your theme root and design it however you want. If you want to exclude the guest-posts from archives, then just do the same that you did to your index.php to the archives.php file! Let me know if I can help anymore!
[...] from showing in the Wordpress loop is important. Here’s a quick tutorial with sample code on how to exclude certain categories in your [...]
Why don’t we make it simple and just add a filter to the functions.php :
is_feed || $query->is_home || $query->is_search) {
$query->set('cat','-17');
}
return $query;
}
add_filter('pre_get_posts','asidesFilter');
?>
Sean,
The point of the post was to remove it by category name, therein making it portable code. Cat 17 isn’t the same for everyone. Functions is just another place to put things so this would work but only if it was my code that was in the filter. Thanks for the feedback!
Leave your response!
Tweets...
Posting tweet...
Highest Rated
Most Viewed
Users Online
Categories
Blogroll
Tags
$wpdb 800 x 600 800x600 resolution 1024x768 resolution Add Categories Alexa Alexa Rank Alexa Traffic Rank A List Bloggers alternating_colors appeal to readers Asides Asides Plugin background_colors Black Hat SEO blog audience blog content Bloggercamp News Blogger Gifts Blog Gifts blogging blogging for money blogging honestly blogging mistakes Blogging Tips blog readership Boeing Boeing Services Company Categories foreach loop get_posts Google PageRank Google Webmaster Tools Personal SEO Tags The Loop Theme Reviews WAMP WAMP5 Webhost Webmaster Tools WordPress WordPress SEO WordPress TipsArchives
Recent Comments
Most Commented
Most Viewed