template_include (overriding default plugin templates via current theme)

This is an extension of this question/answer. A comment on that question references that template_include is preferred to template_redirect when loading templates from a plug-in.

However, hanging this to template_include is breaking everything on the site (any other page view) except the layouts that using the layout override http://pastebin.com/LWpSrfim but using template_include just prepends content (to any template files placed in the theme directory override) — the standard single view for example is still output below.


Edit: source code

<?php
class moulding_templates {
    public static function determine_template(){
        global $post,$wp_query;

        // custom post types
        $post_type_array = array('moulding_profiles','moulding_combination','moulding_collection','idea_gallery');
        foreach ($post_type_array as $post_type_single) {
            global $post;
            if (is_singular($post_type_single)) {
                moulding_templates::loadSingleTemplate($post);
            }
        }
        // custom taxonomies
        $taxonomy_array = array('profile_categories','combination_categories','wood_types');
        foreach ($taxonomy_array as $taxonomy_single) {
            if (is_tax($taxonomy_single)) {
                moulding_templates::loadTaxonomyTemplate($taxonomy_single);
            }
        }
    }

    private static function loadSingleTemplate($post) {
        $template_name="moulding-templates/single-".$post->post_type.'.php';
        $template = locate_template(array($template_name), true);
        if(empty($template)) {
            include(MOULDINGS_BASE_DIR . 'includes/' . $template_name);
            exit();
        }
    }
    private static function loadTaxonomyTemplate($taxonomy) {
        $template_name="moulding-templates/taxonomy-".$taxonomy.'.php';
        $template = locate_template(array($template_name), true);
        if(empty($template)) {
            include(MOULDINGS_BASE_DIR . 'includes/' . $template_name);
            exit();
        }
    }
}
add_action('template_include', array('moulding_templates', 'determine_template'));

1
1

So the template_redirect is used for things such as canonicalisation, feeds etc. If you want to alter the template that is served template_include is preferred.

Unlike template_redirect, template_include is a filter which filters the path of the template page. This means you don’t load/include the template, but just return the template path. WordPress does a straight-forward include on whatever is returned.

Apart from being the appropriate hook, it allows allows the function to be unhooked or over-ridden – which is should be if it’ll ever be distributed.

Related question: Custom Taxonomy in plugin and template

Example of this in action (GitHub Repro): https://github.com/stephenh1988/Event-Organiser/blob/master/includes/event-organiser-templates.php

Example usage:

 function wpse51038_maybe_alter_template($template){

    // is a specific custom taxonomy being shown?
    $taxonomy_array = array('profile_categories','combination_categories','wood_types');
    foreach ($taxonomy_array as $taxonomy_single) {
        if ( is_tax($taxonomy_single) ) {
            //For plugins. You may want to check this template exists before over-riding
            $template = plugin_dir_path('path/to/my/tax-template.php', __FILE__ );
            break;
        }
    }

  return $template;

 }
 add_filter('template_include','wpse51038_maybe_alter_template');

You may want to look at the related question linked to above – this shows how to allow the theme to over-ride the plug-in (say if they have a particularly named template file in their theme/child-theme).

Leave a Comment