product_variants¶
The product_variants
macro is used to render a set of variants for a given product.
Definition¶
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 %}