Category template to show different categories based on parent

Ok so i’ve got categories like setup like this.

Products
   Category A
       Sub Category 1
       Sub Category 2
   Category B
   Category C

What i need is to have the Products category page showing the main Categories (A,B,C).

Read More

The main Category pages (A,B,C) showing their sub Categories (1,2).

Then the Sub Categories (1,2) showing my custom post type i.e the actual products.

I want to avoid using a category-slug.php template because when someone adds a new category i want it to show automatically on the correct page, based on what the parent is.

I thought about using a category.php template but i don’t know if this is possible from one template or what code i would need.

The first category pages (Products) will only display the main Categories (A,B,C). It won’t be showing any posts just a list of category links in the main section. So i can style them so they are like big buttons on the page. The same will be for Category A,B,C. Show the sub categories.

The last category page (sub category 1,2) will show my custom post type (the actual products) in some sort of list. This page won’t show any other categories just the Products in the main section.

Any help on how i can achieve this would be appreciated.

Thanks

UPDATE:
I’ve managed to get the category template to show the right categories. It seems to be working but i’ve not tested it properly yet.

The problem i now have is displaying my custom post types on the deepest level categories. So it will show things like the custom post type title, thumbnail, maybe an excerpt.

Here’s the code i’m using.

<?php // list child categories
$cat_id = get_query_var('cat');

$catlist = wp_list_categories('depth=1&hide_empty=0&echo=0&orderby=id&title_li=&child_of=' . $cat_id);

if ($catlist) {
echo $catlist;
} else {
echo "Please don't print No categories";
} ?>

Currently on the deepest level category page it just displays ‘No Categories’. I need to get that page showing my custom post types that belong to that category.

Related posts

Leave a Reply

2 comments

  1. I managed to do something like you are describing, but for a custom taxonomy.. with a little snippet of extra code. No doubt there is a much better way to write the code, and on top of that there is most likely a much more efficient way to accomplish this.

    But this worked, and is working on an active website. I will describe what I did and you can modify the code for your own needs:

    My problem:
    Like you, I wanted a universal page that would show whatever taxonomy term I sent to it, instead of having to create a taxonomy-slug.php file for every new term in my taxonomy.
    To clarify: my Custom Post Type is Videos, and my custom taxonomy is Video Types

    My solution
    I managed to grab the taxonomy term from the listing of that taxonomy(grabs when someone clicks on that term) and then sends it to an archive page for that particular custom post type. It reads that term and then just shows the post type using that taxo0nmy term

    My Code
    Found this on the web somewhere. It gets pasted into the functions file:

    /*add a filter to pass queries to pages
    can be sent like so: <?= add_query_arg('t', 'argument', home_url( '/videos/' )); ?>
    can be called like so:  $qvar = get_query_var('t');
    */
    add_filter('query_vars', 'p_query');
    
        function p_query($qvars) {
            $qvars[] = 't';
            return $qvars;
        }
    

    On the home-page, I list all of the different “Video Types” as clickable links using a wp-query to show the latest post for each of the different terms in the taxonomy.

    The Query

    $term_args=array(
        'orderby' => 'menu_order',
        'order' => 'DESC'
    );
    $terms = get_terms($taxonomy,$term_args);
    if ($terms) {
      foreach( $terms as $term ) {
        $args=array(
          'post_type' => 'videos',
          'video_types' =>  $term->name ,
          'post_status' => 'publish',
          'posts_per_page' => 1,
          'caller_get_posts'=> 1
          );
        $my_query = null;
        $my_query = new WP_Query($args); 
        if( $my_query->have_posts() ) {  ?>
           <div class="thumb">
            <h3 class="darken"><?php echo $term->name;?></h3>
    
            <?php
          while ($my_query->have_posts()) : $my_query->the_post(); ?>
    

    The Links
    I then make each term in the loop a link like so:

    <a href="<?= add_query_arg('t', strtolower($term->name), home_url( '/videos/' )); ?>">
     <h3><?php echo $term->name;?></h3>
    </a>
    

    which then sends that term name along with the URL to the archives-video.php page. The link ends up looking like this:

    http://thedomainname/videos/?t=theterm

    And then the code on the archives-videos.php page looks like this:

    The Archives page

    <?php 
    
        $taxonomy = 'video_types';
        $qvar = get_query_var('t');
        $orderby      = 'name';
        $show_count   = 0;      // 1 for yes, 0 for no
        $pad_counts   = 0;      // 1 for yes, 0 for no
        $hierarchical = 1;      // 1 for yes, 0 for no
        $title        = '';
        $empty        = 0;
    
        $term = get_term_by('name', $qvar, $taxonomy);
    
      $args=array(  
        'taxonomy'     => $taxonomy, 
        'video_types'  => $qvar,
        'orderby'      => $orderby,
        'show_count'   => $show_count,
        'pad_counts'   => $pad_counts,
        'hierarchical' => $hierarchical,
        'title_li'     => $title,
        'hide_empty'   => $empty,
        'posts_per_page' => 8,
        );
    
            query_posts( $args); ?>
    
    
    
    
           <div class="vdescription">
            <h3 class="pagetitle"><?php echo $term->name;?></h3>
    
            <?php
                $termDiscription = $term->description;
                    if($termDiscription != '') : ?>
                        <p><?php echo $termDiscription; ?></p>
                    <?php endif; ?>
            </div>  <!--.vdescription -->
    

    and below that I can list all of the videos in that particular taxonomy-term:

    <?php while (have_posts()) : the_post(); ?>
    
        <?php the_post_thumbnail(); ?>
    
    <?php endwhile;?>
    

    So that gives me a universal page that will show whatever video-type I send to it..which allows the website owner to create whatever new video-type they want, which will automatically display on the home-page as a link.

    Again, I think someone with a better working knowledge of PHP could write this in a better way (which I would love to see) but the idea is there and working.

  2. After searching the internet for some time I’ve finally got it working.

    This goes in the functions.php

    function category_has_children() {
    global $wpdb;
    $term = get_queried_object();
    $category_children_check = $wpdb->get_results(" SELECT * FROM wp_term_taxonomy WHERE parent = '$term->term_id' ");
         if ($category_children_check) {
              return true;
         } else {
              return false;
         }
    }
    

    This goes into the category.php template

    <?php
    
    if (!category_has_children()) {?>
    <?php foreach(get_the_category() as $category) {
    $cat = $category->cat_ID; }?>
    <?php query_posts('post_type=Product&cat=' .$cat .'&order=ASC'); ?>
                <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
                <p><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></p>
                        <?php endwhile;?>
            <?php endif; ?> 
    <?php get_template_part('loop', 'index');
    } else {?>
    
    <?php 
    $cat_id = get_query_var('cat');
    $catlist = get_categories('child_of=' . $cat_id);
    if ($catlist) {
    wp_list_categories('depth=1&hide_empty=0&echo=1&orderby=id&title_li=&child_of=' . $cat_id);
    } 
    }
    ?>
    

    This code will display sub categories if a category has one, if it doesn’t have a sub category it will display post for that category, in my case products. If a category doesn’t have any sub categories and doesn’t have any posts it won’t display anything.