How to display two different custom taxonomy terms on a WooCommerce single product page

Our WooCommerce products have two custom taxonomies: sizes and colors.

I’m trying to display the custom toxonomy terms for a product on its single product page. I’m using the woocommerce_single_product_summary action hook. I can’t get both taxonomies to display at the same time.

Here’s my code so far:

<?php
/**
 * display a woocommerce product's custom taxonomy terms on single product pages
 */

function display_single_product_sizes_after_summary() { 
    global $post;
    
    $size_terms = get_the_terms( $post->ID , array( 'sizes') );
    // begin creating html markup
    $size_markup = '';
    if(!empty($size_terms)) {
        $size_markup .= "<p>Similar size shades: ";
    }
    // init counter
    $is = 1;
    foreach ( $size_terms as $size_term ) {
        $size_markup .= '<a href="/shades/size/' . $size_term->slug . '">' . $size_term->name . '</a>';
        //  Add comma (except after the last item)
        $size_markup .= ($is < count($size_terms))? ", " : "";
        // Increment counter
        $is++;
        //finish the markup
        if(!empty($size_terms)) {
            $size_markup .= "</p>";
        }
    }
    echo $size_markup;
};

function display_single_product_colors_after_summary() { 
    global $post;
    
    $color_terms = get_the_terms( $post->ID , array( 'colors') );
    // begin creating html markup
    $color_markup = '';
    if(!empty($color_terms)) {
        $color_markup .= "<p>Similar color shades: ";
    }
    // init counter
    $ic = 1;
    foreach ( $color_terms as $color_term ) {
        $color_markup .= '<a href="/shades/color/' . $color_term->slug . '">' . $color_term->name . '</a>';
        //  Add comma (except after the last item)
        $color_markup .= ($ic < count($color_terms))? ", " : "";
        // Increment counter
        $ic++;
        //finish the markup
        if(!empty($color_terms)) {
            $color_markup .= "</p>";
        }
    }
    echo $color_markup;
};

function display_single_product_terms_after_summary() {
    display_single_product_sizes_after_summary();
    display_single_product_colors_after_summary();
};
add_action( 'woocommerce_single_product_summary', 'display_single_product_terms_after_summary', 101, 0 );
?>

This outputs the following:

Similar size shades: Small

Similar color shades:

If I reverse the order of the two sub-functions in display_single_product_traits_after_summary the output changes to:

Similar color shades: Blue

Similar size shades:

I’ve tried to use a reset at the end of each subfunction. I’ve tried:

    echo $size_markup;
    wp_reset_postdata();

and:

    echo $color_markup;
    wp_reset_postdata();

This makes no difference.

I’ve also tried:

    echo $size_markup;
    rewind_posts();

and:

    echo $color_markup;
    rewind_posts();

This breaks the page altogether.

What is my mistake here, and how can I get the terms from both taxonomies to display?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The WordPress documentation shows that an array is an acceptable argument for the taxonomy in get_the_terms (https://developer.wordpress.org/reference/functions/get_the_terms/). An array works if you are trying to get multiple taxonomies. It even works if you are trying to get just one taxonomy. But getting two single taxonomy arrays sequentially is what breaks this code.

In the originally posted code, replacing this:

$size_terms = get_the_terms( $post->ID , array( 'sizes') );

with this instead:

$size_terms = get_the_terms( $post->ID , 'sizes' );

And also replacing this:

$color_terms = get_the_terms( $post->id , array( 'colors') );

with this instead:

$color_terms = get_the_terms( $post->id , 'colors' );

solves the problem.

Another alternative that works is to retrieve both sets of taxonomy terms at once, and then tease apart the WP_Term Object to find exactly what you want. This is probably the better solution in most cases.

function display_single_product_taxonomy_terms() {
    global $post;
    
    $tax_terms = get_the_terms( $post->ID , array( 'sizes','colors') );
    // create the markup variables
    $color_markup = '';
    $size_markup = '';
    // init counters
    $color_counter = 0;
    $size_counter = 0;
    
    foreach ( $tax_terms as $tax_term ) {
        if( $tax_term->taxonomy == 'colors' ) {
            // this is a colors term; increment color counter
            $color_counter++;
            // add to color markup
            $color_markup .= ($color_counter > 1)? "; " : "";
            $color_markup .= '<a href="/shades/color/' . $tax_term->slug . '">' . str_replace(", and,"," and",str_replace("-", ", ", $tax_term->slug)) . '</a>';
        } else {
            // this is a sizes term; increment size counter
            $size_counter++;
            // add to size markup
            $size_markup .= ($size_counter > 1)? "; " : "";
            $size_markup .= '<a href="/shades/size/' . $tax_term->slug . '">' . str_replace("-", " ", $tax_term->slug) . '</a>';
        }
    };
    
    echo '<div class="single-product-taxonomy-terms">' . PHP_EOL;
    if ( $size_counter > 0 ) {
        echo '<p>'. __("Similar size shades: ","bright-side") . $size_markup . '</p>' . PHP_EOL;
    };
    if ( $color_counter > 0 ) {
        echo '<p>' . __("Similar color shades: ","bright-side") . $color_markup . '</p>' . PHP_EOL;
    };
    echo '</div>' . PHP_EOL;
};
add_action( 'woocommerce_single_product_summary', 'display_single_product_taxonomy_terms', 101, 0 );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x