Neste tutorial, veremos como exibir uma etiqueta que calcula a porcentagem de desconto quando um produto tiver um preço original e um preço promocional, tanto no detalhe do produto quanto na lista:
Essa porcentagem é calculada quando o usuário altera uma variável nos detalhes do produto para casos em que eles têm um preço diferente.
HTML
A primeira coisa que vamos fazer é criar o tpl geral para todas as etiquetas relacionadas a um produto: desconto, frete grátis e sem estoque. Se você não precisa de tudo, você pode excluir o código que não precisa.
1. Adicione o arquivo labels.tpl à pasta snipplets
Vamos notar duas coisas importantes aqui:
- O condicional {% if product_detail%} que usamos ao incluir o snipplet para perguntar se ele se aplica ao detalhe do produto ou não, dessa forma podemos usar as classes “js -...”
- A variável price_discount_percentage que faz a conta para calcular qual é a porcentagem de desconto.
{% if product.compare_at_price > product.price %} {% set price_discount_percentage = ((product.compare_at_price) - (product.price)) * 100 / (product.compare_at_price) %} {% endif %} {% if not product.has_stock or product.free_shipping or product.compare_at_price %} <div class="labels"> {% if not product.has_stock %} <div class="{% if product_detail %}js-stock-label {% endif %}label label-default">{{ "Sin stock" | translate }}</div> {% else %} {% if product.compare_at_price %} <div class="js-offer-label label label-primary" {% if (not product.compare_at_price) or not product.display_price %}style="display:none;"{% endif %}> <span {% if product_detail %}class="js-offer-percentage"{% endif %}>{{ price_discount_percentage |round }}</span>% OFF </div> {% endif %} {% if product.free_shipping %} <div class="label label-secondary">{{ "Envío gratis" | translate }}</div> {% endif %} {% endif %} </div> {% endif %}
2. Com labels.tpl criado, temos que incluí-lo no detalhe do produto e na lista de produtos.
Para o item na lista nós o incluímos no item snipplet.tpl dentro da pasta snipplets/grid, pode ser que no seu layout este snipplet seja chamado single_product.tpl.
Chamamos o snipplet da seguinte maneira (idealmente dentro do componente de imagem do produto):
{% include 'snipplets/labels.tpl' %}
Incluiremos o mesmo snipplet nos detalhes do produto. No layout Base, fazemos isso no arquivo product-image.tpl na pasta snipplets/product, no seu caso você pode ter que incluí-lo no template product.tpl. O importante é que esteja dentro do contexto da imagem do produto, já que o componente da etiqueta tem uma posição absoluta no CSS.
{% include 'snipplets/labels.tpl' with {'product_detail': true} %}
3. Continuando com os detalhes do produto, aplicamos as seguintes alterações:
No modelo product.tpl no div principal que engloba todo o conteúdo desta página adicionamos os seguintes IDs e seletores “js -...”, sendo os seguintes:
<div id="single-product" class=”js-product-detail js-product-container" data-variants="{{product.variants_object | json_encode }}" itemscope itemtype="http://schema.org/Product"> … </div>
Depois substituímos o HTML que mostra o preço e o preço promocional dentro do snipplet product-form.tpl ou, talvez, no seu caso ele esteja no product.tpl, com o seguinte código:
{# Product price #} <div class="price-container text-center text-sm-left" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <span class="d-inline-block"> <h4 id="compare_price_display" class="js-compare-price-display price-compare" {% if not product.compare_at_price or not product.display_price %}style="display:none;"{% else %} style="display:block;"{% endif %}>{% if product.compare_at_price and product.display_price %}{{ product.compare_at_price | money }}{% endif %}</h4> </span> <spa class="d-inline-block"> <h4 class="js-price-display" id="price_display" itemprop="price"{% if product.display_price %} content="{{ product.price / 100 }}"{% endif %} {% if not product.display_price %}style="display:none;"{% endif %}>{% if product.display_price %}{{ product.price | money }}{% endif %}</h4> </span> <meta itemprop="priceCurrency" content="{{ product.currency }}" /> {% if product.stock_control %} <meta itemprop="inventoryLevel" content="{{ product.stock }}" /> <meta itemprop="availability" href="http://schema.org/{{ product.stock ? 'InStock' : 'OutOfStock' }}" content="{{ product.stock ? 'In stock' : 'Out of stock' }}" /> {% endif %} </div>
Por último adicionamos a classe js-variation-option dentro do select das variantes do detalhe do produto. No layout Base, isso está no tpl product-variants.tpl dentro da pasta snipplets/product. Em seu layout, esse arquivo pode ser chamado de variants.tpl ou talvez você deva aplicar a alteração diretamente no template product.tpl
CSS
Requisito:
Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).
1. Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou no stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu design:
{# /* // Labels */ #} .label { background: darken($main-background, 1%); &.label-primary{ background: $main-foreground; color: $main-background; } }
2. Adicione os estilos no arquivo static/style-critical.tpl
{# /* // Labels */ #} .labels { position: absolute; top: 0; z-index: 9; } .label { margin-bottom: 10px; padding: 5px 10px; font-size: 12px; text-align: left; }
JS
O JavaScript deve ser adicionado no arquivo store.js.tpl (ou onde você tem suas funções JS). Adicionamos o seguinte código:
$(document).on("change", ".js-variation-option", function(e) { var $this_compare_price = $(this).closest(".js-product-container").find(".js-compare-price-display"); var $this_price = $(this).closest(".js-product-container").find(".js-price-display"); var $installment_container = $(this).closest(".js-product-container").find(".js-product-payments-container"); var $installment_text = $(this).closest(".js-product-container").find(".js-max-installments-container"); var $this_product_container = $(this).closest(".js-product-container"); var $this_add_to_cart = $(this).closest(".js-product-container").find(".js-prod-submit-form"); // Get the current product discount percentage value var current_percentage_value = $this_product_container.find(".js-offer-percentage"); // Get the current product price and promotional price var compare_price_value = $this_compare_price.html(); var price_value = $this_price.html(); // Filter prices to only have numbers old_price_value_filtered = parseInt(compare_price_value.replace(/[^0-9]/gi, ''), 10)/100; current_price_value_filtered = parseInt(price_value.replace(/[^0-9]/gi, ''), 10)/100; // Calculate new discount percentage based on difference between filtered old and new prices price_difference = (old_price_value_filtered-current_price_value_filtered); updated_discount_percentage = Math.round(((price_difference*100)/old_price_value_filtered)); $this_product_container.find(".js-offer-percentage").html(updated_discount_percentage); if ($this_compare_price.css("display") == "none") { $this_product_container.find(".js-offer-label").hide(); } else { $this_product_container.find(".js-offer-label").css("display" , "table"); } if ($this_add_to_cart.hasClass("nostock")) { $this_product_container.find(".js-stock-label").show(); } else { $this_product_container.find(".js-stock-label").hide(); } if ($this_price.css('display') == 'none'){ $installment_container.hide(); $installment_text.hide(); }else{ $installment_text.show(); } });
Pronto, você já tem em sua loja a funcionalidade aplicada.