Template Hierarchy for get_header()

I’m considering having different headers depending on the area of the site. So thought it might be possible to tap into the template hierarchy (or at the very least, re-use some of the code) and filter the output.

Is this something that anyone has tried? Or could anyone point me in the direction of the code which selects the template file in the heirarchy – I’ve been unable to find it.

2 Answers
2

get_header() accepts an argument, using it you can call a different headers.

The only thing that get_header() does, is to include in the template where is called the file 'header.php' from child theme (if present) or from theme.

If you use the argument $name, like so: get_header( $name), the function will look for a file named 'header-{$name}.php'.

An example: you want to use a different header for home page.

So you create a file called 'header-home.php' then in the file 'home.php' instead of calling get_header() you can call get_header( 'home' ) to include 'header-home.php' instead of 'header.php'.

If you have multiple headers, is possible that some parts are repeated the same in all files.

To avoid that and use DRY code, you can extract some parts and put in separate files, then easily reuse them via get_template_part().

An example:

<?php
// header.php
get_template_part('header', 'start'); // header-start.php contain html tag and other stuff
wp_head(); // should always be called in header
get_template_part('header', 'navigation'); // header-navigation.php for menu


<?php
// header-home.php
get_template_part('header', 'start');
wp_head();
get_template_part('header', 'navigation');
get_template_part('header', 'navigation2'); // header-navigation2.php for additional nav
get_template_part('header', 'home'); // header-home.php contain stuff specific to home

This is just an example, however, shows how to create different header files without having to repeat code.

As a bonus is full child theme friendly (in a child theme you can replace even only one ‘piece’ using the others from parent theme).

Edit

Regarding the way to dynamic set the $name argument based on current template, it relatively easy to do.

You can use template_include hook to setup a global accessible variable and use it as argument for get_header.

add_filter( 'template_include', 'my_theme_sniff_template', 99999);

function my_theme_sniff_template( $template ) {
  $info = pathinfo( $template );
  global $my_theme_cur_tmpl;
  $my_theme_cur_tmpl = $info['filename'];
  return $template;
}

Using such a code, in your templates files you can use

get_header( isset($GLOBALS['my_theme_cur_tmpl']) ? $GLOBALS['my_theme_cur_tmpl'] : '' );

the $GLOBALS['my_theme_cur_template'] will contain the file name (without extension) of current template. So for home.php it will be 'home' and so on.

So get_header will automatically search for 'header-home.php', 'header-front-page.php', 'header-single.php', 'header-page.php' and so on…

But don’t worry: you don’t have to create an header for any template, if the template-specific header file is not found, get_header will automatically load the standard 'header.php'.

Leave a Comment