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.