6

What is the best way (performance & code structure) to create a custom template for a WordPress Post, which belong to a specific category? I realized that you can’t just create single-catname.php.

So far i tried two ways to change the template. But which one (or another one) is the best?

EDIT:

Any idea how to include all the sub/parent and so on categories to? I realized right now it only shows the main category...

1. Added to functions.php

function get_custom_cat_template($single_template) {
   global $post;
   if ( in_category( 'movies' )) {
      $single_template = dirname( __FILE__ ) . '/single-movies.php';
   }
   return $single_template;
} 
add_filter( "single_template", "get_custom_cat_template" ) ;

2. Put the following Code in to single.php (instead of all other code) and create a single-template.php (with the code from the single.php) & a custom single-movies.php

<?php        
if(has_term('movies', 'category', $post)) {      
   get_template_part('single-movies', 'movies');
} else {
   // use default template file single-template.php
   get_template_part('single-template');
}
?>
  • My opinion, use what you are comfortable with. If there are any performance difference it will be minute/irrelevant. My preference, use the filter – Pieter Goosen Nov 29 '14 at 10:40
  • Thx for the quick response. Any idea how to include all the sub/parent and so on categries to? I realized right now it only shows the main cat... – NewUser Nov 29 '14 at 10:42
6

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 );
  • 1
    Any feedback on this? It would be appreciated (and good manners) if you can leave feedback to your open questions. It would not only benefit you, but the other users finding your questions via search engines. Simply abandoning your questions as you did might lead to other users ignoring your questions in future. Please help us (and yourself) to keep this site and your questions constructive. Thanks for understanding :-) – Pieter Goosen Apr 14 '15 at 6:12
3

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

    if(is_category('yourCategory')){
        get_template_part('content','yourCategory');
    }else{
        get_template_part('content','single.php');
    }

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

  • 4
    in_category() * – Avishay28 Apr 19 '16 at 9:42
2

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"; 
    if($cat->parent)
    {
      $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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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