How to place custom post type or taxonomy template files in a custom directory

How to place custom post type or taxonomy template files in a custom directory

When developing your own plugin or addon, due to some technical requirements, WordPress template files sometimes need to be placed inside the plugin directory (i.e., not in the theme folder). What is needed for this?

As an example, take the WooCommerce or bbPress plugin. By default, plugin templates are stored inside the plugin folder. For Woo, it’s “/wp-content/plugins/woocommerce/templates”, and for bbPress — “/wp-content/plugins/bbpress/templates/default/bbpress”. This article describes how to partially implement similar functionality, but in a simplified form (we’ll cover full implementation in upcoming posts).

In our case, we will store template files for a custom post type and custom taxonomy inside the plugin folder. In the directory:

plugin_dir_path(__FILE__) . 'views' . DIRECTORY_SEPARATOR;

To let WordPress know it should search for custom post type and taxonomy templates in an additional directory, we need to inform it using the filter:

$templates = apply_filters( "{$type}_template_hierarchy", $templates );

This filter is located in the “wp-includes/template.php” file, see the “get_query_template(...)” function.

It’s a dynamic filter, and the “$type” variable used in the filter can (at a minimum — in my experience) have the following values: single, archive, taxonomy. These are the standard prefixes used for customizing template files.

Now to the code. To load additional template files, use the following code:

For single page:

add_filter('single_template_hierarchy', function($templates)
{
	if(is_singular(‘my-plugin’))
	{
		array_unshift($templates, plugin_dir_path(__FILE__) . 'views' . DIRECTORY_SEPARATOR . 'single.php');
	}

	return $templates;
});

The “if” condition checks that additional theme templates are loaded only if the user is viewing a single plugin page.

A similar code is used for the archive page:

add_filter('archive_template_hierarchy', function($templates)
{
	if(is_post_type_archive('my-plugin'))
	{
		array_unshift($templates, plugin_dir_path(__FILE__) . 'views' . DIRECTORY_SEPARATOR . 'archive.php');
	}

	return $templates;
});

And for taxonomy page:

add_filter('taxonomy_template_hierarchy', function($templates)
{
	if(is_tax('my-plugin'))
	{
		array_unshift($templates, plugin_dir_path(__FILE__) . 'views' . DIRECTORY_SEPARATOR . 'taxonomy.php');
	}

	return $templates;
});

Note that the only difference lies in the template files being loaded and the “if” condition. Now, when WordPress searches for templates, plugin files will have higher priority than theme files.

Posts on similar topics

Are you having problems with your WordPress site? Do you need additional functionality? A custom plugin or a new page?
Then write to me via the feedback form, and I will try to help you.

Write a comment

Your email address will not be published. Required fields are marked *