Autoload header and footer in your template files

(This article is not finished, but it is going to be.)

A WordPress theme using one templates file

To create a WordPress theme you only need to create two files, namely index.php and style.css.

You need to have a .css file in your theme folder even if you decide to make a theme that only uses the browser’s default styling because WordPress reads out the name of the theme from the style.css file.

A basic theme would look like this:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>

    <meta charset="<?php bloginfo( 'charset' ); ?>">

    <?php wp_head(); ?>

</head>
<body>

    <?php

    if ( have_posts() ) :

        while ( have_posts() ) : the_post();

            the_title( '<h2>', '<h2>' );

            the_content()

        endwhile;

    endif;

    wp_footer();

    ?>

</body>
</html>

If you manage to create a theme with only one template file you don’t have to worry about the header.php and footer.php files since you can include your basic HTML structure in your index.php file.

Partial files

Whenever you create an additional template file it a good idea to move the repeating code into partial files.

get_header and get_footer are convenient (wrapper) functions to load your header and footer file. In case you are calling these functions without creating the files you will get a notice - if you have WP_DEBUG enabled.

Notice: Theme without header.php is <strong>deprecated</strong> since version 3.0.0 with no alternative available.
Please include a header.php template in your theme.

In a way it is "forcing" you to have you own header.php and footer.php files.

The fallback files are located in the wp-includes/theme-compat/ folder.

get_header and get_footer everywhere

When working on a simple corporate website it is fairly common to have four-five or even more custom template files beside specialized archive and single pages. You will end up writing the get_header and get_footer over and over again in every single template file.

Fortunately you can autoload these files and clean up your templates files a little. To do this you have to apply a filter to the template_include hook.

template_include is located in the wp-includes/template-loader.php file. Here is the relevant part from that file.

// …

if ( $template = apply_filters( 'template_include', $template ) ) {

    include( $template );

} elseif ( current_user_can( 'switch_themes' ) ) {

    $theme = wp_get_theme();

    if ( $theme->errors() ) {

        wp_die( $theme->errors() );

    }
}

// …

The autoload function

To autoload you have create a function - you can call it autoload_header_footer - add attach to the template_include hook. Set the priority to 90 or even higher and specify that we the number of arguments to accept 1.

When you are working with filters usually you are returning back a value, here we don't return back anything because the autoload_header_footer function does the including, hence you have to set the priority to a high value. This way you can make sure you don't cause conflicts with other filters. Before including the template file call the get_header and after the inclusion the get_footer functions.

Here is how it should look.

add_filter( 'template_include', 'autoload_header_footer', 90, 1 );

function autoload_header_footer( $template ) {

    get_header();

    include( $template );

    get_footer();

}

Extending the autoload_header_footer function by using conventions

At this moment every template load the same header and footer file. It is not by accident that both get_header and get_footer can accept an argument, which would be the name of the file to load. For example get_header( 'inverse' ) would load the header-inverse.php file and get_footer( 'inverse' ) would load the footer-inverse.php file.

This is usefull when dealing with more complex websites and you need to have a different header or footer for a certain template.

If you decide to use a convention to name our header and footer files based on the templates file names you can easily solve this problem.

In the autoload_header_footer function the $template variable holds the full path of the file, not the name of the file.

/Users/implenton/Work/wordpress/wp-content/themes/wordpress/front-page.php

By passing to the get_header and get_footer function the name of template that is loaded you could try to load that file first if that exists and fall back to the default files.

add_filter( 'template_include', 'autoload_header_footer', 90, 1 );

function autoload_header_footer( $template ) {

    $template_basename = basename( $template, '.php' );

    get_header( $template_basename );

    include( $template );

    get_footer( $template_basename );

}

Using the basename function we can get the name of the file. The second argument represents the suffix; since we are only dealing with .php file we can pass that.

If you create the header-front-page.php file in addition to the header.php file that takes precedence when the front-page.php file is rendered. In case that files is missing we are fallin back to the default header.php file.

Turn this into a plugin to have even more control

Even though this approach covers almost all cases you might run into on a medium sized website there are special situations. You might have to enable a temporary page and you just want to add custom HTML there or you might want to use the video.php template without header and footer.

/*
 * Plugin Name: Autoload Header and Footer
 * Plugin URI:  https://implenton.com/2016/10/autoload-header-and-footer-in-your-template-files
 * Description: Autoload the header and footer files in your template files
 * Version:     1.0.1
 * Author:      implenton
 * Author URI:  https://implenton.com/
 * License:     GPLv2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 */

namespace Implenton\HeaderFooter;

if ( ! defined( 'WPINC' ) ) {
    die;
}

add_filter( 'template_include', __NAMESPACE__ . '\autoload', 90, 1 );

function autoload( $template ) {

    if ( true === skip_for( $template ) ) {

        return $template;

    }

    $template_basename = basename( $template, '.php' );

    get_header( $template_basename );

    load_template( $template );

    get_footer( $template_basename );

}

function skip_for( $template ) {

    $template_basename = basename( $template, '.php' );
    $ignored_templates = apply_filters( 'skip_autoload_header_footer_for', [] );

    if ( in_array( $template_basename, $ignored_templates ) ) {

        return true;

    }

    return $template_basename;

}

Download the plugin file

Whenever you want to skip the autoloading for a template file you can add a filter in your function.php file.

add_filter( 'skip_autoload_header_footer_for', function() {

    return [
        'tpl-temporary',
        'video',
    ];

} );

Did you find this article useful, interesting or you want to chat about this topic? Send me a mail and let me know. In case you found some spelling or grammar mistakes let me know that too.