What I’m trying to do is display a menu in my Woocommerce shop’s sidebar with the current product category name and current categories children. If the product category has no children, then it should display the parent category and parent category children.
This is how the hierarchy looks:
SHOP > PREPARED FOODS > FOODSTUFF
When you are on the PREPARED FOODS page you should see.
Prepared Foods
- Bitters
- Charcuterie
- Foodstuff
When you are on the FOODSTUFF page you should see
Prepared Foods
- Bitters
- Charcuterie
- Foodstuff
Right now I’ve gotten it to display the parent category links when you are in the top level category, but I haven’t gotten it to display the parent category name when you are in the top level. Here is the code I have so far:
<?php
$queried_object = get_queried_object();
if ( is_product_category() && is_a($queried_object, 'WP_Term') ) {
$taxonomy = $queried_object->taxonomy;
echo '<h2 class="shop__sidebar-heading">
<a href="' . get_term_link( $queried_object ) . '">' . $queried_object->name . '</a>
</h2>';
}
?>
<?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'>" . "</span>"; ?></a></li>
<?php }
}
?>
An example of what I’m trying to achieve can be see on the Food52 website sidebar https://food52.com/shop/pantry
2
Answers
I’ve taken the liberty to clean up a few things along the way (such as removing some unnecessary open/closing PHP tags) and some clarifying things – I hope you don’t mind! Going through your existing code:
You shouldn’t need to check
is_a()
on the queried object (also, consider usinginstanceof
instead, as it has lower overhead since it’s a language construct and not a function:if($queried_object instanceof WP_Term){}
. Still, you shouldn’t need to check it becauseis_product_category()
runs theis_tax()
function which should handle that for you.You seem to have an unused
$taxonomy
declarationIt’s less important on WordPress supplied functions, but it’s good to get into the habit of using
esc_url
andesc_attr
on attribute fields.You’ve got some redundancy issues with getting the
$term
set. It also seems like you could/should move these up into your outerif
statement since you’re already checking to see if it’s aWP_Term
object, so you shouldn’t have to worry about things not being set or redefining values from it. Also your$term
and$termid
declarations are a bit mixed, it seems like they are flipped ($term
is the ID and$termid
is the actual object)You seem to be creating two separate loop argument arrays (and subsequent loops) for no real reason, other than changing variable names – based just on if it’s a toplevel term or not (parent_id > 0)
You add have a conditional
<li>
that doesn’t take advantage of the conditional check if it’s the currentWP_Term
being queried; Did you mean to add anactive
class or something in there?You don’t appear to have a
<ul>
to contain the<li>
elements. I’ve added that in conditionally based on the results ofget_terms
for the child/sibling terms loop.I’m familiar with WooCommerce, but don’t currently have it installed on my dumping ground site, but I’ve recreated the category (
product_cat
) structure from it and used this code (just with the taxonomy changed) and it appears to do what you’ve asked:A few notes:
I’ve replaced a lot of the
echo
s withprintf()
. It may look a little daunting, but it removes the need for the mix of PHP Escapes and string concatenation that you have. It also makes it easier to pass functions and Ternary Operators to it.%s
, in order, with that value.Ternary Operators are basically a succinct, one line, "if/else" statement. This lets you check for the
active
WP_Term in the same declaration as the other terms really easily.Here are a few links to show you it’s working (scroll to the bottom of the page):
Foods)
Foodstuff)
level)
term)
You can get category and child category using following code. You need to call the following functions according to your needs and pass parameters.