WordPress Tip: Style and layout pages by category

I've been working on a project lately that has required me to knock together a customized WordPress theme. It's been a good learning experience so far, as rather than taking an established theme and editing it to my needs, I've started with the blank 'sandbox' theme. For this project I've run into a few brick walls that have caused a lot of head scratching, and figuring out solutions has not always been a simple thing. Here's one problem and solution I've just found that I thought I share with people. Note: There are probably a lot of ways to do this, the solution below is just the way I got it to work. As usual back up everything before trying this, and test locally first if possible.

Problem: You want to layout posts from one specific category differently from posts from all the other categories. In other words, you may have a general blog with a wide range of post categories. One category might be "movie reviews". You want to give all posts from the "movie reviews" category a different layout, and different styles.

Solution:
Step One. Create two copies of the default single.php file. Give these two new files identifiable names, eg. single-general.php and single-reviews.php.

Step Two: Open the original default single.php file in your text editor (eg. Notepad). Delete all the code within this file and replace it with the following, then save and close the file.

$post = $wp_query->post;
if ( in_category('2') ) {
include(TEMPLATEPATH . '/single-reviews.php');
} else {
include(TEMPLATEPATH . '/single-general.php');
}
?>

What does this code do? Here's a dodgy plain english overview.

$post = $wp_query->post

When a user opens (or requests) a post, WordPress takes a look at it, and runs a query on it (to see what it is).

if ( in_category('2') ) {
include(TEMPLATEPATH . '/single-reviews.php');

This starts the 'if' statement, and says 'if the post that has been queried is from the category with the ID '2' then use the single-reviews.php template. Obviously you'd create a 'Reviews' category in WordPress and use the 'Reviews' categories ID number. You can find the ID number by logging into your Dashboard and the selecting Manage > Categories then find the ID for the relevant category. For the sake of this exercise assume that the 'Reviews' category ID is '2'.


} else {
include(TEMPLATEPATH . '/single-general.php');
}

This section of code says that if the post is not from the category with the ID '2' then use the single-general.php template instead.

So that's pretty much all the code explained. The whole thing uses a simple 'if/else' statement. An 'if/else' statement works by testing a condition. If the condition is satisfied it does the 'if' section, if it's not satisfied it does the 'else' section of the code. In other words, you could read it as, "if I'm hungry, have lunch, else carry on as normal".

Step Three.
Style and layout your two new files, single-general.php and single-reviews.php, however you like. Now if everything has gone to plan you should be able to display posts from a specific category differently to posts from every other category.

13 Comments on WordPress Tip: Style and layout pages by category

  1. Can you fix the errors, I’ve been looking for this in a while now and this is the only site I came across with a solution. I really would like to see the rest of the code. Thanks

  2. There you go Peter. The problem was that I recently installed the exec-php plugin so it was trying to execute the code within the post.

  3. Great Tip, will certainly start using that!

    @Michael you are talking about sth completely different, namely category archives, that is to show a different layout for different category archives.

  4. Sorry Victoria, this was first posted in 2008, the site that I used this on has changed again since again. Haven’t tested the code recently but can’t see any reason it wouldn’t still work.

1 Trackbacks & Pingbacks

  1. WordPress Tip: Style and layout pages by category | FlickWatcher.com

Leave a Reply

Your email address will not be published.


*