Adding conditional headers in WordPress
While working on a project recently, the client wanted to display a custom header graphic for a specific ection of their site. This was complicated by the fact that there were a few places where the header needed to be changed; a static page that's used as a landing page for the content, the category archive page and the single page for each blog post.
So I did what I typically do in these situations, I hit up Google. What I found was several tutorials on conditional headers, but most of them were either VERY outdated, or, they were centered around the idea of using the featured image from a page or post as the header. This wasn't going to work as the site was already using the featured image on posts for display in other areas. So instead I decided to use the add_filter function to display an extra bit of CSS on the proper pages.
The site's style.css file contains the following:
#header {
background: url(images/header.png) no-repeat;
height: 120px;
width: 920px;
}
The project was to change the header any time we were on the sports page, on the sports category archive page, or any time we were on a single blog post page where the post had been added to the sports category. Here's how I did it:
In the theme's functions.php file, I added the following snippet of code:
add_filter( 'wp_head', 'conditional_header_sports' );
function conditional_header_sports() {
if ((in_category( 'sports' ) || is_page( 'sports' )) && !is_home()){
?>
In the example, I'm checking for a few things:
- in_category( 'category_name' ) : This will be TRUE on both the category archive and for any single blog post page where the content has been added to the specified category.
- is_page( 'page_name' ) : This will be TRUE on the page with the specified name.
- !is_home() : Since there is content displaying on the home page from the selected category, prior to adding !is_home(), I was running in to issues where the home page was returning TRUE and displaying the alternate header. Adding the !is_home() confirms that we will use the default header on the home page.
So, as long as EITHER of the first two checks was true and as long as we weren't on the home page, our custom function will be called. When it's called, it's going to display the CSS code needed to override the default header background with the custom background for the sports section.
For my project I only needed to work with the is_category() and is_page() functions, but, WordPress has a bunch more conditional tags you can use to target specific content.
Happy Customizing!
[POST UPDATE!]
After writing this post, I received a comment and a tweet suggesting that this could be done using the body_class() function. So I did a little research, and sure enough. So, here's a second solution for the same problem.
To start, in your template file, make sure the header call looks like this:
>
This will add extra information to the
tag. For example, a single post page's body tag will look like this:
Unfortunately, this wasn't enough info to cover all my requirements. Until I found out you can modify the information that gets added to that body class. on the WordPress codex entry for body_class(), I found this chunk of code:
function category_id_class($classes) {
global $post;
foreach((get_the_category($post->ID)) as $category)
$classes[] = $category->category_nicename;
return $classes;
}
add_filter('body_class', 'category_id_class');
I added that to the functions.php file and that updated the body tag to look like this:
The last few items on that list, 'sports-2' and 'featured-content', are the slugs for the categories this post was in. I now had enough information in the body tag to cover all my bases.
The next step was to add CSS code to cover each case. That code ended up looking like this:
body.page-id-12345 #header, body.sports-2 #header {
background: url(images/header-sports.jpg) no-repeat;
}
In the future, if the client wants to update new sections with custom headers, the steps are pretty simple; grab the page id, the category slug, upload the header graphic and add a new css block to the style sheet. Simple.