Child Themes, the Template Hierarchy, and One Great Little Hack

Tetris wood

(Click to go straight to the hack »)

Here at WPShout, we’re big fans of child themes. The very simple version of a child theme is that it’s a way you can quickly make a theme that “inherits” from another. They’re great because they let you own only what you need to — your changes — while letting you continue to let the creator of the original theme push updates to you.

In other words, child themes save you from the two bad choices of the “update dilemma” that existed before child themes:

  • Make your changes, and skip all updates. If your theme never got meaningfully better—there were never security updates, or new features added, or bugs fixed—you’d be fine. If any of those happened, you were forced to consider the other side of the dilemma.
  • Remake your changes with each update. This is as much of a headache as it sounds. You’d have to either keep each change you made per file and start from the theme’s new baseline, rely on some good file-difference detecting tools, or just hope there were a small number of Subversion or Git commits you could easily see and backport.

If you’re lacking more child-theme context, please check out the article I wrote some time ago about them. It’s not complete, but it covers all the important stuff we’re going to skip explaining in depth here.

In that article, the most obvious changes and tweaks we’d be making were visual (CSS) changes to the parent theme. We can and do make those without all that messy and possibly confusing PHP stuff out of your hair. And that’s really awesome, but sometimes you need to actually change that PHP. That’s when you need to understand the template hierarchy.

A Brief Introduction to the Template Hierarchy

The template hierarchy is how WordPress decides which of your theme’s PHP files it’ll use to show a page.

The template hierarchy is how WordPress decides which of the myriad files in your theme it’ll use to show a page.

This choice is driven by the type of page WordPress is trying to show. If it’s trying to show the page with all the posts from a single user on the site, it walks through a different decision tree than the one it follows for a single blog post, or for a list of all posts of a recent custom post type—say “Products”—recently added to your site.

Visualizing the Template Hierarchy

There are tons of visualizations of this, and you really just need to find one that makes sense for you and refer to it when you have questions. The three I’ll take special note of:

  • The Codex’s version (direct to image) — this is the canonical version. It works well, but it’s a bit small. I do like the colors though.
  • wphierarchy.com — An easy to remember URL, with a pretty version of the template hierarchy, that adds a bit of polish to the one from the codex.WP_CheatSheet_TemplateMap
  • A Tuts+ version (at right) — This more simple and compact version is my personal favorite. It’s got fewer words, and doesn’t clearly cover all the cases, but it better fits the way I think.

WordPress always walks the template hierarchy tree, from left to right, on each page load.

When you understand that WordPress always walks this template hierarchy tree, from left to right, on each page load, you’ve covered a lot of ground.

From there, especially for child theming, grab a plugin like the Show Current Template which Fred linked to recently you’ll be pretty much set. Armed with those two, you’ll be able to figure out which file in the the theme is being used to show the current piece(s) of content, be they posts, pages, or something else.

Using the Template Hierarchy to Override a Parent Template

The template hierarchy will always look for the relevant file in your child theme before it looks in the parent theme.

The best thing about the template hierarchy for child themes is that the whole thing has child theming built right in. At every step along the tree, the template hierarchy will always look for the relevant file in your child theme before it looks in the parent theme. For example, for every file in the line from single-post.php to single.php to index.php, WordPress will always look first in your child theme, then in the parent theme, then move on to the next one. So the template hierarchy tree looks a bit like:

  1. Does the child theme have single-post.php? No, continue.
  2. Does the parent theme have single-post.php No, continue.
  3. Does the child theme have a single.php? No, continue.
  4. Does the parent theme have single.php? Yes. Okay, let’s use it!

What this means is that if you’ve put a file in your child theme with the same name as that same file in the parent theme, you just flat-out win. Simple as that. Couldn’t really hope for better.

When the Template Hierarchy Makes Things Hard

If you understand the way the whole template hierarchy works, and you’re comfortable with it, you may notice that it tends to terminate at a few common collecting points. The files archive.php, single.php, and index.php are the most prominent in my mind. And when you realize that, you may want to save some work by using something “higher up” (or farther to the right) so that you don’t end up re-doing the same work in four different places.

But this creates some tension with the child-theming way the template hierarchy works. If your parent theme has a “more specific” file per the template hierarchy, that’ll win out against the “less specific” child theme file you’d like to use. So if I’d like my category archives to fall back to my thoroughly tweaked archive.php template, the fact that my parent theme contains a category.php becomes a bummer.

The Sanity-Saving Hack

I’ve got a number of options to solve this problem, but here they are in a quick summary from worst to best choice:

  1. Remake the changes from the parent’s category.php. This would mostly just be sadistic and unnecessary re-work, but it might be your first thought.
  2. Delete your parent theme’s category.php file. This would get rid of the annoying possibility of the rework. But you’ve altered your parent theme, and so at some future date some user will update that theme, that file will return, and they’ll have to re-solve the problem.
  3. Copy and rename your archive.php into category.php in your child theme. So long as you’re reached the “final” state for the file, duplicating it manually in this way isn’t so bad. But when at some point in the future you realize that “final” wasn’t quite so final, you’ll have to make the change in both archive.php and category.php. 🙁
  4. The Hack: Make a new category.php and put just <?php include 'archive.php'; as its content.

That last option, when I realized it, was a bit of revelation. You can keep all the beauty of the child theme, keep all the beauty of having one source of truth, and just override the way that WordPress is trying (but, in this case, failing) to help you. Get familiar and comfortable with this method, and you’ll go far. I’ve come to admire the stark beauty of:

<?php 
// category.php

include 'archive.php';

You don’t have to use include; PHP’s require works fine, as would get_template_part('archive'). What’s important is that all options include the child theme’s file, and bypass the template hierarchy decision process that would otherwise force you to repeat child theme templates.

What We’ve Learned

I hope you’ve learned, or been reminded of, the value of a child theme. I hope you got some sense of what the template hierarchy is, why it’s great, and how it works with child themes. Finally, I hope I’ve taught you one specific solution for the way the template hierarchy sometimes works against you: simply include the file in your child theme that you’d rather WordPress would cut straight to, rather than using the parent theme’s version. Happy hacking!

Image credit: Procsilas Moscas


8 Responses

Comments

  • kovshenin says:

    You can also just override the template with a filter:

    add_filter( ‘category_template’, function( $template ) {
    return get_archive_template();
    });

  • cangrejero says:

    Your article is self-explanatory and easy to follow. However, me being me, there’s something I would like to ask. My custom parent theme has a front-page.php. I placed a different front-page.php in my child theme directory. When I load the website, the child theme uses the parent’s file, not its own. Is there a way to deal with this? Thanks!!!

Pingbacks