admin管理员组

文章数量:1333442

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?

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?

Share Improve this question asked Jul 3, 2020 at 15:32 hommealonehommealone 851 silver badge10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

The WordPress documentation shows that an array is an acceptable argument for the taxonomy in get_the_terms (https://developer.wordpress/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 );

本文标签: hooksHow to display two different custom taxonomy terms on a WooCommerce single product page