Home » Featured, WordPress Tips

Remove Several Categories from the Loop in WordPress

28 December 2007 5,318 views 14 Comments

As Featured on: Smashing Magazine!

remove-categories-wordpress
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

  1. <?php
  2. $themes = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'themes'");
  3. $plugins = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'plugins'");
  4. $posts = query_posts($query_string . 'cat=-' . $themes . ',-' . $plugins);
  5. if (have_posts()) : while (have_posts()) : the_post();
  6. ?>

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

  1. <?php
  2. $themecat = $wpdb->get_var("SELECT term_id FROM wp_terms WHERE slug = 'themes'");
  3. $get_themes = new WP_Query('cat=' .$themecat. '&showposts=10&orderby=post_date&order=desc');
  4. while ($get_themes->have_posts()) : $get_themes->the_post();
  5. $do_not_duplicate = $post->ID; ?>
  6. <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
  7. <?php the_content();?>
  8. <?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!

If you need any help or guidance please let me know via comments!


1 Star2 Stars3 Stars4 Stars5 Stars
(4 votes: 3.50 / 5)
Loading ... Loading ...

14 Comments »

  • stefano said:

    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

  • Mark Penix (author) said:

    @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!

  • WordPress Developer’s Toolbox | Developer's Toolbox | Smashing Magazine said:

    [...] 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. [...]

  • Simon said:

    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?

  • Mark Penix (author) said:

    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.

  • Simon said:

    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..?

  • Mark Penix (author) said:

    @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!

  • Simon said:

    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?

  • Mark Penix (author) said:

    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

  • Simon said:

    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/.
    Pity the design for the archives is gone, but at least I kind of have now what I wanted :) Cheers

  • Mark Penix (author) said:

    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!

  • Top 50 Wordpress Tutorials - NETTUTS said:

    [...] from showing in the Wordpress loop is important. Here’s a quick tutorial with sample code on how to exclude certain categories in your [...]

  • BlogInstall said:

    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');
    ?>

  • Mark Penix (author) said:

    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!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.