{"id":516,"date":"2017-01-22T16:49:51","date_gmt":"2017-01-22T16:49:51","guid":{"rendered":"https:\/\/www.joetannorella.com\/?p=516"},"modified":"2017-01-22T18:52:46","modified_gmt":"2017-01-22T18:52:46","slug":"custom-template-custom-post-type-single-post-wordpress","status":"publish","type":"post","link":"https:\/\/www.joetannorella.com\/custom-template-custom-post-type-single-post-wordpress\/","title":{"rendered":"Custom template for custom post type single post wordpress"},"content":{"rendered":"
I recently had\u00a0a somewhat unique situation whereby I needed a custom template per post of a custom post type.<\/p>\n
Consider the custom post type being ‘services’, then you’d set it like this:<\/p>\n
\r\n$labels = array(\r\n 'name' => 'Services',\r\n 'singular_name' => 'Service',\r\n 'menu_name' => 'Services',\r\n 'parent_item_colon' => 'Parent Service',\r\n 'all_items' => 'All Services',\r\n 'view_item' => 'View Service',\r\n 'add_new_item' => 'Add New Service',\r\n 'add_new' => 'Add New',\r\n 'edit_item' => 'Edit Service',\r\n 'update_item' => 'Update Service',\r\n 'search_items' => 'Search Service',\r\n 'not_found' => 'Not Found',\r\n 'not_found_in_trash' => 'Not found in Trash',\r\n );\r\n $args = array(\r\n 'label' => 'Services',\r\n 'description' => 'Service',\r\n 'labels' => $labels,\r\n 'hierarchical' => true,\r\n 'public' => true,\r\n 'show_ui' => true,\r\n 'show_in_menu' => true,\r\n 'show_in_nav_menus' => true,\r\n 'show_in_admin_bar' => true,\r\n 'menu_position' => 5,\r\n 'can_export' => true,\r\n 'has_archive' => true,\r\n 'exclude_from_search' => false,\r\n 'publicly_queryable' => true,\r\n 'supports' => array( 'thumbnail', 'editor', 'title', 'excerpt', 'page-attributes' )\r\n );\r\n \/\/ Registering your Custom Post Type\r\n register_post_type( 'Services', $args );\r\n<\/pre>\nThe URL structure follows something like:<\/p>\n
\/services\/web-development<\/p>\n
\/services\/consulting<\/p>\n
\/services\/cooking<\/p>\n
…and so on.<\/p>\n
In this example, I was looking to have a drastically different template for each of these\u00a0custom post type pages.<\/p>\n
The custom archive template for this is pretty simple, just create a file called ‘archive-services.php’. Similarly, the single post type template is simple, just create a file called ‘single-services.php’.<\/p>\n
Creating a post-specific template<\/h2>\n
The difficulty is where you need a specific template for each post, based on ID or slug.<\/p>\n
Usually you can do this for pages or posts by creating a file called ‘page-{slug}.php’ or ‘page-{ID}.php’ (in the case of the post being a page post type.<\/p>\n
To do the same thing for a custom post type is a little bit more complicated. In an ideal world you could simply create ‘single-{$posttype}-{$slug}.php’ – but alas this does not work. You need to create your own filter which bypasses the tempalte selection, based on the post_type name.<\/span><\/p>\n
In your functions.php file use the following:<\/p>\n
\r\n<p class="lang-php prettyprint prettyprinted" style="color: #393318;"><code><span class="pun" style="color: #303336;">add_filter( 'single_template', function( $template ) {\r\nglobal $post;\r\n$post_type_name = 'services';\r\nif ( $post->post_type === $post_type_name ) {\r\n$locate_template = locate_template( "single-".$post_type_name."-{$post->post_name}.php" );\r\nif ( ! empty( $locate_template ) ) {\r\n$template = $locate_template;\r\n}\r\n}\r\nreturn $template;\r\n} );\r\n<\/pre>\nDon’t forget to replace ‘services’ with the name of your own post_type!<\/p>\n
Using this method, you’ll now be able to create a unique template for each of your custom post type posts.<\/p>\n