skip to Main Content

I have some custom code that creates a shortcode in WordPress/Woocommerce that I use to display the product dimensions (Length, Width, Height) – the output works fine however I would like to change the label for ‘Length‘ to read ‘Depth‘ (front end only is fine) and re-order the output to display as Height, Width, Depth (in that order)

Here is my code to create the shortcode – however, I am unsure what I need to do to change the output label & to re-order them.

add_shortcode( 'product_taxonomies', 'product_taxonomies_shortcode' );
function product_taxonomies_shortcode( $atts ){
    // Shortcode Attributes
    $atts = shortcode_atts( array(
        'id' => '',
    ), $atts, 'product_taxonomies' );

    $product_id = ! empty($atts['id']) ? $atts['id'] : 0;

    if( $product_id > 0 ) {
        $product = wc_get_product( $product_id );
    } else {
        global $product;
    }

    if( ! is_a($product, 'WC_Product' ) ) {
        $product = wc_get_product( get_the_id() );
    }

    if ( is_a($product, 'WC_Product' ) ) {

        ob_start();

        // Weight
        if ( $product->has_weight() ) {
            $weight_unit = get_option('woocommerce_weight_unit');
            $weight_html = '<strong>'.__("Weight").':</strong> ' . $value . $weight_unit;
            echo '<div class="dimensions">' . $weight_html . '</div>';
        }

        // Dimensions
        if ( $product->has_dimensions() ) {
            $dimension_unit = get_option('woocommerce_dimension_unit');
            $dimensions     = array();
            foreach( $product->get_dimensions( false ) as $key => $value ) {
                if( ! empty($value) )
                    $dimensions[] = '<strong>'.ucfirst($key).':</strong> ' . $value . $dimension_unit;
            }
            echo '<div class="dimensions">' . implode('<br>', $dimensions) . '</div>';
        }

        
        return ob_get_clean();
    }
}

3

Answers


  1. Chosen as BEST ANSWER

    I think i've worked it out doing it another way

    function display_product_dimensions( $atts ){
        // Extract shortcode attributes
        extract( shortcode_atts( array(
            'id' => '',
        ), $atts, 'product_dimensions' ) );
    
        if( $id == '' ) {
            global $product;
    
            if( ! is_a($product, 'WC_Product') ) {
                $product = wc_get_product( get_the_id() );
            }
        }
    
        return method_exists( $product, 'get_dimensions' ) ? wc_format_dimensions($product->get_dimensions(false)) : '';
    }
    
    
    add_filter( 'woocommerce_format_dimensions', 'Custom_formated_product_dimentions_with_labels', 10, 2 );
    function Custom_formated_product_dimentions_with_labels( $dimension_string, $dimensions ){
        if ( empty( $dimension_string ) )
            return __( 'N/A', 'woocommerce' );
    
        // Set here your new array of dimensions based on existing keys/values
        $new_dimentions = array(
            '<b>Height:</b>' => $dimensions['height'],
            '<b>Width:</b>'  => $dimensions['width'],
            '<b>Depth:</b>' => $dimensions['length']
        );
    
        $dimensions = array_filter( array_map( 'wc_format_localized_decimal', $new_dimentions ) );
    
        $label_with_dimensions = array();
    
        foreach( $dimensions as $key => $dimention ){
            $dimensions[$key] = ucfirst($key) . ' ' . $dimention . ' ' . get_option( 'woocommerce_dimension_unit' );
        }
    
        return implode( ' <br> ',  $dimensions) . '';
    }
    

    This seems to work and display correctly...


  2. Problem-space

    First, let’s identify the code-range where you need to perform your changes:

            $dimensions     = array();
            foreach( $product->get_dimensions( false ) as $key => $value ) {
                if( ! empty($value) )
                    $dimensions[] = '<strong>'.ucfirst($key).':</strong> ' . $value . $dimension_unit;
            }
            echo '<div class="dimensions">' . implode('<br>', $dimensions) . '</div>';
    

    Perform the changes

            $keys = [
                'Height' => 0,
                'Width' => 0,
                'Depth' => 0
            ];
            $dimensions     = array();
            foreach( $product->get_dimensions( false ) as $key => $value ) {
                if( ! empty($value) ) {
                    $currentKey = (($key === 'Length') ? 'Depth' : $key);
                    $dimensions[$keys[$currentKey]] = '<strong>'.ucfirst($currentKey).':</strong> ' . $value . $dimension_unit;
                }
            }
            echo '<div class="dimensions">' . implode('<br>', $dimensions) . '</div>';
    

    Explanation

    • We map the metrix to their desired array-index, so the array will be build in the correct order instead of having it reordered
    • We replace ‘Length’ with ‘Depth’ if that’s the $key, otherwise use the $key, any replacement being done on the representation level

    Potential problem

    I assumed some concrete key values. If my understanding of them is wrong, then some incorrect values might cause troubles. If that’s the case, let’s discuss the situation you might arrive to.

    Login or Signup to reply.
  3. I know it’s not directly what you were asking for, maybe even off topic on a developer forum. But I wanted to provide a second option: a plugin that allows you to alter strings on your site without editing WordPress core.

    I guess there is a lot of those plugins out there, but one I like is one called Say What

    Best of luck!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search