Display some data in a specific html structure for simple and variable products

In WooCommerce, I would like to create a function that displays a simple “list” of data for each variant or variable product. Or, if a simple product, then the details of the product itself. Details that I need to include for each is: regular price, size attribute(used for options) sale price, stock.

This is for the "catalog" version of the WooCommerce product pages, so there will be no actual "Add to Cart" or "Change" button. Instead, I want to provide the user with information about each product / variation.

I need to output the data of each of them as list items in <ul>. New <ul>for every option.

Product example with three options:

<div class="fs-product-data-wrapper">
  <ul>
    <li class="fs-data-price">$49.98 ea.</li>
    <li class="fs-data-size">Size: 15-18"</li>
    <li class="fs-data-sale">$49.98 ea. Preferred Customer Price</li>
    <li class="fs-data-stock">Quantity in Stock: 40</li>
  </ul>
  <ul>
    <li class="fs-data-price">$799.98 ea.</li>
    <li class="fs-data-size">Size: 2-2.5'</li>
    <li class="fs-data-sale">$67.98 ea. Preferred Customer Price</li>
    <li class="fs-data-stock">Quantity in Stock: 15</li>
  </ul>
  <ul>
    <li class="fs-data-price">$29.98 ea.</li>
    <li class="fs-data-size">Size: 12"</li>
    <li class="fs-data-sale">$19.98 ea. Preferred Customer Price</li>
    <li class="fs-data-stock">Quantity in Stock: 0</li>
  </ul>
</div>

The product example is unchanged, but it is just a simple product:

<div class="fs-product-data-wrapper">
  <ul>
    <li class="fs-data-price">$99.98 ea.</li>
    <li class="fs-data-size">Size: 15-18"</li>
    <li class="fs-data-sale">$99.98 ea. Preferred Customer Price</li>
    <li class="fs-data-stock">Quantity in Stock: 32</li>
  </ul>
</div>

Example screenshot:

Example screenshot

I can control CSS. I just need the ability to create this data within ulfor each option. Ideally, this can also be done using short code, as I will fill it with the page builder template. But I could do this if he hooks onto an existing product page hook. Maybe woocommerce_after_single_product.

+4
source share
2 answers

The following is a way to display some specific formatted product data for simple and variable products:

// Utility funtion: getting and formtting product data
function format_product_data_output( $the_id ){
    $empty =  __( '<em>(empty)</em>', 'woocommerce' );

    // Get an instance of the WC_Product_Variation object
    $product = wc_get_product( $the_id );

    // Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
    $price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
    $sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
    $sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;

    $size = $product->get_attribute( 'pa_size' );
    $size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;

    $stock_qty = $product->get_stock_quantity();
    $stock_qty = ! empty( $stock_qty ) ? $stock_qty : $empty;

    $output = '
    <ul>
        <li class="fs-data-price">'.$price.'</li>
        <li class="fs-data-size">Size: '.$size.'</li>
        <li class="fs-data-sale">'.$sale_price.' Preferred Customer Price</li>
        <li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
    </ul>';

    return $output;
}

//
add_action( 'woocommerce_after_single_product', 'custom_table_after_single_product' );
function custom_table_after_single_product(){
    global $product;

    $output = '<div class="fs-product-data-wrapper">';

    // Variable products
    if( $product->is_type('variable'))
    {
        // Get available variations in the variable product
        $available_variations = $product->get_available_variations();

        if( count($available_variations) > 0 ){
            foreach( $available_variations as $variation )
                $output .= format_product_data_output( $variation['variation_id'] );
        }
    }
    // Simple products
    elseif( $product->is_type('simple'))
    {
        $output .= format_product_data_output( $product->get_id() );
    }
    else return; // Exit

    echo $output .= '</div>'; // Display
}

function.php ( ). .

CSS ( ). , , .

+1

,

enter image description here

, functions.php ( )

/**
 * Display list data after single product
 */
function display_list_after_single_product() {
    $product_data = get_product_data();

    ?>
    <div class="fs-product-data-wrapper">
    <?php
        if ( isset( $product_data['price'] ) ) {
            ?>
            <ul>
            <?php
                ?>
                <li class="fs-data-price"><?php echo $product_data['price'] ?></li>
                <li class="fs-data-size"><?php echo $product_data['size'] ?></li>
                <li class="fs-data-sale"><?php echo $product_data['sale_price'] ?></li>
                <li class="fs-data-stock"><?php echo $product_data['stock'] ?></li>
            </ul>
            <?php
        } else {
            foreach ( $product_data as $data ) {
                ?>
                <ul>
                <?php
                    ?>
                    <li class="fs-data-price"><?php echo $data['price'] ?></li>
                    <li class="fs-data-size"><?php echo $data['size'] ?></li>
                    <li class="fs-data-sale"><?php echo $data['sale_price'] ?></li>
                    <li class="fs-data-stock"><?php echo $data['stock'] ?></li>
                </ul>
                <?php
            }
        }
    ?>
    </div>
    <?php

}
add_action( 'woocommerce_after_single_product', 'display_list_after_single_product' );

/**
 * Collect product data depending on product type
 *
 * @return array $product_arr
 */
function get_product_data() {
    global $product;
    if( $product->is_type( 'variable' ) ) {
        $variation_arr = [];
        $imp_variations = $product->get_available_variations();
        foreach ( $imp_variations as $key => $prod_var_arr ) {

            $variation_obj = new WC_Product_variation($prod_var_arr["variation_id"]);
            // collect reqired variation data to array
            $product_arr[] = [
                'price'      => $variation_obj->get_regular_price(),
                'sale_price' => $variation_obj->get_sale_price(),
                'size'       => $prod_var_arr['attributes']['attribute_pa_size'],
                'stock'      => $variation_obj->get_stock_quantity(),
            ];
        }
    } else if( $product->is_type( 'simple' ) ) {
        $terms = $product->get_attributes()["pa_size"]->get_terms();

        $product_arr = [
            'price'      => $product->get_regular_price(),
            'sale_price' => $product->get_sale_price(),
            'size'       => $terms[0]->name,
            'stock'      => $product->get_stock_quantity(),
        ];
    }

    return $product_arr;
}

, .

+1

Source: https://habr.com/ru/post/1695554/


All Articles