Neste tutorial, vamos implementar a promoção de cross selling ao adicionar um produto ao carrinho.

HTML
1. Vamos criar um novo snippet chamado snipplets/cross-selling.tpl dentro da pasta snipplets. Neste arquivo, utilizaremos o componente privado cross-selling-form.
O código correspondente é o seguinte:
{# Cross selling promotion form #}
{% if promotion %}
{{ component(
'promotions/cross-selling-form', {
css_classes: {
main_container: 'm-auto',
image_container: 'position-relative',
discount_percentage_label: 'label label-accent position-absolute label-top-left',
image: 'img-fluid w-100 lazyload product-image-limited',
form_container: 'px-4 py-3',
product_name: 'font-big text-center mb-2',
prices_container: 'price-container text-center mb-3',
price_wrapper: 'd-inline-block',
original_price: 'price-compare font-weight-normal mb-0',
promo_price: 'text-primary mb-0',
variant_selection_group: 'form-group px-2 mb-2',
variant_selection_label: 'form-label',
variant_select: 'form-select',
variant_select_icon_container: 'form-select-icon',
add_to_cart_button: 'btn btn-primary btn-block mt-3 mb-1'
},
icon_config: {
use_svg_icon: false,
use_custom_icon: true,
custom_icon_markup: include("snipplets/svg/chevron-down.tpl", { svg_custom_class: "icon-inline icon-w-12 icon-md mr-3" })
},
content: {
button_placeholder: include('snipplets/placeholders/button-placeholder.tpl', { custom_class: 'btn-block mt-3 mb-1' })
}
})
}}
{% endif %}2. No final do arquivo snipplets/header/header.tpl, é necessário adicionar o seguinte trecho de código:
{# Cross selling promotion notification on add to cart #}{% embed "snipplets/modal.tpl" with {modal_id: 'js-cross-selling-modal',modal_class: 'bottom modal-bottom-sheet h-auto overflow-none modal-body-scrollable-auto',modal_header: true,modal_header_class: 'm-0 w-100',modal_position: 'bottom',modal_transition: 'slide',modal_footer: true,modal_width: 'centered-md m-0 p-0 modal-full-width modal-md-width-400px'} %}{% block modal_head %}{{ '¡Descuento exclusivo!' | translate }}{% endblock %}{% block modal_body %}{# Promotion info and actions #}<div class="js-cross-selling-modal-body" style="display: none"></div>{% endblock %}{% endembed %}
3. Agora bem, para que o modal possa ser aberto e mostrar a promoção corretamente, é necessário que em snipplets/modal.tpl contemos com o parâmetro {{ modal_header_class }}. Caso não o tenha, é necessário modificar o componente. Para isso, devemos procurar a seguinte linha nesse arquivo:
<div class="js-modal-close {% if modal_mobile_full_screen %}js-fullscreen-modal-close{% endif %} modal-header">E substituí-la por esta:
<div class="js-modal-close {% if modal_mobile_full_screen %}js-fullscreen-modal-close{% endif %} modal-header {{ modal_header_class }}">4. É necessário ajustar o resumo do carrinho para mostrar o desconto aplicado por cross selling. Para isso, em snipplets/cart-totals.tpl, devemos procurar a seguinte linha, que deveria aparecer duas vezes:
<span class="js-promo-in" style="display:none;">{{ "en" | translate }}</span>E logo acima dessa linha, adicione o seguinte:
<span class="js-promo-discount" style="display:none;"> {{ "Descuento" | translate }}</span>Posteriormente, devemos procurar:
{% elseif promotion.isBuyXPayY %}{{ promotion.buy }}x{{ promotion.pay }}
E abaixo incorporar:
{% elseif promotion.isCrossSelling %}{{ "Descuento" | translate }}
Ambas as mudanças deveriam aparecer duas vezes no mesmo arquivo.
CSS
Requisito:
Certifique-se de que as classes helpers estejam adicionadas ao seu design. Você pode seguir este pequeno tutorial para fazê-lo (basta copiar e colar algumas classes, e isso não levará mais de 1 minuto).
1. Para que os estilos sejam aplicados corretamente, é necessário colocá-los no lugar adequado. Todas as alterações serão feitas em static/css/style-async.scss.tpl.
Procuramos o seletor .modal que está fora das media queries. Em seguida, dentro deste mesmo, procuramos o seletor &-centered, e ali inserimos o seguinte:
&-md.modal-show {left: 50%;transform: translateX(-50%);&.modal-bottom-md,&.modal-bottom {top: 50%;bottom: auto;left: 50%;height: fit-content;transform: translate(-50%, -50%);}}
2. Em seguida, devemos adicionar esses estilos, garantindo que não fiquem dentro de nenhuma media query:
.modal-full-width {width: 100%;max-width: 100%;}.modal-body-scrollable-auto .modal-body {max-height: calc(100vh - 100px);overflow-y: auto;}.label-top-left {top: 25px;left: 25px;z-index: 2;}.product-image-limited {max-height: 320px;max-width: 100%;object-fit: contain;}
3. Na seção de media queries adicionamos o seguinte:
{# /* // Max width 767px */ #}@media (max-width: 767px) {.product-image-limited {max-height: 210px;}}
4. Dentro da mesma seção, devemos procurar a media query de min-width: 768px e, dentro dela, localizar a definição de .modal, como antes, mas desta vez para a versão desktop. Neste caso, o que devemos adicionar é o seguinte:
&-centered-md.modal-show {left: initial;transform: none;&.modal-bottom {top: 50%;}}
E mais abaixo:
&-md-width-400px {width: 400px;max-width: 90vw;}
JS
1. É necessário modificar a função de callback que é executada ao adicionar um produto ao carrinho. Para isso, devemos acessar o arquivo base/static/js/store.js.tpl e procurar a seguinte linha:
var callback_add_to_cart = function(html_notification_related_products){Em seguida, substitua-a por:
var callback_add_to_cart = function(html_notification_related_products, html_notification_cross_selling) {2. Dentro do mesmo callback, adicionamos o seguinte código no final da função:
{# Display cross-selling promotion modal #}if (html_notification_cross_selling != null) {jQueryNuvem('.js-cross-selling-modal-body').html("");modalOpen('#js-cross-selling-modal');jQueryNuvem('.js-cross-selling-modal-body').html(html_notification_cross_selling).show();}{# Change prices on cross-selling promotion modal #}const crossSellingContainer = document.querySelector('.js-cross-selling-container');if (crossSellingContainer) {LS.fillCrossSelling(crossSellingContainer);}
3. Para habilitar corretamente a funcionalidade de compra via AJAX, é necessário realizar as seguintes modificações no código:
Primeiro, identificar o seguinte comentário no arquivo:
{# Define if event comes from quickshop or product page #}E substituí-lo por:
{# Define if event comes from quickshop, product page or cross selling #}Em seguida, abaixo da linha:
var isQuickShop = $productContainer.hasClass('js-quickshop-container');Adicionar o seguinte:
var isCrossSelling = $productContainer.hasClass('js-cross-selling-container');Depois, localizar a seguinte estrutura:
if (!isQuickShop) {// ...}
E substituí-la por:
{# Add item information for notification #}
if (isCrossSelling) {
var imageSrc = $productContainer.find('.js-cross-selling-product-image').attr('src');
var quantity = $productContainer.data('quantity')
var name = $productContainer.find('.js-cross-selling-product-name').text();
var price = $productContainer.find('.js-cross-selling-promo-price').text();
var addedToCartCopy = $productContainer.data('add-to-cart-translation');
} else if (!isQuickShop) {Por fim, ao final da função callback_add_to_cart (modificada anteriormente), adicionar o seguinte:
{# Automatically close the cross-selling modal by triggering its close button #}
if (isCrossSelling) {
jQueryNuvem('#js-cross-selling-modal .js-modal-close').trigger('click');
}Traduções
Neste passo adicionamos os textos para as traduções no arquivo config/translations.txt:
es "¡Descuento exclusivo!"pt "Desconto exclusivo!"en "Exclusive discount!"es_mx "¡Descuento exclusivo!"es "Descuento"pt "Desconto"en "Discount"es_mx "Descuento"
Ativação
Para ativar a funcionalidade, acesse o administrador da loja e vá até a seção Descontos > Promoções. Em seguida, crie uma nova promoção, configure os parâmetros conforme necessário e salve as alterações.