9 Ways to Set Dynamic Body IDs via PHP and WordPress

by Jeff Starr on Tuesday, May 26, 2009 39 Responses

When designing sites, it is often useful to identify different pages by adding an ID attribute to the <body> element. Commonly, the name of the page is used as the attribute value, for example:

<body id="about">

In this case, “about” would be the body ID for the “About” page, which would be named something like “about.php”. Likewise, other pages would have unique IDs as well, for example:

<body id="archive">
<body id="contact">
<body id="subscribe">
<body id="portfolio">

..again, with each ID associated with the name of the page. This identification strategy is useful for a variety of reasons, including the following:

  • Page-specific control over CSS via descendant selectors
  • Page-specific DOM manipulation via JavaScript
  • Page-specific control over the navigational interface, current-page highlighting et al
  • Page-specific content-inclusion via conditional PHP if() statements

For page-specific control over your design, using the current page name as the body ID will certainly do the trick. The question is, what is the best way to go about defining the different attributes? For static sites or for sites with only a few pages, it might be easiest to just add the IDs manually. For larger, dynamic sites, however, you can automate the process with the magical powers of PHP.

The basic idea is simple: use PHP to dynamically check the URL, extract the file name, and echo the name as the body ID for that specific page. The cool thing is that, once the page name is captured as a PHP variable, it can be tested conditionally to include or exclude page-specific content. This is a great way to consolidate and streamline content into a single file.

There are probably a million different ways to accomplish this sort of functionality, but I am only familiar with about nine different techniques, which actually do pretty much the same basic thing only in different ways. Even so, I apply body IDs for page-specific CSS styling all the time, and have refined my collection of PHP snippets to include the following nine ways of getting it done. Enjoy!

Method 1

This method captures the requested URI as a $page variable and then strips out everything except for the file name. The $page variable is then echoed as the ID attribute for the body element.

<?php 
$page = $_SERVER['REQUEST_URI']; 
$page = str_replace('/', '', $page); 
$page = str_replace('.php', '', $page); 
$page = str_replace('?s=', '', $page); 
$page = $page ? $page : 'default'; 
?>

<body id="<?php echo $page ?>">

Method 2

This variation streamlines the syntax of the previous method by using an array for the str_replace() function. I’m sure there is an even more efficient way of writing this, so speak up if you happen to know of one.

<?php 
$page = str_replace(array('/', '.php', '?s='), '', $_SERVER['REQUEST_URI']); 
$page = $page ? $page : 'default'; 
?>

<body id="<?php echo $page ?>">

Method 3

This method cuts to the chase by echoing the name of the PHP file directly (after removing the “.php” extension). I use this technique in my dark n’ minimalist Perishable theme (opens new tab). Note the convenient shortcut syntax for echo() for greater efficiency.

<body id="<?=basename($_SERVER['PHP_SELF'],'.php')?>">

Method 4

If I remember correctly, I discovered this technique from one of Chris Coyier’s excellent screencasts. I had to squint hard and type fast to catch it, but the code works great and I love having it at my disposal. The cool thing about this technique is that it echoes the name of the first-level directory and discards any subsequent directory information. Thanks Chris! :)

<?php 
$url = explode('/', $_SERVER['REQUEST_URI']); 
$dir = $url[1] ? $url[1] : 'home'; 
?>

<body id="<?php echo $dir ?>">

Method 5

Here is a more versatile method that I learned from Trevor Davis. The benefit of this technique is that it enables you to specify the same body ID for multiple pages. The script captures the requested URI as a $path variable and then pattern-matches against user-defined character strings to determine its value. You could even adapt this script to set variables according to an entire range of pages.

<?php
function setBodyId() {

    $path = $_SERVER['REQUEST_URI'];

    if(!isset($bodyId)) {

		if(eregi('^/about/', $path) == 1) {

			$bodyId = 'about';

		} elseif(eregi('^/archive/', $path) == 1) {

			$bodyId = 'archive';

		} elseif(eregi('^/contact/', $path) == 1) {

			$bodyId = 'contact';

		} elseif(eregi('^/business/', $path) == 1) {

			$bodyId = 'business';

		} elseif(eregi('^/pleasure/', $path) == 1) {

			$bodyId = 'pleasure';

		} elseif ($path == '') {

			$bodyId = 'home';

		} else {

			$bodyId = 'default';
		}
	}
	return $bodyId;
}
$bodyId = SetBodyId();
?>

<body id="<?=$bodyId;?>">

Earlier I discussed the idea of using the page-specific body ID to include conditional content. Here we may see an example of this technique by using the $bodyId variable from Trevor’s script:

<?php if($bodyId == 'home') {

// content placed here will only appear on the home page

} ?>

Method 6: WordPress

Moving on to WordPress-specific methods, here is a technique that Elliot Jay Stocks adapted from Darren Hoyt. The idea here is to take advantage of WordPress’ conditional tags in order to output the desired <body> ID:

<?php if (is_home()) { ?>

	<body id="home">

<?php } elseif (is_archive) { ?>

	<body id="archive">

<?php } else { ?>

	<body class="<?php echo $post->post_name; ?>">

<?php } ?>

Notice how this technique cleverly outputs the post_name variable for pages without an ID. This method certainly is useful, and there is much more that may be done with it.

Method 7: WordPress

Taking the conditional-tag method further, shows us how to expand the script and clean things up by placing it the functions.php file:

<?php // dynamic body IDs

function dynamicBodyID() {

	if (is_home()) {

		echo ' id="home"';

	} elseif (is_single()) {

		echo ' id="single"';

	} elseif (is_search()) {

		echo ' id="search"';

	} elseif (is_archive()) {

		echo ' id="archive"';
	}
}
?>

This function is then called via the following code placed in your theme template:

<body<?php dynamicBodyID(); ?>>

Then, as with method #6, we may modify this technique to add a post-specific class to every single post page:

<?php // dynamic body IDs

function mytheme_body_control() {

	global $post; 
	$postclass = $post->post_name;
 
	if (is_home()) {

		echo ' id="home"';

	} elseif (is_single()) {

		echo ' id="single" class="'.$postclass.'"';

	} elseif (is_search()) {

		echo ' id="search"';

	} elseif (is_archive()) {

		echo ' id="archive"';
	}
}
?>

And once again, this function is then called via the following code placed in your theme template:

<body<?php dynamicBodyID(); ?>>

Method 8: WordPress

Here is a WordPress method that echoes the name of the parent page as the <body> ID, regardless of whether or not the page is a sub-page (or child-page). As we have seen, we can echo the name of any post or page via the following code:

<body id="<?php echo $post->post_name; ?>">

However, for pages that are children of parent pages, this snippet will echo the name of the child page instead of the name of the parent page, which may be more useful for the purposes of CSS styling. Fortunately, we may find a solution for this via plaintxt.org’s’s excellent Sandbox Theme for WordPress:

<?php
	$current_page = $post->ID;
	$parent = 1;

	while($parent) {
		$page_query = $wpdb->get_row("SELECT post_name, post_parent FROM $wpdb->posts WHERE ID = '$current_page'");
		$parent = $current_page = $page_query->post_parent;
		if(!$parent) $parent_name = $page_query->post_name;
	}
?>

This code would then be followed by this line of code:

<body id="<?php echo (is_page()) ? "$parent_name" : ((is_home()) ? "blog" : ((is_search()) ? "other" : ((is_single()) ? "blog" : "blog"))); ?>">

That is all well and good for current versions of WordPress, but as we will see in the next example, the soon-to-be-released WordPress 2.8 includes a built-in method for applying page-specific body IDs that simplifies the process to the point of absurdity!

Method 9: WordPress

Those of you who keep up with the relentless evolution of WordPress certainly have heard about the new body_class() tag that is due out in version 2.8. As WPengineer points out, by simply including this in the <body> element:

<body <?php body_class(); ?>>

..you get something like this in your source-code output:

<body class="page-template page-template-tutorial-php logged-in">

Pure awesome-ness. Here is a list of the available classes for the new body_class() tag:

  • rtl
  • home
  • blog
  • archive
  • date
  • search
  • paged
  • attachment
  • error404
  • single postid-(id)
  • attachmentid-(id)
  • attachment-(mime-type)
  • author
  • author-(user_nicename)
  • category
  • category-(slug)
  • tag
  • tag-(slug)
  • page-parent
  • page-child parent-pageid-(id)
  • page-template page-template-(template file name)
  • search-results
  • search-no-results
  • logged-in
  • paged-(page number)
  • single-paged-(page number)
  • page-paged-(page number)
  • category-paged-(page number)
  • tag-paged-(page number)
  • date-paged-(page number)
  • author-paged-(page number)
  • search-paged-(page number)

Obligatory Hendrix Perm

The best part about running a personal, non-commercial blog such as Perishable Press is that I get to do and say whatever I want. I usually play it straight, sticking to the script and focusing on the topic at hand, but every now and then, I just gotsta exercise my right to cut loose and have a little fun. So today, instead of another boring and predictable article summary, I thought I would wrap things up with an obligatory nod to a song from my favorite band. Take that, sleepwalkers! ;)

About the author

[ Jeff Starr ]

Jeff Starr is a web developer, graphic designer and content producer with over 10 years of experience and a passion for quality and detail. Jeff is co-author of the book Digging into WordPress and strives to help people be the best they can be on the Web. + Follow Jeff on Twitter and subscribe to Perishable Press for quality web-design content delivered fresh.


39 Responses
[ Gravatar Icon ]

Patternhead#1

Great roundup. Sure this will come in handy so thanks for sharing.

Oh, and I see you’re a Pink Floyd fan :D

[ Gravatar Icon ]

The Frosty @WPCult#2

Very nice, good for extra CSS styling!

[ Gravatar Icon ]

Jeff Starr#3

@Patternhead: Yes! Floyd rulez!! :)

@The Frosty: Absolutely! And for JavaScript stuff as well =)

[ Gravatar Icon ]

Judd Lyon#4

Body classes are such a must, they always come in handy. Thanks for such an exhaustive list. This site rocks.

FWIW, if any of the fine folks who read this site use ExpressionEngine, there is a plugin called classEE body that does this very thing.

[ Gravatar Icon ]

Jessi Hance#5

Jeff, you’ve done it again! I don’t usually go for lists of n this or that, but you knowing 9 ways to do this qualifies you as a wizard in my book. Looking forward to the new WP tag, which I hadn’t known about.

And I thought I was the only one pausing, squinting and transcribing stuff from one of Chris Coyier’s videos!

[ Gravatar Icon ]

Chris Coyier#6

Cripes you are some kind of crazy mad scientist =)

I’ve always been a method four kinda guy but it’s so generic and doesn’t leverage any WordPress smarts. I’m thinking method seven is the sexiest.

[ Gravatar Icon ]

Nihar#7

Great post again…

I saw in my previous theme there was id attribute for body tag, but didn’t know whats the purpose of it. NOw i know it and also know how to generate dynamically.

[ Gravatar Icon ]

Jeff Starr#8

@Judd: Thanks for the tip on the classEE plugin for Expression Engine — will have to keep that one in mind. ;)

@Jessi: Yes, the new WordPress body_class() tag is going to be a real treat for designers. I can’t wait to dissect it and apply it to older versions of WordPress via functions.php!

@Chris: Crazy and mad perhaps, but scientist is certainly questionable ;) Actually, your screencast was the catalyst for this entire article — I started out with a few of these tricks sitting around, then saw your screencast and just had to do it. So it’s all your fault :)

@Nihar: Yes indeed, you may also want to look into your theme’s CSS or JS file(s) and see exactly how the various body IDs are being used. Could be for lists, links, or just about anything, really.

[ Gravatar Icon ]

weston#9

holy awesomeness method nine!

I just finished a project today and had no idea that was possible.

That is a real wordpress gem, thanks!

[ Gravatar Icon ]

carlnunes#10

I currently use Method 1.

Six months prior to your post, Chris over at css-tricks.com posted a screencast detailing some similar tips:

Current Nav Highlighting: Using PHP to Set the Body ID
http://css-tricks.com/video-screencasts/36-current-nav-highlighting-using-php-to-set-the-body-id/

and at about 11:33 into the screencast Chris give’s me credit for the find. Credit goes to Chris; I, working off one of Chris’s tutorials, discovered the “?s=” missing from his current str_replace set.

[ Gravatar Icon ]

Jeff Starr#11

@carlnunes: Yes that screencast is full of good stuff. I link to it in Method #4, but apparently got the credit links mixed up during the creation of the post (I try to give proper credit for each method). Thanks for setting the record straight, and thanks for helping to improve the technique with the addition of the “?s=”. Cheers :)

[ Gravatar Icon ]

Lewis Litanzios#12

I like the fact everyone raves about the body_class(), but nobody explains how to actually use if with conditionals (hint hint).

L

[ Gravatar Icon ]

Jeff Starr#13

@Lewis Litanzios, That’s actually a great idea and something that I have been mulling over in my head regarding the best way to go about writing up a useful article. Thanks for the inspiration ;)

[ Gravatar Icon ]

Lewis Litanzios#14

I ended up going 400+ lines deep into my post-template with the following:

// controls body class background colours
if ($pageID == 7 || $wp_query->post->post_parent == 7){
       $classes[] = 'fmcg';
}
if ($pageID == 8 || $wp_query->post->post_parent == 8){
       $classes[] = 'corp';
}

… but it’s a complete botch job :Z

This subject really does need to be ironed out, cause there’s NOTHING online about it, let alone in the WP Codex for 2.8 yet.

Most designers are raving about doing it all with CSS, but this isn’t what I call efficient:

.category-advertising-corp{ background-color:#71919e;}
.category-branding-strategy-design-corp{ background-color:#71919e;}
.category-brochures-corp{ background-color:#71919e;}
.category-core-creative-corp{ background-color:#71919e;}
.category-events-corp{ background-color:#71919e;}
.category-instore-corp{ background-color:#71919e;}
.category-packaging-corp{ background-color:#71919e;}
.category-web-new-media-corp{ background-color:#71919e;}

Ta mate - let me know what you make of it (@ldexterldesign).
L

[ Gravatar Icon ]

Lewis Litanzios#15

F*ck it:

body[class*="fmcg"] #s
body[class*="corp"] #s
- A combination of CSS and greeeeeezy category naming to the rescue :]

Do let me know if you get on with the body_class() conditional logic thing. I will stay tuned.

Thanks,
L

[ Gravatar Icon ]

Jeff Starr#16

Hi Lewis, I think there is a way to do this using PHP’s output buffering functionality. I will play around with it this weekend and try to get something posted soon.
Cheers,
- Jeff

[ Gravatar Icon ]

Lewis Litanzios#17

Cool, rather you than me. Post up if you get something working.

Cheers,
L

[ Gravatar Icon ]

Jeff Starr#18

@Lewis: Here you go:

http://digwp.com/2009/08/wordpress-body-class-plus/

Thanks for the idea! :)

[ Gravatar Icon ]

paul#19

thanks for the WP 2.8 body_class function, a real life saver!
I enjoy reading your articles, they are always very well written and exhaustive.

keep up the good work

and this psychedelic background :-)

[ Gravatar Icon ]

Jeff Starr#20

@paul: My pleasure! Thanks for the feedback :)

[ Gravatar Icon ]

Steve Coates#21

Great article, thanks. Wasn’t aware of the new body_class() tag with WP2.8. I’ve used Sandbox for ages for the ease it allows with styling by adding all that goodness to the body tag.

Nearly tempted to move to using the native wordpress tag but on experimentation it doesn’t add any category info (id or name) to the body tag on single posts which is a major limitation if you’re trying to style things based on category.

[ Gravatar Icon ]

Jeff Starr#22

@Steve: Yes, but there are always conditional tags to help with that. For example:

<body<?php if(is_category('33')) { echo ' class="whatever"'; } ?>

But I’ll admit, this method is a bit tedious and not as elegant. Have you checked out my body_class_plus() plugin?

http://digwp.com/2009/08/wordpress-body-class-plus/

It is pretty flexible, and there may be a way to implement custom category classes.

[ Gravatar Icon ]

Steve Coates#23

Thanks Jeff,

WIll check it out.

[ Gravatar Icon ]

Nik#24

you are amazing. thank you for writing this.

[ Gravatar Icon ]

Jermaine#25

Thanks for this, it came in very usefull today at work

[ Gravatar Icon ]

NeoSting#26

Very useful. I was looking for différent méthods, but before, i had in mind to use the Wordpress one, the 6th you show. But after reading your very good post, i am now decided to use the 7th, a little bit better. I think it is probably good enough for what it has to do.

[ Gravatar Icon ]

SohoInteractive#27

nice trick.
thanks for sharing.

[ Gravatar Icon ]

darrinb#28

Thanks for all the different ways you listed! I recently wrote a function that addresses this very thing for WordPress sites utilizing WP’s Conditional Tags and placing everything in the functions.php file. I figured I’d share it since this was one of the few articles I came across while doing research on the subject.

http://darrinb.com/notes/2010/add-a-custom-id-to-the-body-element-in-wordpress/

[ Gravatar Icon ]

Bobbie Barginear#29

You would not believe how long ive been searching for something like this. Scrolled through 8 pages of Yahoo results and couldnt find anything. First page of bing. There was this…. Really gotta start using that more often Thank you.

Trackbacks / Pingbacks
  1. Links for May 27th | jonathan stegall: creative tension
  2. 9 Ways to Set Dynamic Body IDs via PHP and WordPress | Design Newz
  3. WordPress 2.8 and the body_class() Function — Nathan Rice
  4. Extensive Wordpress 2.8 Getting Started Guide | tripwire magazine
  5. New And Comprehensive Wordpress 2.8 Tutorial and Hack Toolbox | Graphic and Web Design Blog - Inspiration, Resources and Tools
  6. New And Comprehensive Wordpress 2.8 Tutorial and Hack Toolbox - Programming Blog
  7. Wordpress 2.8 tricks and hacks | Word-ex-press
  8. Advanced WordPress Targeting with body_class_plus()
  9. darrinb.com | adding a custom id to the body element in wordpress
  10. How to Style Individual Wordpress Posts in Seconds
Comments are closed for this post

If you have or need further information, contact me.



Attention: Do NOT follow this link!