Home > Enterprise >  How to extend the "variation.php" template file with available or custom data in WooCommer
How to extend the "variation.php" template file with available or custom data in WooCommer

Time:08-13

I want to customize the variation.php file in WooCommerce

Path : /themes/theme-child/woocommerce/single-product/add-to-cart/variation.php

I want to remove the part that shows the price and show my custom data instead:

<div >{{{ data.variation.price_html }}}</div>

Now i want to put the regular price, the sale price, the on sale from and on sale to date of each variable. That is, when each variable is selected, display the desired data.

I did this easily for the simple product, but I don't know how to get the regular price, sale price, etc.. of the variable product, so that when you go to each variable, the data of that variable will be displayed.

In my search for an answer I found:

Unfortunately this doesn't fully answer my question.


For example: I want to show the regular price and sale price of each variable, that's mean:

  • Variable 1 : regular price = $20 | sale price = $15
  • Variable 2 : regular price = $30 | sale price = $20
  • Variable 3 : regular price = $40 | sale price = $25

If the user selects variable 1, it will show the regular price of $20 and the sale price of $15. Any advice?

CodePudding user response:

What should be mentioned first of all is that the variation.php template file is slightly different from the other WooCommerce template files, this because it is a javascript-based template.

See: https://codex.wordpress.org/Javascript_Reference/wp.template

The code below is taken from the /single-product/add-to-cart/variation.php template file (line 16-20 @version 2.5.0)

<script type="text/template" id="tmpl-variation-template">
    <div >{{{ data.variation.variation_description }}}</div>
    <div >{{{ data.variation.price_html }}}</div>
    <div >{{{ data.variation.availability_html }}}</div>
</script>

The intention is to extend this file in the same syntax or to apply the same methods!


The get_available_variation() function from /includes/class-wc-product-variable.php (line 346-394 @version 3.0.0) plays an important role in it:

/**
 * Returns an array of data for a variation. Used in the add to cart form.
 *
 * @since  2.4.0
 * @param  WC_Product $variation Variation product object or ID.
 * @return array|bool
 */
public function get_available_variation( $variation ) {
    if ( is_numeric( $variation ) ) {
        $variation = wc_get_product( $variation );
    }
    if ( ! $variation instanceof WC_Product_Variation ) {
        return false;
    }
    // See if prices should be shown for each variation after selection.
    $show_variation_price = apply_filters( 'woocommerce_show_variation_price', $variation->get_price() === '' || $this->get_variation_sale_price( 'min' ) !== $this->get_variation_sale_price( 'max' ) || $this->get_variation_regular_price( 'min' ) !== $this->get_variation_regular_price( 'max' ), $this, $variation );

    return apply_filters(
        'woocommerce_available_variation',
        array(
            'attributes'            => $variation->get_variation_attributes(),
            'availability_html'     => wc_get_stock_html( $variation ),
            'backorders_allowed'    => $variation->backorders_allowed(),
            'dimensions'            => $variation->get_dimensions( false ),
            'dimensions_html'       => wc_format_dimensions( $variation->get_dimensions( false ) ),
            'display_price'         => wc_get_price_to_display( $variation ),
            'display_regular_price' => wc_get_price_to_display( $variation, array( 'price' => $variation->get_regular_price() ) ),
            'image'                 => wc_get_product_attachment_props( $variation->get_image_id() ),
            'image_id'              => $variation->get_image_id(),
            'is_downloadable'       => $variation->is_downloadable(),
            'is_in_stock'           => $variation->is_in_stock(),
            'is_purchasable'        => $variation->is_purchasable(),
            'is_sold_individually'  => $variation->is_sold_individually() ? 'yes' : 'no',
            'is_virtual'            => $variation->is_virtual(),
            'max_qty'               => 0 < $variation->get_max_purchase_quantity() ? $variation->get_max_purchase_quantity() : '',
            'min_qty'               => $variation->get_min_purchase_quantity(),
            'price_html'            => $show_variation_price ? '<span >' . $variation->get_price_html() . '</span>' : '',
            'sku'                   => $variation->get_sku(),
            'variation_description' => wc_format_content( $variation->get_description() ),
            'variation_id'          => $variation->get_id(),
            'variation_is_active'   => $variation->variation_is_active(),
            'variation_is_visible'  => $variation->variation_is_visible(),
            'weight'                => $variation->get_weight(),
            'weight_html'           => wc_format_weight( $variation->get_weight() ),
        ),
        $this,
        $variation
    );
}

The $variation_data from that function is passed/converted to the variation.php template file, by default variation_description, price_html and availability_html are used in the variation.php template file.

However, in the above function you see that by default much more data is passed such as attributes, backorders_allowed, etc..

For example, if you change the code in the variation.php template file (follow the appropriate method to overwrite template files) to:

<script type="text/template" id="tmpl-variation-template">
    <div >{{{ data.variation.variation_description }}}</div>
    <div >{{{ data.variation.price_html }}}</div>
    <div >{{{ data.variation.availability_html }}}</div>
    <div >{{{ data.variation.display_regular_price }}}</div>
    <div >{{{ data.variation.display_price }}}</div>
</script>

You will see that automatically the display_price and the display_regular_price are now also displayed. This is because it was already available by default.


But what if you want to display data that is not available by default?

For that you can use the woocommerce_available_variation filter hook and then edit the variation.php template file:

Step 1) code goes in functions.php file of the active child theme (or active theme)

function filter_woocommerce_available_variation( $variation_data, $product, $variation ) {
    // Add extra data
    $variation_data['my_custom_data'] = __( 'My custom data', 'woocommerce' );

    return $variation_data;
}
add_filter( 'woocommerce_available_variation', 'filter_woocommerce_available_variation', 10, 3 );

Step 2) add the following line in the variation.php template file:

<div >{{{ data.variation.my_custom_data }}}</div>

The result is that our custom data now is displayed, only this is the same for each variation. To avoid this, we can use can use the extra arguments that are passed to the woocommerce_available_variation filter hook, namely $product and $variation.


Let's say we want to use date_on_sale_from and date_on_sale_to for each variation, if set. Then you get:

Step 1) code goes in functions.php file of the active child theme (or active theme)

function filter_woocommerce_available_variation( $variation_data, $product, $variation ) {
    // Getters: when NOT empty, add value
    $date_on_sale_from = ! empty( $variation->get_date_on_sale_from() ) ? $variation->get_date_on_sale_from() : '';
    $date_on_sale_to = ! empty( $variation->get_date_on_sale_to() ) ? $variation->get_date_on_sale_to() : '';

    // Push
    $variation_data['date_on_sale'] = array(
        'from' => $date_on_sale_from,
        'to'   => $date_on_sale_to,
    );

    return $variation_data;
}
add_filter( 'woocommerce_available_variation', 'filter_woocommerce_available_variation', 10, 3 );

What as a result will add the following to the $variation_data:

[date_on_sale] => Array
    (
        [from] => WC_DateTime Object
            (
                [utc_offset:protected] => 0
                [date] => 2022-08-12 00:00:00.000000
                [timezone_type] => 3
                [timezone] => Europe/Brussels
            )

        [to] => WC_DateTime Object
            (
                [utc_offset:protected] => 0
                [date] => 2023-03-01 23:59:59.000000
                [timezone_type] => 3
                [timezone] => Europe/Brussels
            )

    )

As you can see, this data not only contains the dates but additional information that we can use if desired.

Step 2) add/change the following lines in the variation.php template file:

<script type="text/template" id="tmpl-variation-template">
    <div >{{{ data.variation.variation_description }}}</div>
    <div >{{{ data.variation.price_html }}}</div>
    <div >{{{ data.variation.availability_html }}}</div>
    <div >{{{ data.variation.date_on_sale.from.date }}}</div>
    <div >{{{ data.variation.date_on_sale.to.date }}}</div>
</script>

In short, what is used in the filter hook as naming, to extend $variation_data should also be used in the template file.

  • Related