Sam Brown
February 23rd 2008 @ 3:00 pm #
Cool technique, I may have to convert it for use in my CMS of choice Textpattern.
Are you still using TextMate to code your sites?

I spent most of yesterday building a site for a friend and found myself falling in love with Wordpress all over again in the process. A highlight of the day's work (which saw me using Wordpress more as a standard CMS rather than a blog engine) was finding a really easy way of dynamically applying a class or ID to the <body> tag.
Now, I'm not a PHP guy at all, so I like to use it in the simplest way possible to get the results I need, and - in my limited knowledge of the language - I've found this to be one of the easiest tricks that can potentially lead to some really powerful stuff. If you're going to apply a class name dynamically, you might as well do it to the <body>, because - thanks to CSS' descendant selectors - you can pretty much alter anything on the page, as everything sits inside this tag.
What I wanted to do was give each page on the site a unique class so that I could reference it in my CSS (important for hover / selected states when using sprite-based navigation). I'd actually been doing it for ages - but in a very long, round-the-houses fashion - by checking each page's ID number and then assigning styles where necessary. It's not bad but I hated all that styling sitting in header.php when I wanted to keep every bit of CSS in my stylesheet. It was just plain messy.
A quick Google search for wordpress dynamic body class brings up an article on Scott Allan Wallick's site that talks about his excellent Sandbox theme. While all well and good, I wasn't using Sandbox on this project so I wanted something I could easily put into my own theme (based on Starkers). I then found a post by Darren Hoyt that seemed to detail the technique I wanted. I pasted in the code and it worked like a dream.
PHP only really looks neat if you adhere to the line breaks (as Darren does), but that made lots of unnecessary whitespace when the values were printed to the page... and that makes a pedantic loser like me very unsettled. :p Plus the extra code dealt with adding both a class and an ID, as well as checking if the page was an 'interior' one or not. I didn't need anything like this complexity, so I re-ordered the code for exactly what I was after.
<?php if (is_home()) { ?>
<body class="news"> <!-- The default body class is "news" -->
<?php } else { ?>
<body class="<?php echo $post->post_name; ?>"> <!-- An alternative body class is defined, based on the page title -->
<?php } ?>
In English: if the page is the 'home' page, the first option is printed; if the page is anything other than 'home', it's given a class based on the page slug. In the site I was building, that meant things like "films", "about", "links", etc; in other words, simple, semantic class names.
Note: In this case I'm writing a class but you could equally use it to create an ID. Similarly, with two 'options', you could include more stuff within the <body> tag if you wanted. For instance, you could print an ID as well as a class and then reference the ID in your CSS to override other styles, like so:
<?php if (is_home()) { ?>
<body id="overrideEverything" class="news"> <!-- The default body class is "news" -->
<?php } else { ?>
<body class="<?php echo $post->post_name; ?>"> <!-- An alternative body class is defined, based on the page title -->
<?php } ?>
<style>
body#overrideEverything p { color:red }
</style>
In fact, there are loads of things you can do with this very simple bit of code. Like I say, I'm no PHP expert, so if you know of an easier way to do this, please feel free to share. It was just one of many things I learned yesterday that I know I'll be using again and again in the future. I hope it helps you too!
This is a fantastic tutorial Elliot and opens up a whole new bunch of opportunities. I too have started using WordPress again recently and also have a couple of websites I am builidng for a client with WordPress as the CMS engine to keep costs down. Sure this method will come in handy.
When you make sites for friends or smaller sized sites in general, maybe you fall in love with the very good cms called symphony (http://www.symphony21.com).
I'm also a newby to it, but after a day you can do all the basic xml/xslt-stuff to create very dynamic pages with a beautiful backend. My first project with symphony was this. I created the page about a year ago by hand with my own crappy php-solution. A week ago I adapted it to symphony in about two days.
I never did a wordpress theme, but everytime I looked at the themes they seemed to me very complex and hard to handle, which is far more easy in symphony.
A css-class for every section of a site would be the code of:
body class="{$current-page}"
which is really cool.
I like it. Keeps things well organized and easily extensible. Could you utilize this technique with calling multiple style sheets to only load the styles you need for the page? So you'd have a general style sheet for consistent elements, and then load page-based styles as needed, again based on filename.
thanks for the post, Elliot ;)
very much into WordPress myself at the moment - just got to love it :)
will have a go at using your technique in my next project - thanks for sharing :)
PS: and thanks again for your starker's theme - saving me loads of time these days :)
Another way to tackle this is through the use of custom page templates. If you're just changing one item, like adding a body class, your method is neater and quicker. But if find yourself in a situation where you want to do a few things to individualize a page (one I recently did included different sidebar content for each page, for example), you can create a custom page template for it.
Essentially, what you do is take the normal page template, make the changes you need to, add save it with another name (like page-film.php and page-links.php, etc.) You need to include this code at the top:
(See here.)
Then, when you're writing the page's content, open the Page Template bar on the right side of the edit screen and choose the appropriate template from the list. The templates can be used over and over if your site calls for it; for example, if you create a special page template for Personnel or somesuch, you could have each person have their own page, each using the Personnel template.
Like I said, this may be overkill if you only want to add a class or something like that, but it's awesome for fine-tuned control when you need a certain page or pages to have individualized content. Super powerful!
I find myself using WP's conditional tags more and more these days. They come in super handy for doing things like setting the current state for nav items and displaying unique content depending on the page you're on.
As Laura mentioned, page templates are great when you're making significant changes, but conditional tags do the job when you're changing minor details.
I did some pretty crazy stuff with the Graphics.net redesign, where I used WP posts for nearly every bit of content on the site, and specified unique content for different pages using conditionals. Here's how I set the active state of the "blog" tab if you're on the blog page, on a subpage of /blog, viewing an author archive, viewing a category archive, or viewing a post that's in the blog category...
if (is_page('5') || is_child('5') || is_author() || is_category() || in_category('7') && is_single()) : echo " id=\"current\""; endif;
Phew! For the PHP n00bs, the || equals "or", while && equals "and" - handy if you need to specify more than one condition... like being a post and in a certain category as I've done here.
Anyway, there's tons you can do with conditionals, and I have a feeling you're going to start using them more frequently.
I'm a huge advocate of WordPress too - most website requirements I get on quick freelance projects manage to fit around the WordPress platform, if only for the standard CMS system.
I also used a very similar technique on a recent website for some friends running for charity called ELF Runners (donations are still welcome!). The main difference for me though was to apply the page slug to the body class so I had an easy handle on all the pages (and was very specific).
Maybe I should create a quick write up like yourself...
Hi,
Great Post its really helpful.
I'm Donna and I'm new in wordpress and I just want to know in this part of your page "Speaking engagements" are the content dynamic? I hope you'll answer this and what technique do you use?
Thank Elliot and more power!
Thanks for the mention, Elliot (and good luck post-Carsonified, btw!). I like what you did to tweak the code.
Plus the extra code dealt with adding both a class and an ID, as well as checking if the page was an ‘interior’ one or not. I didn’t need anything like this complexity
Re: that extra code, it's just a product of how I typically design sites -- the homepage has a distinct layout, while all interior pages tend to share a layout, so #home and #interior provide hooks for the CSS to edit things like masthead height, column size, and so on. This provides a ton of control and allows me to recycle classes like ".masthead" according to their context rather than creating bloated new ones like ".home-masthead" and ".interior-masthead".
Then with the dynamic body class, you get additional granularity when you want to tweak specific elements on some pages and not others (just as you were saying):
body.about-us h2 {
color:red}
body.contact-us h2 {
color:blue
}
Hope that makes sense, I seem to have an easier time coding this stuff than articulating it well ;)
Another way to tackle this is through the use of custom page templates.
I'd warn against using them too often as it bloats the theme and reduces your ability to make global changes. The various ways of deploying WP conditionals ultimately make your templates 'smarter' and less numerous.
I use a very similar piece of code on the Hunter Island Press Inc site -
http://hunterislandpress.org.au.
The news section (or blog) is a sub-section of the site. So a special template is used on the home page.
So in header.php I simply have a php if else statement that says
if(!is_page()) {
// then the body = News
} else {
// then the body id = the_title();
}
So on normal pages on the site the id is for a page but anywhere in the news section (search, categories, single) the id stays News.
Its a handy little way of isolating the news section entirely for a little special treatment - perhaps a subtle colour as an ambient signifier.
Cheers for the comments, guys and gals...
@ Sam Brown: Yep, I'm still using TextMate. I love it!
@ Mark: Thanks for the Symphony link - it looks pretty impressive. Beautifully designed admin section, too! I must admit that so far it doesn't look like it can do anything WP cannot, but I may well look into this when I get the time (and it'd be a good excuse to get up-to-speed with XSLT).
@ Brian Cobb: Not as far as I know, I'm afraid.
@ Laura & Hamish M: You're right; using custom page templates means lots of flexibility, although I second Darren Hoyt's comment about page templates causing unnecessary theme bloating. For instance (and this isn't best practice at all but just as an off-the-cuff example), you could use the following CSS to hide or display content and just one single page template:
body.pageIsNormal div.sidebarOne { display:block }
body.pageIsNormal div.sidebarTwo { display:none }
body.pageIsSpecial div.sidebarOne { display:none }
body.pageIsSpecial div.sidebarTwo { display:block }
@ Matt Brett: Thanks for sharing the tips about conditional comments - this is really useful stuff. In fact I can think of a project I can use that code in straight away! Might IM you later about it...
@ Donna: I'm afraid the 'speaking engagements' links are actually hard-coded. They'll be dynamic in the next version of the site, though, so I'll be sure to do a write-up.
@ Darren Hoyt: Thanks! And yeah, the interior thing makes a lot of sense. I hope you don't think I was criticising your code! :)
@ Steven Clark: I've just been reading your post on the subject, and I have to say I think your method is excellent, especially in the way that it applies a dynamic id only to certain pre-specified pages.
I hope you don’t think I was criticising your code!
Not at all - just didn't want anyone confused as to what the sweet hell "interior" was supposed to mean ;) Just one of those naming conventions that's evolved over the years.
I have used a similar technique to apply different headers to a page. I had a flash header for the home page, but I didn't want the flash header to be on ever page. I used very similar code to tell which div the page should use for the header. It really is a wonderful little tool.
I want to adapt Wordpress into a real CMS next. Something along these lines would come in handy. I was also thinking to modify this to something like:
<body id="<?php the_title() ?>"
and
<link rel="stylesheet" href="path/to/theme/<?php the_title() ?>.css" type="text/css" media="screen">
Doing that you could easily add header specific images, optional colors for each page and current page navigation with the same php mod.
<li><a href="/about" class="<?php the_title() ?>">About</a></li>
body#About a:link.About { active state; }
Of course a base style sheet is stil there, the page specific ones would just have the necessary overrides.
I learn more and more about PHP everyday and readin posts like this and experimenting with Wordpress goes along way.
Elliot,
Your code snippets are unfortunate victims of an IE bug (Firefox and Opera render them correctly, of course). There is an unnecessary vertical scrollbar, which is distracting. If you feel so inclined, I have a fix for the problem.
Best regards...
Mmmm great read and some good food for thought.
I have a new website that this will be good for. I had wanted this feature for a previous website but left it alone but not know.
What I love about WordPress is that when you think you know everything, bam comes a new idea/ Plugin/ way of doing things and blows your preconceive ideas out the window!
Please keep these ideas etc coming...
Nice little bit of code. I just dropped it into the header of a project for a new client. I'm taking your "Starkers" theme for a spin as well. I love the dynamic body class idea. Sandbox handles it very well, but it's extremely heavy code-wise. I used it as the basis of my own site and was able to add nifty "placecards" using the dynamic class that change depending on the type of page the reader is on.
The current project just doesn't need that level of detail, but this code is mighty compact. It'll help a lot.
This is great : ) It may just be the thing I've been looking for to pull off the layout for my blog. Cheers Elliot!
I'm coming to this one a bit late, but here's another take.
I have a lot of different templates for my site, but the opening CONTENT div is specified in the header.php. To get different classes in there, I set a global variable in my template file and simply echo this in my header.php.
So, in your template at the top, you'll have something like this:
<?php
global $contentClass;
$contentClass = "wide";
get_header();
?>
In your header.php, you set the global variable anywhere in a php code block, but before you need to use it:
<?php
global $contentClass;
?>
Then in your header, after that global variable is called, your HTML block would be something like this:
<div id="content" class="<?php echo $contentClass;?>">
Works great and means I only need to set the class on templates that need it. Anything else will just leave the class on the content div empty.
I want to thank you.
I was looking for a way to use conditional tags to change the state in which my head navigation displayed. I am using the tags to change the background state of the image to show the page it is currently on.
Cheers,
Frosty
Frosty Web Designs
Glad you're finding this useful, guys. And thanks for posting your own tips too - all very handy!
isnt there is such thing as 'dynamic menu highlighting' in the wp codex ?
Awesome ideas! Thanks for sharing! I intend to use this for my new wedding photography blog that uses WordPress. I used to use Blogger...not as fun.
You rock,
Lawrence
@ Matt Brett: You don't know how much time you saved me with your comments about && and || . I didn't know you could in_category('9') && is_single().
Many thanks
Karl
Recent Comments: