Wordpress - Custom single template for a specific category

From my comment to the OP

My opinion, use what you are comfortable with. If there are any performance difference it will be minute/irrelevant. My preference, use the filter

To come to your real concern/question, in my opinion, the best approach will be to use the parent category ID and work from there. It will be the least resource intensive to work from here. Reverse engineering can become quite an unnecessary waste of resources.

Make use of get_categories to get the child categories from the given category. You can make use of either one of two parameters, either parent or child_of

parent (integer)

Display only categories that are direct descendants (i.e. children only) of the category identified by its ID. This does NOT work like the 'child_of' parameter. There is no default for this parameter. [In 2.8.4]

child_of (integer)

Display all categories that are descendants (i.e. children & grandchildren) of the category identified by its ID. There is no default for this parameter. If the parameter is used, the hide_empty parameter is set to false.

Once you have these, use wp_list_pluck to get the catID, name or slug fields from the returned array of categories. This array will be used to check if a post belongs to one of these categories. You can either use has_category or in_category

This is how you can extend your code to make sure that posts belonging to either the parent category or its descendants uses the given template

add_filter( 'single_template', function ( $single_template ) {

    $parent     = '21'; //Change to your category ID
    $categories = get_categories( 'child_of=' . $parent );
    $cat_names  = wp_list_pluck( $categories, 'name' );

    if ( has_category( 'movies' ) || has_category( $cat_names ) ) {
        $single_template = dirname( __FILE__ ) . '/single-movies.php';
    return $single_template;
}, PHP_INT_MAX, 2 );

step 1: Create or copy content-single.php and create a new file. eg: content-yourCategory.php step 2: Open single.php and replace this get_template_part('content','single'); by the following code


The parameter can be Category ID, Category Title, Category Slug or Array of IDs, names, and slugs.

This is a convenient way of doing that, found here past this code into your function.php

// Custom single template by category
// https://halgatewood.com/wordpress-custom-single-templates-by-category

add_filter('single_template', 'check_for_category_single_template');
function check_for_category_single_template( $t )
  foreach( (array) get_the_category() as $cat ) 
    if ( file_exists(STYLESHEETPATH . "/single-category-{$cat->slug}.php") ) return STYLESHEETPATH . "/single-category-{$cat->slug}.php"; 
      $cat = get_the_category_by_ID( $cat->parent );
      if ( file_exists(STYLESHEETPATH . "/single-category-{$cat->slug}.php") ) return STYLESHEETPATH . "/single-category-{$cat->slug}.php";
  return $t;

for more info check out https://halgatewood.com/wordpress-custom-single-templates-by-category