Skip to main content

WordPress Tutorial: Safely Include Custom Templates

Following on from my previous WordPress tutorial relating to template redirects, this article features a different technique to include custom templates within your WordPress website that is more efficient than doing a template redirect.

add_filter('template_include', 'jnorton_template_include');
function jnorton_template_include($incFile) {
  global $wp_query;
  $url = explode("/", substr($_SERVER ['REQUEST_URI'], 1));
  if ($url [0] == 'test') {
    $file = get_theme_root() . '/' . get_template() . '/test.php';
    if (file_exists($file)) {
      $incFile = $file;
    }
    else {
      $wp_query->is_404 = TRUE;
    }
  }
  return $incFile;
}

To briefly explain the code features an if statement to check if the browser has requested the URL named 'test'. If a match is found then the local system path and file name of the template file is returned to WordPress to use with the template_include filter.

The core filter is found in the file: wp-includes/template-loader.php and features the following code:

if ( $template = apply_filters( 'template_include', $template ) ) include( $template ); return; 

Looking at the core code you will see that there is a very simple if statement and standard PHP include to the file defined in your custom template_include filter.

We can also use WordPress query vars in the template include filter that allows unique templates to be shown for custom post types and custom taxonomies. A great use case for this is when you need a directory index style landing page and a breadcrumb / directory style hierarchy for taxonomy terms. For example, your custom post type is defined with the slug 'test' and you want custom taxonomy terms to site below e.g. test/all-terms-for-test.

add_filter('template_include', 'custom_template_include', 10, 1);
function custom_template_include($template) {
  global $wp_query;
  if (get_query_var('custom_post_type_key') == 'custom_taxonomy_key') {
    // Add a title.
    add_filter('wp_title', function ($title) {
      return 'A custom archive of taxonomy items';
    }, 100000);
    // Set query attributes.
    $wp_query->is_archive = TRUE;
    $wp_query->is_home = FALSE;
    $wp_query->is_404 = FALSE;
    // Load the template.
    $template = locate_template('custom-taxonomy-index.php');
    // Set some headers to help with caching etc.
    $ttl = 86400;
  	status_header('200');
  	header('Cache-Control: public, max-age=' . $ttl);
  	$expires = gmdate('D, d M Y H:i:s', time() + $ttl) . ' GMT';
  	header('Expires: ' . $expires);
  }

  // Check if the template file exists
  if (!file_exists($template)) {
    $wp_query->is_404 = TRUE;
    $template = get_404_template();
  }

  return $template;
}

Using a custom template_include filter to include template files allows WordPress to clean up after itself by closing database connections, destroying objects, etc. This means your website will be in great shape and will perform better under heavy load.