1

I'm a bit confused with templates for custom post types defined as hierarchical. I've got a CPT set to hierarchical, not strictly in order to have a nested hierarchy, but so that they can be ordered by the Simple Page Ordering plugin. Here's the code:

register_post_type(
    'case_study', array(
        'label'                 => _x( 'case studies', 'post type plural name' ),
        'labels'                => array(
            'name'                  => _x( 'Case studies', 'post type general name' ),
            'singular_name'         => _x( 'Case study', 'post type singular name' ),
            'menu_name'             => _x( 'Case studies', 'admin menu' ),
            'name_admin_bar'        => _x( 'Case study', 'add new on admin bar' ),
            'add_new'               => _x( 'Add New', 'case study' ),
            'add_new_item'          => __( 'Add New Case study' ),
            'new_item'              => __( 'New Case study' ),
            'edit_item'             => __( 'Edit Case study' ),
            'view_item'             => __( 'View Case study' ),
            'all_items'             => __( 'All Case studies' ),
            'search_items'          => __( 'Search Case studies' ),
            'parent_item_colon'     => __( 'Parent Case studies:' ),
            'not_found'             => __( 'No Case studies found.' ),
            'not_found_in_trash'    => __( 'No Case studies found in Trash.' )
        ),
        'public'                => true,
        'publicly_queryable'    => true,
        'show_ui'               => true,
        'show_in_nav_menus'     => true,
        'show_in_menu'          => true,
        'show_in_admin_bar'     => true,
        'menu_position'         => 20, // Below Pages
        'menu_icon'             => 'dashicons-clipboard', // @link https://developer.wordpress.org/resource/dashicons/
        'query_var'             => false,
        'rewrite'               => array( 'slug' => 'case-study', 'with_front' => false ),
        'capability_type'       => 'case_study',
        'map_meta_cap'          => false,
        'capabilities' => array(
            'publish_posts'         => 'publish_case_studies',
            'edit_posts'            => 'edit_case_studies',
            'edit_others_posts'     => 'edit_others_case_studies',
            'delete_posts'          => 'delete_case_studies',
            'delete_others_posts'   => 'delete_others_case_studies',
            'read_private_posts'    => 'read_private_case_studies',
            'edit_post'             => 'edit_case_study',
            'delete_post'           => 'delete_case_study',
            'read_post'             => 'read_case_study',
        ),
        'has_archive'           => false,
        'hierarchical'          => true, // Set to true to allow ordering
        'supports'              => array( 'title', 'editor', 'custom-fields', 'thumbnail', 'revisions', 'pilau-author' ),
        'taxonomies'            => array( 'topic' ),
    )
);

By default a hierarchical CPT uses the page.php template instead of single.php - which took me a while to realise, but it makes sense.

However, now I want to create a template specifically for this CPT, and single-case_study.php doesn't work. Neither does page-case_study.php.

How do you create a template specifically for a hierarchical CPT?

5
  • Note, if you are going to have hundreds of posts and you re not going to use parent-child relations between posts, you would want to set the hierarchical parameter to false. Having his set to true will cause your back end to timeout when posts gets to many :-) Commented Sep 25, 2015 at 13:13
  • 1
    Hierarchical custom post types don't use page.php, they follow the same template hierarchy as non-hierarchical post types. You've set query_var to false, so you are possibly seeing the 404 template or your theme is using some other template loading mechanism, because as-is your post type is not viewable on the front end.
    – Milo
    Commented Sep 25, 2015 at 16:43
  • Pieter, thanks, I don't think there's going to be that many posts of this type. Commented Sep 25, 2015 at 17:01
  • Milo, it's definitely not a 404 - is_404() == false, is_page() == true. (It's my own theme, based on a my own framework I've been using for years, so I know it's not theme-related template loading that's opaque to me.) Setting query_var to true has no effect. Here's the hack I'm using for now but obviously I'm missing something: gist.github.com/gyrus/023841a0cc548e36419a Commented Sep 25, 2015 at 17:05
  • Have to leave this for now but it seems to be happening on non-hierarchical post types as well, and checking my other projects it seems I do usually set query_var to true. Switching that doesn't immediately solve the issue but I guess the answer is in that direction - will post if/when I nail it. Commented Sep 25, 2015 at 17:12

2 Answers 2

1

Old question but maybe it helps someone else:

You could do something like this in page.php:

$postType = get_post_type();

if($postType == 'case_study'){
   include('single-case_study.php');
} else{
   // Do your page.php stuff
0

I sense I'm still missing something, but for now I've approached this another way. Since the only reason for the CPT to have hierarchical set to true is so that Simple Page Ordering will work (I'm not actually after a nested hierarchy), I went back to the plugin's FAQ and found that it is possible to order non-hierarchical post types. Either include 'page-attributes' in the supports array or use the simple_page_ordering_is_sortable filter, then you can click 'Sort by Order' on the posts admin listing page and drag-and-drop.

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.