While prototyping a WordPress plugin I’m writing, I experimented with supplying default templates to display pages related to a custom post type. This is accomplished using the template_redirect
action API. If the following technique is not used, any special templates a plugin provides would need to be copied to the active theme, making plugin installation more complex than necessary.
The first step in building the template_redirect
action is to determine if the page being displayed is either a single page or archive of the custom post type. WordPress supplies the functions is_singular()
and is_post_type_archive()
for this purpose. If it’s a page that does not have a plugin supplied template, the function should return allowing WordPress core to select the correct template to use.
if (is_singular($my_post_type)) { $template_name = 'single-'; } elseif (is_post_type_archive($my_post_type)) { $template_name = 'archive-'; } else { return; }
Next, I build the full name for the template file that will be used and attempt to locate one supplied by the active theme. The WordPress function locate_template()
will return the path to a matching template if one is present.
$template_name .= get_post_type($post) . '.php'; // Look for theme provided template $template = locate_template(array($template_name), true);
Finally, if the theme does not supply a template, the plugin supplied default template is used. When the template_redirect
action does use an alternate template, it is expected to exit and no further processing should be done by WordPress core.
if (empty($template)) { include(WP_PLUGIN_DIR . '/my-plugin-dir/template/' . $template_name); } exit();
Putting this all together, here’s the entire code snippet:
function my_template_redirect() { global $post; global $my_post_type; if (is_singular($my_post_type)) { $template_name = 'single-'; } elseif (is_post_type_archive($my_post_type)) { $template_name = 'archive-'; } else { return; } $template_name .= get_post_type($post) . '.php'; // Look for available templates $template = locate_template(array($template_name), true); if (empty($template)) { include(WP_PLUGIN_DIR . '/my-plugin-dir/template/' . $template_name); } exit(); } add_action('template_redirect', 'my_template_redirect');