How to Create Your Template Hierarchy in WordPress

When I decide to learn a specific topic I like to dig deep into it, and understand as much as possible about that topic. Simply learning how the standard template hierarchy works wasn’t enough for me. My problem now was that I wanted to be able to create my personal template hierarchy. After having seen how flexible WordPress is I was sure that it’s possible to do it, and in fact I was right. I’ve found the right hook to understand this topic in a talk given by Kostantin Kovshenin at a WordCamp in Sofia (yes, it was in English, and no, I don’t talk Bulgarian). I watched the video last week, and I was fascinated by the power and simplicity of the mechanism. You can literally turn WordPress upside down. The whole talk includes also an explanation of how to use a filter to alter the WordPress hierarchy but since I haven’t discussed yet filters and actions I’ll let this for another article.
The first function discussed by Konstantin is locate_template(). This is probably one of the most fundamental functions for theming WordPress. In order to better study how this function works, I’ve downloaded the _s theme, or underscores if you prefer. Underscores is not a finished theme, it’s made and distributed by Automattic, and it’s meant to be the basis of your theme if you want to build one. There’s no CSS, but there are over 1000 hours of work and refinement behind its code. When I’ll build my firs theme I will use _s as a starting point. I should say that _s is also a great text-book if you want to study how to write code for WordPress but of course if you want to understand it you shouldn’t be a total beginner.

So, I’ve downloaded _s and called the theme after my name, and then I’ve opened the index.php file in my editor. Here’s what I’ve found

<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
* Learn more: http://codex.wordpress.org/Template_Hierarchy
*
* @package Giulio
*/

get_header(); ?>

<div id="primary">
<main id="main" role="main">

<?php if ( have_posts() ) : ?>

<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>

<?php
/* Include the Post-Format-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Format name) and that will be used instead.
*/
get_template_part( 'content', get_post_format() );
?>

<?php endwhile; ?>

<?php giulio_paging_nav(); ?>

<?php else : ?>

<?php get_template_part( 'content', 'none' ); ?>

<?php endif; ?>

</main><!-- #main -->
</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Inside this code there are many functions that are of interest to us. I must say now that the template hierarchy and the documents that I linked in a previous article give only part of the picture about the template hierarchy. All these templates are broken down in sub-templates which you can further break down in sub-templates.

So, what happens in the index.php file shown above? This is the first line of code after the comments

get_header(); ?>;

What this function does looks pretty straightforward; it loads the file header.php which is in charge of writing the head of the html page that our screen will show up. Now it comes the fun part: how does the get_header() function works? The description in codex.WordPress.org tells me everything that I need to know but I’m not satisfied, I want to see the function. Why? Because I’m terribly curious! So I open the file wp-includes/general-template.php and look into the function.

function get_header( $name = null ) {
do_action( 'get_header', $name );
$templates = array();
$name = (string) $name;
if ( '' !== $name )
$templates[] = "header-{$name}.php";
$templates[] = 'header.php';
// Backward compat code will be removed in a future release
if ('' == locate_template($templates, true))
load_template( ABSPATH . WPINC . '/theme-compat/header.php');
}

The function takes an optional parameter $name which is null by default. Forget about the following instruction where it creates an action hook. Then it comes the interesting part. The function creates the $templates array, and it builds a template hierarchy for the header inside this array. If the parameter $name is not null, then that it’s used to build the name of the first header template. Then it calls the locate_template() function that will load the right template.

The locate_template() function uses the $templates array to decide which header file to load. For example, if I call get_header('special') the array will look like if I had done the following:

$templates[] = "header-special.php";
$templates[] = "header.php";

In other words, the argument of the function is appended to “header-” to compose the template file name. This template file gets the highest priority in our mini hierarchy. This is the order in which the locate_template() function will look for the templates. The functions get_sidebar() and get_footer()work exactly in the same way. What I’ve learned from this is that not only WordPress has sub-templates but that you can further broken them down in sub-templates. In theory I could have a different header, footer and sidebar in every template that I build. In practice I would be crazy if I’d do this but all of this power could help me manage some extreme situations.

There is still a function to discuss that our index.php template calls from two different places, at the lines 29 and 38. The function is get_template_part() and it’s another ammunition in our arsenal. This function allows you to break templates into template parts that you can reuse across a theme or even better in a child theme. This is the same concept at the base of the get_header() , get_sidebar() and get_footer() functions but more generalized. If you want an explanation about this function, Konstantin has written a very detailed article about it some time ago. I’m very grateful that the people who develop the WordPress core spend time explaining these things to people like me. It’s what makes WordPress so fun to learn and to work with.

These are the files that contain all the functions related to templates in WordPress.

  • wp-includes/template-loader.php
  • wp-includes/general-template.php
  • wp-includes/template.php

I will look into them in the coming weeks when I’ll have some time, and if I find some hidden gem I will write an article about it.


So, what do you think ?