Update: For an update to this post, and more examples of complex conditional statements, read the new article Complex WordPress Conditional Tags
While re-aligning my website I realized I was writing a lot of redundant code. Some page templates were nearly exactly the same like the category and tags pages, the only difference was one word! Copying and pasting that one template seemed like a big waste of time, and it was.
I read somewhere that good programmers are lazy programmers. Not in the sense that they don’t fix their own code when they find a better way to do it…but that they don’t repeat code, over and over and over again. Not only does it take longer to repeat code, but it is a royal pain when you need to update(like when a CSS framework gets updated and drops a class name…).
Learn it right the first time
When learning to build themes the idea of template hierarchy got pounded into my head. I had template names floating around my head and had the idea that I needed to use them. All of them. Category, Tag, Author, Page, Archive, Home, Date, Search and all the rest of them. You don’t need to have a template for each, unless there are going to be major differences between them! That was a major point I missed when learning WordPress.
Conditional tags to the rescue
You’ve probably heard about conditional tags, used them, or seen them in other themes. I used them all along for things like dynamic titles, but somehow it escaped me to use them to make my life simpler. A conditional tag looks like this:
<?php
if (is_home()) { echo bloginfo('name'); }
That means if you are on the home page print the blogs name. You can use conditional tags for everything from adding content just for the owner of the site(edit post links) to finding out what category a post is in. Go here for a full list of tags.
A bit about the hierarchy
Pretty powerful little tool no doubt, but so far it looks like adding more code not less. Combine conditional tags with the template hierarchy and you will see what I am talking about. WordPress calls certain files by default. For instance, if you visit a single post WordPress will try to call single.php, if WordPress can’t find single.php it will call index.php. You can use this to your advantage!
Say you wanted to develop a theme for WordPress(good for you!). You design your theme and decide that your category, tag, monthly, and authors page are all going to look exactly the same except for the header. Instead of making a category.php, tag.php, date.php and author.php you are going to create archive.php. Why? Glad you asked, If WordPress doesn’t find any of those files it will automatically call archive.php. We’ll use conditional tags to call specific content based on what type of page it is. Lets look at some code!
<div class="content">
<h1>You are viewing the Archives
<?php if(have_posts()): while(have_posts()) : the_post(); ?>
<h2>
<p class="meta"> by
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
</div>
Theres a really basic archives template in all its glorious glory. But what if you are viewing an authors page? You don’t want to see “Viewing the Archives”, thats confusing to people(and you never want to confuse people, unless its a puzzle site). Lets stick a conditional tag in there to show the authors name at the top.
<div class="content">
<?php if (is_author()) { ?>
<h1>Posts Written By <?php the_author(); ?>
<?php } else (is_archive()) { ?>
<h1>You are viewing the Archives
<?php } ?>
<?php if(have_posts()): while(have_posts()) : the_post(); ?>
<h2>
<p class="meta"> by
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
</div>
Now when viewing an author page you will see “All Posts By The Dude” instead of “You are viewing the Archives”. This is just a basic if else php block which can be used to do all sorts of things(I suggest playing around with ideas). But what about all the other pages? We can use an if elseif else block:
<div class="content">
<?php if (is_author()) { ?>
<h1>Posts Written By <?php the_author(); ?>
<?php } elseif (is_category()) { ?>
<h1>You are viewing the <?php single_cat_title(); ?> category
<?php } else (is_archive()) { ?>
<h1>You are viewing the Archives
<?php } ?>
<?php if(have_posts()): while(have_posts()) : the_post(); ?>
<h2>
<p class="meta"> by
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
</div>
You can insert as many elseif statements as you need. For this example I would insert one for is_tag() and another for is_date(). Now you have five different headings and they clearly tell the user what they are looking at, and you only had to create one page!
You got homework
Sure now you don’t have to write as much code but don’t stop there. You can use this technique to dynamically show content depending on the type of page the user is looking at whether its a post, an about page, or the home page. Make custom layouts for pages or certain categories. Combine this technique with some basic php and make it even more powerful.
Note: These code examples wouldn’t actually work as the_author() has to be inside the loop. It can work, but thats another whole tutorial.Now go outside.
20 Comments
Leave a CommentThanks so much for this article. Very helpful. I do have one problem and that is that the is_search is not being recognized as true when I add a conditional for that. Just cannot figure out why.
Well, I lied, I have two problems. I used the line for “is_author”, and that is recognized, and I get the “Posts Written by”, but it will not show the author name.
12th Sep 2008
Mark,
Not sure why is_search wouldn’t work. Are you using it in search.php? Can you post some of the code, or email it me.
There is a mistake in the code above I never caught. the_author() has to be used inside the loop. See the Codex Author Page on how to do it outside the loop.
Or you can just look at the Checkmate code to see it in action. Line 6 to 23.
Looks like I need to update this tutorial as they have added some more conditional statements in the newest WordPress release.
12th Sep 2008
I need help grasping the conditional tag concept. I want different categories to show in the sub navbar of my theme on different pages. So far I have come this far, but I’m stuck at understanding the navbar code to use. Do you think you could explain this further or show me what those codes should look like?
5th Nov 2008
vb,
So you have categories showing in the sub nav bar?
The conditional code will replace what you currently have controlling the sub navigation.
Example: You have two pages, one for xbox games and one for playstation games.
<php
if ( is_page('Xbox Games') ) {
wp_list_categories('child_of=1') }
elseif ( is_page('Playstation') ) {
wp_list_categories('include=2,3,4') }
?>
This code will list any category that is a child of the category with an id of 1 on the Xbox Games page. On the Playstation page it will list only the categories with an id of 2,3, and 4. This is just two different ways of listing categories and you can use whichever works for you.
7th Nov 2008
Thank you very much for your help Curtis. Your example helped me understand conditional tag concept.
I appreciate your help. Thanks again.
7th Nov 2008
Looking for a conditional tag to display sub-categories of a particular category so they can be displayed in a different template. I have this but it doesn’t get the children or sub-cats.
if (is_category(‘blog’)){
include(TEMPLATEPATH.’/theblog.php’);
}
else … ( i am using the else to display everything else in another template)
this works fine but I can’t seem to find a way to target the subcatagories.
Like:
if (is_category(‘child_of=4′)){
include(TEMPLATEPATH.’/theblog.php’);
}
any ideas? Thanks!
19th Apr 2009
There’s two ways you could do it:
First is to pass an array to it, this will work if you know the categories that need to be displayed, and they aren’t going to change.
if(is_category(array(1,2,3,'category_name')){
//do stuff
}
Second is to grab the children then pass them to is_category. Something like this:
$cats = wp_list_categories('child_of=4&echo=0');
if(is_category(array($cats)){
//do stuff
}
19th Apr 2009
Thanks for the reply… the second one is what I am after but can’y seem to get it to work. here is my code:
// if category name is blog then do this
if (is_category('blog')){
include(TEMPLATEPATH.'/theblog.php');
}
$cats = wp_list_categories('child_of=4&echo=0');
else if(is_category(array($cats)){
include(TEMPLATEPATH.'/theblog.php');
}
else {
// all others do this
include(TEMPLATEPATH.'/all-categories.php');
}
Did I mess something up?
thanks again… appreciate the help.
20th Apr 2009
Mark,
I did some testing and it turned out to be more complicated than I thought. This should work:
$cats = get_categories('child_of=4');
foreach ($cats as $cat){
$cats_array[] = $cat->cat_ID;
}
if ( is_category($cats_array) ) {
//do stuff
}
20th Apr 2009
Thanks Curtis,
I will give it a try when I get home.
And again, I appreciate the help.
20th Apr 2009
Works Perfectly!
thanks!
20th Apr 2009
Oh This is good for me. Thank
29th May 2009
if i want to create 3 child category… how is the script ???
1st Jun 2009
Just find out, that is will not work when child of the category more than one.
1st Jun 2009
I’m not sure what you are asking for.
1st Jun 2009
Botakedan is true. The code didn’t work when you have more than one child category.
I would like display several child categories with the same template. For example, all the categories which are children of the category X have the same template.
Do you have an idea of how it can work ?
17th Sep 2009
Mathilde,
What you want to use is probably in_category() instead of is_category() and pass the ID of category X to in_category.
You can see an example at the bottom of the follow up post Complex Conditionals
17th Sep 2009