Web Development by Solarise

The Solarise.dev Blog

How To Build Smarter WordPress Themes With template_redirect and template_include

Dig deep into WordPress’ templating functionality to discover how to make these two hooks work for you and your website theme.

Blog archive Robin Metcalfe 27th November 2017

Show your site visitors exactly what they need

Building a WordPress theme can be a bit like untangling spaghetti. But by using template_redirect and template_include you can gain a lot of control over where your users go and what they see.

Controlling Your WordPress Templates

Sometimes you need to display different layouts based on which user is logged in or the state of your application. This can lead to complex nested routes and tangled template hierarchies.

Introducing the template_redirect and template_include hooks.

These useful WordPress filters can help you to take more control over the layouts presented to your visitors, and insert custom templates or take other actions based on the current URL and state of the user’s current session.

  • template_include – used to override WordPress’ default template behaviours. This is executed just before WordPress includes the default template file for a given route. Use this to get more control over what users see.
  • template_redirect – used to override what WordPress does before it starts to load the default template. You use this hook to determine where users go.

They’re similar, but the difference between them is important. Only use template_redirect to guide a user to another part of your site. Don’t use it to load a different template, that’s what template_include is for!

template_redirect And template_include – The Perfect Pair

When the template_redirect and template_include hooks run, WordPress has already done the heavy lifting, has populated the global objects, and has full knowledge of the state of the current page. In other words, it’s a great time to make a decision as to where you want the user to go next or what they should see on the page.

You can see why this gives you a lot more control over your template appearance and functionality. Use that power wisely!

template_redirect and template_include let you connect your templates with ease

Template Redirection

There’s a small but important distinction between these two hooks. template_redirect is designed only for redirecting a user to another page or location (hence the name!). Use this if you want to

  • Send an unauthorised user to a specific page
  • Modify the HTTP headers before the page loads (this is a great place to do it as you can’t modify headers once the content loads)
  • Load non-WordPress content, such as loading in data from a 3rd party database
  • Prevent accesstemplate_redirect is the perfect place to check if a user should be blocked from accessing a resource

The reason why this is not the place to be placing other code to adjust the template layout is that WordPress may be relying on additional functionality hooked into template_redirect. If you try to output a template at this point then exit to terminate the script, that additional functionality may not run.

One example use for template_redirect could be to disable the single page view for a given post type but only for guest users.

add_action('template_redirect', 'single_view_disable');

/**
* Redirect away from the single view for my_custom_post_type only
* if the user is not logged in
*/
function single_view_disable() {
    global $post;
    if($post->post_type == 'my_custom_post_type' && is_single() && !is_user_logged_in()):
        // Redirect back home
        wp_redirect(home_url(), 301);
        exit;
    endif;
}

Template Inclusion

The other hook, template_include would be used if you wanted to display a different template than the one which will be served up normally as part of WordPress’ process flow rather than redirecting the user to an entirely new page.

You might use template_include to

  • Filter template files – dynamically select a template based on custom logic
  • Create a child theme – overide some specific parent templates conditionally
  • Develop a plugintemplate_include is an excellent way to give your plugin control over the front-end appearance
  • Debug during developmenttemplate_include is a perfect place to force specific templates for testing purposes

To give another specific example, modifying the example above, say we want to have two different layouts for logged in and non-logged in users for a given post type.

add_action('template_include', 'single_view_adjustment');

/**
* Redirect away from the single view for my_custom_post_type only
* if the user is not logged in
*/
function single_view_adjustment($template) {
    global $post;
    if($post->post_type == 'my_custom_post_type' && is_single() && is_user_logged_in()):
        // Search for the new template file either within the parent
        // or child themes
        $new_template = locate_template(array('my_custom_post_type-single-for-auth-users.php'));
        if ( '' != $new_template ) {
            return $new_template;
        } // if the template doesn't exist, WordPress will load
        // the default template instead
    endif;
    return $template;
}

Easily Locating A Template In The Filesystem

Note here, our use of the locate_template() function. This handy little helper function returns the path to a given template file, allowing for optional overrides within the parent/child themes.

You will also need to create a file my_custom_post_type-single-for-auth-users.php within your theme folder. To get started, you can copy the contents of single.php into this file.

Finally…

These two hooks are great places to run functionality which is dependent on the overall state of WordPress’ objects for any given URL, but to keep things tidy, it’s best to pop any non-template-related code into another hook. The init hook is a great place to do that.

add_action('init', 'do_some_stuff');

function do_some_stuff()
{
    // And here we go...
}
Author Image

About the author

Robin is the dedicated developer behind Solarise.dev. With years of experience in web development, he's committed to delivering high-quality solutions and ensuring websites run smoothly. Always eager to learn and adapt to the ever-changing digital landscape, Robin believes in the power of collaboration and sharing knowledge. Outside of coding, he enjoys diving into tech news and exploring new tools in the industry.

If you'd like to get in touch to discuss a project, or if you'd just like to ask a question, fill in the form below.

Get in touch

Send me a message and I'll get back to you as soon as possible. Ask me about anything - web development, project proposals or just say hi!

Please enable JavaScript in your browser to complete this form.

Solarise.dev Services

Maintenance Retainers

Min 3 hours per month, no contract

Project Planning

Get in touch to discuss your project details

Consultancy

Face-to-face chats. Solve your problems!