Skip to content

product_variants

The product_variants macro is used to render a set of variants for a given product.

Definition

{% product_variants(product, options) %}

Input parameters

product

Product represents a Product object from ObjectApi.

options

object parameter represents an object of macro options:

Option key Type Default Required Description
options.instanceId string "" yes An id necessary to make internal macro elements unique. Usually it can just be the module instance id
options.moduleTitleInProductVariants string "" yes If specified, a title will appear on top of the product variants
options.noMessages boolean "" yes If specified, potential messages will not appear in a local flash messenger inside this macro
options.groupFlashMessengerName string "" yes Name of the flash messenger that will receive error messages
options.shouldDisplayNonStockOptionsOnly boolean "" yes If set to true only non stock options for a given product will be displayed
options.hidePriceModification boolean "" yes If set to true a price modification resulted from selecting specific variants will not be displayed
options.shouldShowVariantsPriceDifferenceInfo boolean false yes If set to true the additional info about possibility of price differences in variants will be displayed
options.productInstanceKey number "" no Key that allows differentiation of multiple instances of the same product variant on a single page. Without it, the variants may not function correctly.

Example

In this example we use ObjectApi to get a Product object. If using the macro inside a module we can pass a moduleInstance as an instanceId parameter. As specified earlier, usually it does the job.

{% from "@macros/product_variants.twig" import product_variants %}

{% set product = ObjectApi.getProduct(6) %}

{{ product_variants(product, {
    instanceId: moduleInstance
}) }}

Macro source code

{% macro product_variants(product, options) %}
    {% from "@macros/radio.twig" import radio %}
    {% from "@macros/checkbox.twig" import checkbox %}
    {% from "@macros/input.twig" import input %}
    {% from "@macros/file_picker.twig" import file_picker %}
    {% from "@macros/text_variant_option.twig" import text_variant_option %}
    {% from "@macros/checkbox_variant_option.twig" import checkbox_variant_option %}
    {% from "@macros/file_variant_option.twig" import file_variant_option %}
    {% from "@macros/radio_variant_option.twig" import radio_variant_option %}
    {% from "@macros/select_variant_option.twig" import select_variant_option %}
    {% from "@macros/color_variant_option.twig" import color_variant_option %}
    {% from "@macros/loader.twig" import loader %}

    {% set defaultVariant = product.variant %}

    {% set globalPricesSettings = ObjectApi.getProductPricesSettings() %}

    {% set selectedOptionsValues = defaultVariant.optionValues|map(optionValue => optionValue.optionValue.id) %}

    {% if selectedOptionsValues|length == 0 and product.variants.count == 1 %}
        {% set selectedOptionsValues = product.variants[0].optionValues|map(optionValue => optionValue.optionValue.id) %}
    {% endif %}

    {% set hasSelectedValuesByDefault = selectedOptionsValues|length > 0 %}

    {% set showGrossPrice = globalPricesSettings.showGrossPrice or (globalPricesSettings.showGrossPrice and globalPricesSettings.showNetPrice) %}

    {% set stockOptionsOrder = 1 %}

    <product-variants
            module-instance-id="{{ options.instanceId }}"
            class="product-variants"
            {% if defaultVariant.optionValues.count %}has-default-variant="true"{% endif %}
            validation-name-label="{{ variantOption.name }}"
            product-id="{{ product.id }}"
            variant-id="{{ product.variant.id }}"
            {% if options.noMessages %} no-messages {% endif %}
            {% if options.groupFlashMessengerName %}
                group-flash-messenger-name="{{ options.groupFlashMessengerName }}"
            {% endif %}
            {% if options.productInstanceKey %} product-instance-key="{{ options.productInstanceKey }}" {% endif %}
        >
        {% if options.moduleTitleInProductVariants %}
            <p class="p font_semibold">
                {{ options.moduleTitleInProductVariants }}
            </p>
        {% endif %}

        {% if product.options.count > 0 and options.shouldShowVariantsPriceDifferenceInfo %}
            <p class="p_s">
                {{ translate('Individual variants may differ in price') }}
            </p>
        {% endif %}

        {% if not options.noMessages %}
            <flash-messenger
                    class="flash-messenger control"
                    name="product-variants-flash-messenger-container-{{ options.instanceId }}"
            ></flash-messenger>
        {% endif %}

        <div hidden
             class="mb-lg-2 mb-md-2 mb-sm-2 mb-xs-2 box box_primary box_spacing-s js__variant-validation-info-box">
            <p class="box__content">
                {{ translate('Mandatory fields are marked with') }} - <span class="color-primary-500">*</span>
            </p>
        </div>

        {% if defaultVariant.optionValues.count %}
            {{ loader({ ariaLabel: 'product variants options loader' }) }}
        {% else %}
            <div class="js__module-loading-loader">
                {{ loader({ ariaLabel: 'product variants options loader' }) }}
            </div>
        {% endif %}

        {% set
            productOptions = options.shouldDisplayNonStockOptionsOnly ?
                product.options|filter((option) => not option.isStockOption) :
                product.options
        %}

        {% for option in productOptions %}
            {% set hasPriceModification = option.isPriceModifier or option.isPercentagePriceModifier %}

            {% set hasIncrisingPriceModification =  hasPriceModification and option.priceModification.grossValue > 0 or option.percentagePriceModification > 0 %}

            {% set formatPriceModification = showGrossPrice ? option.priceModification.formatGross : option.priceModification.formatNet %}

            {% if option.isPercentagePriceModifier %}
                {% set formatPriceModification = option.formatPercentagePriceModification %}
            {% endif %}

            {% if hasPriceModification %}
                {% set formatPriceModification = hasIncrisingPriceModification ? "+#{formatPriceModification}" : formatPriceModification %}
            {% endif %}

            {% set controlId = "option-#{ option.id }" %}
            {% set controlName = "option_#{ option.id }" %}

            {% if options.instanceKey %}
                {% set controlId = "#{controlId}-#{options.instanceKey}" %}
                {% set controlName = "#{controlName}_#{options.instanceKey}" %}
            {% endif %}

            {% if options.productInstanceKey %}
                {% set controlId = "#{controlId}-#{options.productInstanceKey}" %}
                {% set controlName = "#{controlName}_#{options.productInstanceKey}" %}
            {% endif %}

            {% if option.isText %}

                {{ text_variant_option({
                    productId: product.id,
                    option: option,
                    hasPriceModification: hasPriceModification and not options.hidePriceModification,
                    formatPriceModification: formatPriceModification
                }) }}

            {% elseif option.isCheckbox %}

                {{ checkbox_variant_option({
                    id: controlId,
                    name: controlName,
                    productId: product.id,
                    option: option,
                    hasPriceModification: hasPriceModification and not options.hidePriceModification,
                    formatPriceModification: formatPriceModification
                }) }}

            {% elseif option.isFile %}

                {{ file_variant_option({
                    id: controlId,
                    name: controlName,
                    productId: product.id,
                    option: option,
                    hasPriceModification: hasPriceModification and not options.hidePriceModification,
                    formatPriceModification: formatPriceModification,
                    productInstanceKey: options.productInstanceKey
                }) }}

            {% elseif option.isRadio and option.values.count > 0 %}

                {{ radio_variant_option({
                    id: controlId,
                    name: controlName,
                    productId: product.id,
                    option: option,
                    stockOptionsOrder: stockOptionsOrder,
                    selectedOptionsValues: selectedOptionsValues,
                    showGrossPrice: showGrossPrice,
                    moduleConfig: options,
                    hasSelectedValuesByDefault: hasSelectedValuesByDefault,
                    hasPriceModification: not options.hidePriceModification
                }) }}

            {% elseif option.isColor and option.values.count > 0 %}

                {{ color_variant_option({
                    productId: product.id,
                    option: option,
                    stockOptionsOrder: stockOptionsOrder,
                    selectedOptionsValues: selectedOptionsValues,
                    showGrossPrice: showGrossPrice,
                    moduleConfig: options,
                    hasSelectedValuesByDefault: hasSelectedValuesByDefault,
                    hasPriceModification: not options.hidePriceModification
                }) }}

            {% elseif option.isSelect and option.values.count > 0 %}

                {{ select_variant_option({
                    productId: product.id,
                    option: option,
                    stockOptionsOrder: stockOptionsOrder,
                    selectedOptionsValues: selectedOptionsValues,
                    showGrossPrice: showGrossPrice,
                    moduleConfig: options,
                    hasSelectedValuesByDefault: hasSelectedValuesByDefault,
                    hasPriceModification: not options.hidePriceModification
                }) }}

            {% endif %}

            {% if option.isStockOption %}
                {% set stockOptionsOrder = stockOptionsOrder + 1 %}
            {% endif %}
        {% endfor %}
    </product-variants>
{% endmacro %}

Webcomponents reference

Object Api methods reference