Custom Single Post By Category

I’m trying to get up to speed with the terminology of the ins and outs of WordPress, so apologies.

I’m setting up a full site utilizing WordPress and a custom template, basing it on TwentyTen underpinnings.

Read More

I’m trying to have as much as possible under the “post” Post Type, and the top level “list” pages just be the category pages.

One category is “work”

I’ve been able to customize those by making custom category-work.php and loop-work.php files. But how do I go about making a custom single post by category?

It looks like making a single-work.php would look for a custom post type called “work.” Is there a way to make a single.php modified clone that is triggered by category / category slug?

Related posts

Leave a Reply

2 comments

  1. Make your single.php the following:

    <?php
    $post = $wp_query->post;
    
    if ( in_category( 'work' ) ) {
      include( TEMPLATEPATH.'/single-work-cat.php' );
    } 
    else {
      include( TEMPLATEPATH.'/single-generic.php' );
    }
    ?>
    

    and make single-work-cat.php the template you wish to show for single work category posts, and single-generic.php the one you wish to show in all other cases. For more categories just add more elseif statements and make new single templates.

  2. I realize this is an old question, but in case anyone else finds whilst searching the same topic, be aware that you should not use include statements in your WordPress themes. Always use get_template_part() or locate_template() instead.

    (see http://make.wordpress.org/themes/guidelines/guidelines-theme-check/)

    The following code uses WordPress filters to accomplish the task and will automatically search for templates for any and all categories:

    /**
     * Replace "themeslug" with your theme's unique slug
     *
     * @see http://codex.wordpress.org/Theme_Review#Guidelines
     */
    add_filter( 'single_template', 'themeslug_single_template' );
    
    /**
     * Add category considerations to the templates WordPress uses for single posts
     *
     * @global obj $post The default WordPress post object. Used so we have an ID for get_post_type()
     * @param string $template The currently located template from get_single_template()
     * @return string The new locate_template() result
     */
    function themeslug_single_template( $template ) {
        global $post;
    
        $categories = get_the_category();
    
        if ( ! $categories )
            return $template; // no need to continue if there are no categories
    
        $post_type = get_post_type( $post->ID );
    
        $templates = array();
    
        foreach ( $categories as $category ) {
    
            $templates[] = "single-{$post_type}-{$category->slug}.php";
    
            $templates[] = "single-{$post_type}-{$category->term_id}.php";
        }
    
        // remember the default templates
    
        $templates[] = "single-{$post_type}.php";
    
        $templates[] = 'single.php';
    
        $templates[] = 'index.php';
    
        /**
         * Let WordPress figure out if the templates exist or not.
         *
         * @see http://codex.wordpress.org/Function_Reference/locate_template
         */
        return locate_template( $templates );
    }
    

    There are a couple of weak points in the code. First, it means that WordPress performs locate_template() twice for single posts (once before this function runs, and once during). Second, I don’t think there is a clean way to prioritize which categories to look up first. This means that if your post is in multiple categories that have unique single post templates, you won’t get to choose which template is used.