I'm writing a plugin to manage data about open-source projects. I developed an object model and have successfully created all custom post types and taxonomies, as well as implemented the correct capabilities/roles using the Members plugin. The appropriate users can create, modify, and delete their own posts, and administrators can approve them, as well as modify and delete anyone's posts.

My problem is, that I want to define the template for a single Project and for a list of Projects (single and archive, I believe - I've never worked with Wordpress at this level), but I do not want The Loop to rely on the current theme to render the page for a single Project or a list of Projects. If I am using the TwentyTen theme, I want it to use my plugin's template for those custom post types. If I am using the TwentyEleven theme, I still want it to use my plugin's template for those custom post types.

I want this to obey the "it just works" paradigm, but right now users can't just drop the folder in the plugin directory - they have to add the appropriate files to their theme folder every time they switch themes. I've checked out the template hierarchy and I have the filenames correct, but they aren't used by Wordpress if they are in the plugin folder, or in plugin/templates folder.


  • Of course, it always seems like I find the answer right after I post a question... It seems like I need to add to the single_template filter to accomplish this. Source: codex.wordpress.org/Plugin_API/Filter_Reference/single_template (1 reputation, so it won't let me answer my own question!)
    – ZachM
    Jun 19, 2012 at 14:44
  • single_template runs for individual posts and pages. You're describing using it for a list of projects so you need a different filter - answer below Jun 19, 2012 at 15:48

1 Answer 1


You need to use the template_include filter which is the generic filter for all template inclusions.

add_filter( 'template_include', 'my_plugin_templates' );
function my_plugin_templates( $template ) {
    $post_types = array( 'project' );

    if ( is_post_type_archive( $post_types ) && ! file_exists( get_stylesheet_directory() . '/archive-project.php' ) )
        $template = 'path/to/list/template/in/plugin/folder.php';
    if ( is_singular( $post_types ) && ! file_exists( get_stylesheet_directory() . '/single-project.php' ) )
        $template = 'path/to/singular/template/in/plugin/folder.php';

    return $template;

I've not fully tested the post type archive bit, you may need to include a check using is_tax( $taxonomies ) to get it to work on associated custom taxonomy archives.

  • Thanks! This helps. Though the $theme = wp_get_theme(); and if ( $theme-> stylesheet... lines are not what I need here (I need it to be entirely independent of themes - maybe I said it previously in a confusing way). The rest of the code looks good though!
    – ZachM
    Jun 19, 2012 at 17:17
  • Works great! Needs a semicolon after the two $template=... lines though... didn't catch that the first time and was wondering what went wrong. Thanks!
    – ZachM
    Jun 19, 2012 at 19:00
  • @ZachM d'oh! sorry - I'll fix that in the answer. I thought you wanted to only override those 2 themes but what you really need to do then is to check the current theme for the existence of those template files. Do you want any help with that bit? Jun 20, 2012 at 9:59
  • is this truly theme independant? i thought single.php etc contain get_header() / get_footer() and lots of template specific html?
    – Steve
    Feb 28, 2013 at 3:06
  • 1
    @Eherman it just gets passed into PHP's include function. Works fine for me. Is your absolute path definitely correct? eg. you may need to use plugins_dir_path( __FILE__ ) . 'template.php' Mar 17, 2014 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.