WooCommerce Sidebar – If It Is A Top Level Category, Show Children, Otherwise Show Siblings!

A tale by

Amy Nortje

Recently, I ran into a snag when building a WooCommerce site for a client. We needed a WooCommerce sidebar to show the product categories. Simple right? Well not exactly, the designer wanted the sidebar to show the subcategories of the current category you are viewing. I know that WooCommerce had a widget to do this, and when I added it to my sidebar it all looked great. However, when I went to a category that had no subcategories, the WooCommerce widget would just disappear… what a nuisance. What we really needed the sidebar to do was simple:

If the current category is a top-level category, list the children categories in the sidebar:

  • Child 1
  • Child 2
  • Child 3

But if the current category is not a top-level category, it must instead show its sibling categories:

  • Sibling 1
  • Sibling 2
  • Sibling 3

I was rather surprised and disappointed that the native WooCommerce category widget didn’t do this. Having the sidebar just go blank every time there are no sub categories is definitely not ideal. So, I decided to write some code of my own to achieve this and though I would share it as this might be useful to someone trying to achieve the same thing. It is just for a simple sidebar and one level of children categories.

First of all, I needed to work with the taxonomy term “product_cat” in order to call WooCommerce product categories. So I just used the get_term function to find the current category. I added the following to my theme:

<?php  	
   $term = get_queried_object()->term_id;
   $termid = get_term($term, 'product_cat' );
 ?>

I suppose there are a number of ways to do this going forward, but I found the best way to suit my needs was to find out if the term had a parent term or not. I needed to figure out:

If the current category has a parent category, get the sibling categories and display each in a list item.

ELSE display the children of the current category each in a list item.

So I started with an “if statement” (advanced stuff, I know). It checks to see if the id of the parent is greater than 0 or not. Obviously, if there is no parent the id would be nothing.

if($termid->parent > 0) { 
  /* Show siblings */
} else {
  /* Show children */
}

Next, I added the get_terms function into each if statement to get the sibling or child depending on the value of the parent id. If the value of the parent ID was greater than 0, I used get_terms to list the children of the PARENT category. These would be the SIBLINGS of the current category.

If the value of the parent ID was 0, I used the get_terms function to list the children of the CURRENT category.

<?php 
if($termid->parent > 0) { 
    $args = array(
        'orderby'       => 'name', 
        'order'         => 'ASC',
        'hide_empty'    => false, 
        'child_of'      => $termid->parent,
    ); 

    $siblingproducts = get_terms( 'product_cat', $args);

    foreach ($siblingproducts as $siblingproduct) { ?>        
        <li><a href="<?php echo get_term_link( $siblingproduct ); ?>"><?php echo $siblingproduct->name; ?><?php echo "<span class='count'>" .  $siblingproduct->count . "</span>"; ?></a></li>
<?php }

} else { 
    $args = array(
        'orderby'       => 'name', 
        'order'         => 'ASC',
        'hide_empty'    => false, 
        'child_of'      => $term 
    ); 

$subproducts = get_terms( 'product_cat', $args);

foreach ($subproducts as $subproduct) { ?>

    <li><a href="<?php echo get_term_link( $subproduct ); ?>"><?php echo $subproduct->name; ?><?php echo "<span class='count'>" . $subproduct->count . "</span>"; ?></a></li>
<?php }

}
?>

Lastly, I decided that I wanted to highlight the list item that is the current category when I am displaying siblings. Just to add a nice touch to the navigation.

if ($siblingproduct->term_id == $term ) {  ?>
   <li class="currentterm">
<?php } else { ?>    
   <li>
<?php } ?>

So my final code looks like this:

<?php 

$term = get_queried_object()->term_id;
$termid = get_term($term, 'product_cat' );

if($termid->parent > 0) 
    { 
        $args = array(
            'orderby'       => 'name', 
            'order'         => 'ASC',
            'hide_empty'    => false, 
            'child_of'      => $termid->parent,
    ); 

    $siblingproducts = get_terms( 'product_cat', $args);

    foreach ($siblingproducts as $siblingproduct) { 
         if ($siblingproduct->term_id == $term ) {  ?>
            <li>
    <?php } else { ?>    
            <li>
    <?php } ?>    

        <a href="<?php echo get_term_link( $siblingproduct ); ?>"><?php echo $siblingproduct->name; ?><?php echo "<span class='count'>" .  $siblingproduct->count . "</span>"; ?></a></li>
<?php }

    } else { 
        $args = array(
            'orderby'       => 'name', 
            'order'         => 'ASC',
            'hide_empty'    => false, 
            'child_of'      => $term 
        ); 

    $subproducts = get_terms( 'product_cat', $args);

    foreach ($subproducts as $subproduct) { ?>
        <li> <a href="<?php echo get_term_link( $subproduct ); ?>"><?php echo $subproduct->name; ?><?php echo "<span class='count'>" . $subproduct->count . "</span>"; ?></a></li>
<?php }

}
?>

I hope that this little blog post is helpful to anyone who ran into the same snag as me! If you found this helpful, have any suggestions or know of a better way to do this then please comment below!

Share this: