Custom Post Type Archive in Sub Folder

I have a sub-directory in my WordPress theme (there are a lot of pages and I want a more logical structure). I have a custom post type called “entry” but if I place the archive-entry.php template in my sub-directory it is no longer picked up by the theme.

Is there a way I can put my custom post type archive templates in a sub-directory?

Related posts

2 comments

  1. Unlike page templates, WordPress doesn’t look in subdirectories for post template pages. The base function used for locating such templates is locate_template() (see source), which looks in the root directory of your theme (and parent theme).

    (On the other hand get_page_templates() searches sub-directory).

    You can use template_include filter (which filters the absolute path to your template) to change the template used:

    add_filter( 'template_include', 'wpse119820_use_different_template' );
    function wpse119820_use_different_template( $template ){
    
       if( is_post_type_archive( 'entry' ) ){
           //"Entry" Post type archive. Find template in sub-dir. Look in child then parent theme
    
           if( $_template = locate_template( 'my-sub-dir/archive-entry.php' ) ){
                //Template found, - use that
                $template = $_template;
           }
       }            
    
    
       return $template;
    }
    
  2. As explained by @StephenHarris, the template loader does not do this by default.

    While Stephen’s answer looks fine to me, I was working on one before he posted and it is a bit different. I used the archive_template hook and generated the template name using get_queried_object.

    add_action(
      'archive_template',
      function($template) {
        $path = pathinfo($template);
        if (!empty($path['filename'] && 'archive' === $path['filename']) {
          $pg = get_queried_object();
          if (!empty($pg->name)) {
            $t = locate_template('archive/'.$pg->name.'.php');
            if (!empty($t)) {
              $template = $t;
            }
          }
        }
        return $template;
      }
    );
    

    It is rough code. It may be buggy.

Comments are closed.