Blog

Sharing WordPress tips and tricks as I find them

Reusing Template Files

WordPress’ built-in template hierarchy is very useful for reusing template files on standard websites. If you have something you want used for all category archives, use category.php. If you want a template file to be used on all archives (category, tag, search…), use archive.php.

But when you’re building websites with complex content structures, you’ll often need to build a very specific template hierarchy of your own, or else duplicate a lot of code.

I’m building a site right now with four custom post types, and each post type has 2-4 taxonomies. Take a look at the screenshot above. The ‘recipe’ post type has two taxonomies: ‘name-range’ which allows the client to break down the list of recipes by name (ex: A-D, E-G…), and ‘base’ (dropdown says category), which is a shared taxonomy with another post type that specifies the alcoholic base of the cocktail.

I want a single template file that is used in all of these situations:

  • Recipe post type archive
  • Name Range taxonomy archive
  • Base taxonomy archive (if post type is also ‘recipe’)

For this, I’ll use the template_include filter. This filter runs right after WordPress determines what template it thinks it should use, but before that template is actually loaded. This is where you can hop in and specify your own template hierarchy.

Without this technique, I’d need to put the same code in archive-recipe.php, taxononomy-name-range.php, and taxonomy-base.php (with some extra code in here to check for the current post type).

The code above says “if this is the post type archive for ‘recipe’, the taxonomy archive ‘name-range’, or the taxonomy archive ‘base’ AND post type ‘recipe’, then use the template file archive-recipe.php.”

I also like to generalize this section checker into its own function so I can use it elsewhere. You might want to add a body class called ‘section-recipe’ if any of these templates are in use. Here’s how:

First I’m creating a function that returns the current section if there’s a match, and ‘false’ if there isn’t.

Then I have my template redirect function. If the current page is in a section, it loads the template ‘archive-$section’ (ex: archive-recipe.php).

Then I have my body class filter. If the current page is in a section, it adds the body class ‘section-$section’ (ex: ‘section-recipe’ ).

If you add a new taxonomy, just edit the be_return_archive_section() function to specify the section it belongs in, and it will automatically use the correct template file and have the body class.

9 Comments

  1. Incredibly useful tip. I’ve been including multiple files for custom taxonomies on portfolios even though they display out the same. Thanks for posting.

  2. Thomas Bock says:

    Bill,

    Thanks for the tip. You make things efficient.

  3. Could you not put common code into another file, and then have a simple require in the template files that need to make use of them?

    • Bill Erickson says:

      Yes, but then you’d still need to create three template files which all include a require statement. This is a much cleaner solution, assuming they are all the same template. If you only want to include a few functions, then yes, a require is best, or include the function in functions.php and just put the add_action() in the template file.

  4. Yeah, thats dope. :)

  5. Interesting technique! Thank you for sharing.

  6. Bruce Munson says:

    Thanks for the very useful article Bill! (Also well written).

  7. Intersting technique of writing quality code inside wordpress. Thanks for sharing.

Join the Conversation

If you'd like to include code in your post, please post it to http://gist.github.com and include a link.