Styling Individual Posts Based On Category
One of the reasons I like to help out in the WordPress Support Forum is it gives me yet something else to blog about. A recent poster asked if it was possible to apply a different style to categories. The answer is yes.
Back on 09 April 2008 I showed you how to create a page with a unique style. (see Create Pages With a Different Style Sheet) To summarize that post you only need to create a new style sheet, upload it to your theme's folder, then call that style sheet in header.php. In that post we used is_page() but you can easily substitute is_category().
Let's assume you have a category called "news" that you want to apply a different style to. Using your theme's style sheet as a guide, create a new one, call it something like news.css and upload it to your theme's folder. I chose the name news.css purely for the sake of organization but you can call it anything you want. Next, look in header.php for the call to the regular style sheet. It will look something like this ...
<link rel="stylesheet" href="<php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
We then wrap a few lines of code around that as such ...
<?php if ( is_category('X') ) { ?>
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
<?php } else { ?>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<?php } ?>
... where X is the numerical ID of the category you want to style. What that says is if we are on the category page with the numerical ID of X use news.css and if not then use style.css.
Now this is fine for styling category pages, that is, the pages that contain a list of posts from a certain category. However if you click on one of the post titles to read that particular entry your special styling will be lost. Why? Because we are now using a different page template. According to the WordPress template hierarchy individual posts are displayed using single.php. Can we style those pages as well? Again the answer is yes.
Let's assume you have completed the above and have your special styling applied to the "news" category page. We now want to apply that same styling to all of the individual posts from that same category. First, make 2 copies of single.php and call them single-a.php and single-b.php. You will now have 3 php files for displaying individual posts - single.php, single-a.php and single-b.php. Open single.php and delete the contents. Now insert the following ...
<?php
$post = $wp_query->post;
if ( in_category('X') ) {
include(TEMPLATEPATH . '/single-b.php');
} else {
include(TEMPLATEPATH . '/single-a.php');
}
?>
Again, X being the numerical ID of the category you want to style. What the above says is if we are on the single post page that belongs to category X use the template file single-b.php and if not use single-a.php. So far so good. Now the rest gets a little tricky but it's not that difficult. Just take your time and reread everything as many times as you need to.
So far we have created 2 new php files for displaying individual posts and have altered the original single.php file so that it now is simply a conditional file telling WordPress which template file to use under certain conditions. We also have the style sheet - news.css - you created earlier. Since style sheets are called in header.php we need to create a new header.php file. Make a copy of your theme's header.php file and call it newsheader.php (once again I chose the name merely for the sake of organization) Open up newsheader.php and look for the call to the style sheet. It will look something like ...
<link rel="stylesheet" href="<php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
Replace it with this ...
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
Or, if you have already made the modifications to header.php that I mentioned earlier your newsheader.php will probably contain the following since it is an exact copy of header.php ...
<?php if ( is_category('X') ) { ?>
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
<?php } else { ?>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<?php } ?>
If newsheader.php contains the above simply delete it and again replace it with this ...
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
Now we go to single-b.php and at the top you will see <?php get_header(); ?> Replace that with <?php include ('newsheader.php'); ?>
What we have done is tell WordPress if we are on a single post page belonging to category X use single-b.php which contains a call to newsheader.php which in turn contains a call to news.css and if not use single-a.php


This would be perfect if I could use a category name rather than
If it is possible could you please email me a solution i would really appreciate that!
Sorry, scrap that! I decided to try it anyway using a category name and it works just fine! Thanks for that.
You're welcome Ryan.
Is there anyway you could adapt this, to display a different author.php, based on the author ID?
cheers
adam
That's a very good question Adam. Hmmm, I'd have to think about that. Off the top of my head I would think you'd first need to get the author ID then somehow use the template tag
the_author_metaMore reading on that particular template tag.