loyalty_product_tile¶
The loyalty_product_tile
macro is used to render a single tile of a product in a loyalty program context. Such tile can be highly configured in terms of displayed informations what will be shown in the examples.
Definition¶
Input parameters¶
product¶
Product
parameter represents a Product object from ObjectApi.
options¶
object
parameter represents an object of product tile options
Option key | Type | Default | Required | Description |
---|---|---|---|---|
options.instanceId | string |
"" | yes | Unique identifier commonly provided by a special module variable moduleInstance |
options.className | string |
"" | no | A list of classes that will be added to the product tile |
options.imageSize | string |
"" | yes | A number representing a size of the image to render in pixels |
options.hasFavouriteIcon | boolean |
false | no | If set to true a button allowing to add the product to favourites will be rendered |
options.hasSkuCode | boolean |
false | no | If set to true the SKU code of the product will be rendered |
options.hasProducerCode | boolean |
false | no | If set to true the producer code of the product will be rendered |
options.shouldShortenLongProductName | boolean |
false | no | If set to true a long product name will be shortened to two rows |
options.hasProducerName | boolean |
false | no | If set to true the name of the producer will be rendered |
options.hasAddToBasketButton | boolean |
false | no | If set to true the button allowing to add the product to the basket will be rendered |
options.hasAvailabilityStatus | boolean |
false | no | If set to true the availability status of the product will be rendered |
options.basketTrackingParams | string |
false | no | Parameters used to track a given product in terms of being added to the basket |
overrides¶
object
parameter represents an object of configuration parameters that override product and options configuration options if needed
Option key | Type | Default | Required | Description |
---|---|---|---|---|
options.url | string |
"" | no | A url path to the given product |
Example¶
In this example we use a product tile macro to render a list of products based on a given product list. To get a list of products we use a getProducts() method from ObjectApi and to get a default size of the image we use the System Configuration object from SVE.
{% from "@macros/loyalty_product_tile.twig" import loyalty_product_tile %}
{% set productList = ObjectApi.getProducts() %}
{% for product in productList %}
{{ loyalty_product_tile(product, {
instanceId: moduleInstance,
imageSize: systemConfig.lSize
}) }}
{% endfor %}
Example¶
In this example we use a similar product list but this time all product tiles have additional buttons allowing to add products to favourites and to the basket. They also have a producer name along with it's code.
{% from "@macros/loyalty_product_tile.twig" import loyalty_product_tile %}
{% set productList = ObjectApi.getProducts() %}
{% for product in productList %}
{{ {% from "@macros/loyalty_product_tile.twig" import loyalty_product_tile %}(product, {
instanceId: moduleInstance,
imageSize: systemConfig.lSize,
hasFavouriteIcon: true,
hasAddToBasketButton: true,
hasProducerName: true,
hasProducerCode: true
}) }}
{% endfor %}
Example¶
In this example the product tiles have a custom className making them visible on all devices but mobile
{% from "@macros/loyalty_product_tile.twig" import loyalty_product_tile %}
{% set productList = ObjectApi.getProducts() %}
{% for product in productList %}
{{ loyalty_product_tile(product, {
instanceId: moduleInstance,
imageSize: systemConfig.lSize,
className: 'hidden-xs-only'
}) }}
{% endfor %}
Macro source code¶
{% macro loyalty_product_tile(product, options, overrides) %}
{% from "@macros/image.twig" import image %}
{% from "@macros/ribbon.twig" import ribbon %}
{% from "@macros/ribbon_group.twig" import ribbon_group %}
{% from "@macros/add_to_favourites_button.twig" import add_to_favourites_button %}
{% from "@macros/price_product_tile_regular.twig" import price_product_tile_regular %}
{% from "@macros/icon.twig" import icon %}
{% set settings = ObjectApi.getProductPricesSettings() %}
{% set loyaltyProgramSettings = ObjectApi.getLoyaltyProgramSettings() %}
{% set notificationSettings = ObjectApi.getNotificationSettings() %}
{% set productUrl = overrides.url ?? product.loyaltyUrl %}
{% set basketSettings = ObjectApi.getBasketSettings() %}
{% set shopUrls = ObjectApi.getShopUrls() %}
{% if product.isNew %}
{% set newProductRibbon = {
text: translate('New Product'),
options: {
classNames: 'ribbon_new'
}
} %}
{% endif %}
{% if loyaltyProgramSettings.productsForThePoints %}
{% set exchangePrice = loyaltyProgramSettings.productsForThePoints.exchangePrice %}
{% endif %}
<div
id="{{ product.id }}-{{ options.instanceId }}"
class="product-tile loyalty-product-tile {{ options.className }}"
>
<div
class="
product-tile__row
product-tile__header
loyalty-product-tile__row
loyalty-product-tile__header
"
>
<div
class="
product-tile__row
product-tile_row_image
loyalty-product-tile__row
loyalty-product-tile_row_image
"
>
<div class="product-tile__image loyalty-product-tile__image">
{% if promoProductRibbon or newProductRibbon %}
{{ ribbon_group([promoProductRibbon, newProductRibbon], { position: "absolute" }) }}
{% endif %}
<a href="{{ productUrl }}" title="{{ product.name }}">
{{ image({
img: {
src: product.featuredImage.thumbnailUrl(options.imageSize, options.imageSize),
alt: product.featuredImage.name,
title: product.featuredImage.name,
width: options.imageSize,
height: options.imageSize,
loading: 'lazy'
}
}, [
{
src: product.featuredImage.webpThumbnailUrl(options.imageSize, options.imageSize),
type: 'image/webp'
}
]) }}
</a>
{% if options.hasFavouriteIcon %}
<div class="product-tile__favourites loyalty-product-tile__favourites">
{{ add_to_favourites_button(product, { instanceId: options.instanceId }) }}
</div>
{% endif %}
</div>
</div>
{% if product.sku or product.productCode %}
<span class="product-tile__codes loyalty-product-tile__codes">
{% if product.sku and options.hasSkuCode %}
<span
class="
product-tile__code
product-tile__code_sku
loyalty-product-tile__code
loyalty-product-tile__code_sku
"
>
{{ product.sku }}
</span>
{% endif %}
{% if product.producerCode and options.hasProducerCode %}
<span
class="
product-tile__code
product-tile__code_producer
loyalty-product-tile__code
loyalty-product-tile__code_producer
"
>
{{ product.producerCode }}
</span>
{% endif %}
</span>
{% endif %}
{% if product.name %}
<a href="{{ productUrl }}" title="{{ product.name }}" class="link_no-underline">
<h2
class="
product-tile__name
loyalty-product-tile__name
{% if options.shouldShortenLongProductName %}
product-tile__name_fixed-height
loyalty-product-tile__name_fixed-height
{% endif %}
"
>
{{ product.name }}
</h2>
</a>
{% endif %}
{% if product.producer.name and options.hasProducerName %}
<span class="product-tile__producer loyalty-product-tile__producer">
{{ product.producer.name }}
</span>
{% endif %}
</div>
<div
class="
product-tile__row
product-tile__content
loyalty-product-tile__row
loyalty-product-tile__content
"
>
{% set prices %}
{{ price_product_tile_regular("#{product.variant.loyaltyPointsCost.points} #{translate('pts')}") }}
{% if not exchangePrice.isZero %} {{ price_product_tile_regular("+ #{exchangePrice}") }} {% endif %}
{% endset %}
{% if settings.showPricesToUnregistered %}
{{ prices }}
{% else %}
<auth-controller>
{{ prices }}
</auth-controller>
{% endif %}
</div>
{% if options.hasAddToBasketButton or options.hasAvailabilityStatus %}
<div class="product-tile__footer loyalty-product-tile__footer">
{% if options.hasAddToBasketButton %}
{% if basketSettings.isBuyingEnabled %}
{% if product.variant.isAvailable or not product.hasOnlyDefaultVariant %}
{% set loyaltyAddToBasketButton %}
{% if product.isBundle and product.bundle.hasItemWithNotStockOption %}
<a class="btn btn_s btn_special" href="{{ productUrl }}">
{{ translate('Set up bundle') }}
</a>
{% else %}
{% if product.packageQuantity %}
{% set quantity = product.packageQuantity %}
{% else %}
{% set quantity = 1 %}
{% endif %}
<loyalty-buy-button
product-id="{{ product.id }}"
variant-id="{{ product.variant.id }}"
is-buyable="{{ product.availability.isAvailable }}"
product-path="{{ productUrl }}"
quantity="{{ quantity }}"
{% if basketSettings.redirectToBasketAfterAdding %}
basket-path="{{ shopUrls.basketUrl }}"
{% elseif not basketSettings.showConfirmationMessage %}
has-flash-message
{% endif %}
{% if options.basketTrackingParams is defined %}
basket-tracking-params="{{ options.basketTrackingParams }}"
{% endif %}
{% if product.options.count > 0 %}
has-product-variants
{% endif %}
{% if not product.isAvailable %}
hidden
{% endif %}
points-cost="{{ product.variant.loyaltyPointsCost.points }}"
on-interaction
>
</loyalty-buy-button>
{% endif %}
{% endset %}
<auth-controller>
<div slot="logged-in">
{{ loyaltyAddToBasketButton }}
</div>
<div slot="logged-out">
<span class="btn btn_s btn_outline">{{ translate('Not enough points') }}</span>
</div>
</auth-controller>
{% elseif not notificationSettings.getIsProductNotificationEnabled() or not product.availability.isNotificationEnabled %}
<span class="btn btn_s btn_special btn_special-disabled">
{{ translate('Unavailable') }}
</span>
{% endif %}
{% if notificationSettings.getIsProductNotificationEnabled() and product.availability.isNotificationEnabled %}
<availability-notifier-btn
product-name="{{ product.name }}"
product-image="{{ product.featuredImage.webpThumbnailUrl(120, 120) }}"
product-id="{{ product.id }}"
product-variant-id="{{ product.variant.id }}"
{% if not product.availability.isNotificationEnabled %}
hidden
{% endif %}>
<button class="btn btn_secondary btn_s" slot="subscribe">
{{ translate('Notify me when available') }}
</button>
<button class="btn btn_outline btn_s" slot="unsubscribe" hidden>
{{ translate('Opt out of notifications') }}
</button>
</availability-notifier-btn>
{% endif %}
{% else %}
<span class="btn btn_s btn_special btn_special-disabled">
{{ translate('Cart disabled') }}
</span>
{% endif %}
{% endif %}
{% if options.hasAvailabilityStatus %}
<span class="product-tile__availability loyalty-product-tile__availability">
{{ translate("Availability") }}:
<strong class="{{ html_classes('product-tile__availability-value', {
'product-tile__availability-value_inactive': not product.availability.isAvailable,
'loyalty-product-tile__availability-value_inactive': not product.availability.isAvailable,
}) }}">{{ product.availability.name }}</strong>
</span>
{% endif %}
</div>
{% endif %}
</div>
{% endmacro %}