Skip to content


WordPress: hacking categories

The Loop is your basic WordPress doodad. (Please do not be intimidated or alarmed by my command of fancy-pants terminology.) Its function is to retrieve and display the latest posts with the number of posts displayed per page set by the user in WordPress’ Admin page (Settings>Reading). I’ve got this blog currently set to display five posts per page.

A basic loop looks like this:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

BLAH BLAH BLAH

<?php endwhile; else: ?>

<p>Sorry, no posts matched your criteria.</p>

<?php endif; ?>

The BLAH BLAH BLAH is the section of the loop that determines how each post is displayed. In most themes, this will retrieve and display the title, date, time and author name along with the actual post content.

Now I’ve got a Web category on this blog that presents links I’ve found on the … Web. Rather than do the typical blog thing of grabbing an image and padding the entry with some snarky comments, I simply present these links with a brief one-line description if necessary.

I got it in my head that I would restyle the blog so that it handled these quick link entries differently from the rest of the blog. This involved three different tasks: excluding the Web category from the main loop, displaying the five latest posts in the Web category on the left sidebar and finally changing how posts are displayed when viewing the Web category.

For now, let’s take a look at …

Excluding a category

The first step was to exclude the Web category (i.e. category 6) from the main page loop (which in my theme is located in the home.php file). As always, there are several methods of accomplishing this in WordPress and as always, some methods are better than others.

The simplest method is detailed in the WordPress Codex:

< ?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

< ?php if (in_category('3')) continue; ?>

BLAH BLAH BLAH

< ?php endwhile; else: ?>

<p>Sorry, no posts matched your criteria.</p>

< ?php endif; ?>

That tells WordPress to simply ignore the post (i.e. don’t display it) if it’s in category 3. That works but there’s one important caveat as noted in the Codex:

Please note that even though the post is not being displayed it is still being counted by WordPress as having been shown — this means that if you have WordPress set to show at most seven posts and that two of the last seven are from Category 3 then you will only display five posts on your main page.

So the code works but it’s a little awkward.

Michael Ciccarelli has a better solution.

He’s accomplishing a lot more with his code than I needed so I trimmed it down to just this:

< ?php if (have_posts()) : ?>
< ?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; query_posts("cat=-6&paged=$paged"); ?>

< ?php while (have_posts()) : the_post(); ?>

BLAH BLAH BLAH

< ?php endwhile; else: ?>

<p>< ?php _e('Sorry, no posts matched your criteria.'); ?></p>

< ?php endif; ?>

There are two things to note there.

The first is the query_posts call to retrieve all posts except the posts in category 6.

The second is the code to command WordPress to pay attention to the pagination. Using query_posts screws pagination up and without all that additional code, WordPress would display the latest five posts on every single page.

Posted in WordPress.


5 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. James says

    is there any way to do this and have the posts in ascending order, i have tried to add this to your code – but it doesnt work, any ideas?

  2. James says

    This is great, where would i add my code to get my posts to display in reverse? if i have another query posts piece if php it renders whichever is first useless, any way of adding that into your example?

  3. Gobi says

    I haven’t tested it out but you could try replacing the line in the code snippet above with this:
    < ?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; query_posts("cat=-6&order=ASC&paged=$paged"); ?>

Continuing the Discussion

  1. WordPress: multi-loop : Fuyoh! linked to this post on Saturday, April 4, 2009

    […] a previous post, I looked at The Loop in WordPress and how it was possible to exclude specific categories from […]

  2. WordPress: Categorically speaking : Fuyoh! linked to this post on Sunday, May 17, 2009

    […] previous posts, I looked at excluding a category from the main page of WordPress blog and displaying posts […]



Some HTML is OK

or, reply to this post via trackback.