Dig deep into WordPress’ templating functionality to discover how to make these two hooks work for you and your website theme.
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!
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!
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
template_redirect
is the perfect place to check if a user should be blocked from accessing a resourceThe 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;
}
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
template_include
is an excellent way to give your plugin control over the front-end appearancetemplate_include
is a perfect place to force specific templates for testing purposesTo 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;
}
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.
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...
}
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.
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!