Bypassing the Hierarchy in WordPress

WordPress Templates

  • When developing an extendable theme for public distribution it’s best to stick to the WP Template Hierarchy. If the theme is not extendable, the Template Hierarchy can be bypassed with a custom-made router in the index.php file for tight access control over the WP system.
  • The WordPress function get_template_part() can be used to include template files from custom sub-directories.

Custom Post Type options

<?php /* Template Name: Custom Template A 
Template Post Type: post, page, event */

$GLOBALS['layout_template_type'] = 'type_a';
include(get_stylesheet_directory() . '/index.php');
?>

index.php

Custom theme routing using conditional tags in the index.php file allows for strict control of the WP environment.

<?php

/**
 * Route the request to it's template file
 *
 * WP is not provided any other template files so all requests go here.
 * This is done to control access to everything. Any route we want to block
 * simply becomes a 404 if it is not specifically defined here.
 *
 * NOTE: When you use is_home() and is_front_page(), you have to use them in the
 * right order to avoid bugs and to catch all user configurations.
 *
 * `is_front_page()`
 * Returns `true` if the request is for the front page of the site, whatever the
 * content may be. If it’s a static home page, or a list of blog posts, or
 * something else this will return `true`. Any other page and it will return
 * `false`.
 *
 * `is_home()`
 * Returns `true` if the request is for the default WordPress homepage, it shows
 * the reverse chronological list of blog posts.
 */

// Set the default template style if it has not already been set.
if (!isset($layout_template_type) || $layout_template_type == '') {
    $layout_template_type = 'type_b';
}
$GLOBALS['layout_template_type'] = $layout_template_type;

// Define alowed resquests.
if     (is_front_page() && is_home())   { get_template_part('includes/partials/manager'); } // Index page requests.
elseif (is_front_page())                { get_template_part('includes/partials/manager'); } // Index page requests.
elseif (is_home())                      { get_template_part('includes/partials/manager'); } // Index page requests.
elseif (is_single())                    { get_template_part('includes/partials/manager'); } // `Post` type page requests.
elseif (is_page())                      { get_template_part('includes/partials/manager'); } // `Page` type page requests.
elseif (is_search())                    { get_template_part('includes/partials/manager'); } // `Search Results` type page requests.
else                                    { get_template_part('includes/404'); } // By default everything is a 404 page.

404.php

All requests not specifically allowed get redirected to the the 404 page template file.

<?php get_template_part('partials/doc_top'); ?>
<h1>404 Page Not Found</h1>
<p>Sorry but the page you requested could not be found.</p>
<?php get_template_part('partials/doc_bottom'); ?>

manager.php

  • All requests specifically allowed are sent to the manager.php template file.
  • The HTML document is rendered from the doc_top.php and doc_bottom.php partial template files.
  • The WP Loop is called to get the posts for the request.
  • The Post Type of each record is checked, and checked if it will be used by itself on a sing-page, or in a page wich displays a list of posts. Based on these parameters, the proper template files are used to render the HTML for the post.