I'm using this code and getting only a forward slash for results. I'm trying to print the parent category of a WooCommerce product.

$prod_cat = get_category_parents($product->id);
echo $prod_cat;

Any idea how to modify it so it prints the parent categories name?


The get_category_parents is a function that retrieve the parent categories passing as argument a category id.

So, if you have a product and you want to retrieve a list of attached categories to it, the right function is get_the_terms.That function return all the categories objects, without order, and so you can take the first of these categories and call get_category_parents.

Assuming the $product variable contain a post object, you can use

$cats = get_the_terms( $product->ID, 'product_cat' );
echo $cats ? get_category_parents( array_shift($cats)->term_id ) : '';
|improve this answer|||||
  • Thanks for the feed back G.M. - I tried your code but only got a / on the page when I view it. The above code from ialocin works though and it's exactly what I need. I really appreciate the response though. Thank you very much! – lankywood Sep 16 '13 at 20:31
  • worked for me but with array_pop – Jesús Carrera Feb 18 '17 at 20:14

Below code should do what you want, it has the benefit of working in product and product category environments. Besides that it has some options build in, as described under how to use.


function wc_origin_trail_ancestor( $link = false, $trail = false ) {

    if (is_product_category()) {
        global $wp_query;
        $q_obj = $wp_query->get_queried_object();
        $cat_id = $q_obj->term_id;

        $descendant = get_term_by("id", $cat_id, "product_cat");
        $descendant_id = $descendant->term_id;

        $ancestors = get_ancestors($cat_id, 'product_cat');
        $ancestors = array_reverse($ancestors);

        $origin_ancestor = get_term_by("id", $ancestors[0], "product_cat");
        $origin_ancestor_id = $origin_ancestor->term_id;

        $ac = count($ancestors);

    } else if ( is_product() ) {

        $descendant = get_the_terms( $post->ID, 'product_cat' );
        $descendant = array_reverse($descendant);
        $descendant = $descendant[0];
        $descendant_id = $descendant->term_id;

        $ancestors = array_reverse(get_ancestors($descendant_id, 'product_cat'));
        $ac = count($ancestors);


    $c = 1;
    if( $trail == false ){

        $origin_ancestor_term = get_term_by("id", $ancestors[0], "product_cat");
        $origin_ancestor_link = get_term_link( $origin_ancestor_term->slug, $origin_ancestor_term->taxonomy );

        if($link == true) 
            echo '<a href="'. $origin_ancestor_link .'">';
        echo $origin_ancestor_term->name;
        if($link == true) 
            echo '</a>';


        foreach ($ancestors as $ancestor) {
            $ancestor_term = get_term_by("id", $ancestor, "product_cat");
            $ancestor_link = get_term_link( $ancestor_term->slug, $ancestor_term->taxonomy );

            if($c++ == 1) 
                echo '» '; 
            else if($c++ != 1 || $c++ != $ac) 
                echo ' » ';

            if($link == true) 
                echo '<a href="'. $ancestor_link .'">';
            echo  $ancestor_term->name;
            if($link == true) 
                echo '</a>';


        $descendant_term = get_term_by("id", $descendant_id, "product_cat");
        $descendant_link = get_term_link( $descendant_term->slug, $descendant_term->taxonomy );

        echo ' » ';
        if($link == true) 
            echo '<a href="'. $descendant_link .'">';
        echo $descendant->name;
        if($link == true) 
            echo '</a>';



how to use

  • just toplevel, origin ancestor; without link
  • just toplevel, origin ancestor; with link
  • ancestor trail; without link
  • ancestor trail; with link


  • won't work if a product has multiple main-/toplevel-categories, or at least won't show them all;
  • same should be the case for multiple subcategories on the same level;
|improve this answer|||||
  • Awesome! This works perfectly for what I need. I was so far off. PS. I don't get a link or any text when I use the "just toplevel, origin ancestor; with link wc_origin_trail_ancestor(true);" – lankywood Sep 16 '13 at 20:26
  • I spoke too soon :( It works fine mostly but on categories where the subcategory was created after the parent category it shows the subcategory name and not the parent. When I add a new subcategory (called Grand Piano) to a parent category (called New). It displays "Grand Piano" instead of "New" even though "New" is the parent. The rest of the categories/subcategories display fine and like they should. It's only on subcategories with a higher Tag_ID then the parent category. Is there a fix to this? – lankywood Sep 16 '13 at 21:11
  • @lankywood: The link is working fine for me, so I'm not sure about that. But I see where the other problem is you are describing, give me a minute or two, I will update the code. – Nicolai Sep 16 '13 at 21:53

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.