Snipplets

Snipplets são as menores unidades de HTML dentro de um modelo e são encontrados dentro da pasta com o mesmo nome.

Eles representam componentes isolados que podem ser incluídos em um ou vários locais da loja, como o item de produto na lista:

Eles podem ser elementos genéricos como um simples input para um formulário

Ou algo específico para uma funcionalidade como a calculadora de envio:

Você pode adicionar todos os snipplets que você precisa em seu layout usando o nome que desejar, o importante é entender que quanto mais isolado for o componente, mais fácil será sua manutenção sem afetar outros arquivos.

Nos modelos existem apenas 4 snipplets que não podem mudar de local ou nome dentro dos arquivos por razões de backend (isto é, eles são usados a partir do PHP Tiendanube):

  • product_grid.tpl → É usado para carregar mais produtos nas páginas da categoria quando o usuário atinge o footer
  • shipping_options.tpl → Usado para opções de envio
  • cart-item-ajax.tpl → É o item do produto adicionado ao carrinho
  • shipping_suboptions → é uma pasta que contém apenas um tpl que é usado quando o meio de envio tem mais opções, por exemplo, um menu  para ramificações OCA, meio de envio de Argentina.

Abaixo você pode ver em detalhes alguns dos snipplets mais importantes de um template:

Grid

Dentro da pasta Grid, temos todos os snipplets em relação ao grid ou a lista de produtos:

  • filters.tpl
  • categories.tpl
  • sort-by.tpl
  • item.tpl
  • quick-shop.tpl

filters.tpl

Neste snipplet, você encontra tudo relacionado aos filtros de propriedades para produtos:

Nós separamos os filtros em 4 grupos:

  • Filtros de cor principais, que são mostrados com um botão circular com o fundo colorido.
  • Filtros para cores secundárias, com cores mais específicas, como "salmão". Estes são mostrados com um botão normal cujo texto será o nome da cor.
  • Filtros de tamanho
  • Outros filtros, para os mais personalizados.

Usamos filtros apenas para a página da categoria dentro do arquivo category.tpl

{% set default_lang = current_language.lang %}
{% set filter_colors = insta_colors|length > 0 %}
{% set filter_more_colors = other_colors|length > 0 %}
{% set filter_sizes = size_properties_values|length > 0 %}
{% set filter_other = variants_properties|length > 0 %}

{% if default_lang == 'pt' %}
    {% set color_name = 'Cor' %}
    {% set size_name = 'Tamanho' %}
{% endif %}
{% if default_lang == 'es' %}
    {% set color_name = 'Color' %}
    {% set size_name = 'Talle' %}
{% endif %}
{% if default_lang == 'en' %}
    {% set color_name = 'Color' %}
    {% set size_name = 'Size' %}
{% endif %}
<div id="filters" data-store="filters-nav">
    {% if filter_colors or filter_more_colors %}
        <div class="mb-4" data-store="filters-group">
            <h6 class="mb-3">{{ 'Color' | translate }}</h6>
            {% for name,color in insta_colors %}
                <label class="checkbox-container font-weight-bold {% if mobile %}mb-3{% else %}mb-2{% endif %}" onclick="LS.urlAddParam('{{ color_name|replace("'","%27") }}', '{{ name|replace("'","%27") }}');">
                    <span class="checkbox">
                        <input type="checkbox" autocomplete="off">
                        <span class="checkbox-icon"></span>
                        <span class="checkbox-text">{{ name }}</span>
                        <span class="checkbox-color" style="background-color: {{ color[name] }};" title="{{ name }}"></span>
                    </span>
                </label>
            {% endfor %}
            {% for color in other_colors %}
                <label class="checkbox-container font-weight-bold {% if mobile %}mb-3{% else %}mb-2{% endif %}" onclick="LS.urlAddParam('{{ color_name|replace("'","%27") }}', '{{ color|replace("'","%27") }}');">
                    <span class="checkbox">
                        <input type="checkbox" autocomplete="off">
                        <span class="checkbox-icon"></span>
                        <span class="checkbox-text">{{ color }}</span>
                    </span>
                </label>
            {% endfor %}
        </div>
    {% endif %}
    {% if filter_sizes %}
        <div class="mb-4" data-store="filters-group">
            <h6 class="mb-3">{{ 'Talle' | translate }}</h6>
            {% for size in size_properties_values %}
                <label class="checkbox-container font-weight-bold {% if mobile %}mb-3{% else %}mb-2{% endif %}" onclick="LS.urlAddParam('{{ size_name|replace("'","%27") }}', '{{ size|replace("'","%27") }}');">
                    <span class="checkbox">
                        <input type="checkbox" autocomplete="off">
                        <span class="checkbox-icon"></span>
                        <span class="checkbox-text">{{ size }}</span>
                    </span>
                </label>
            {% endfor %}
        </div>
    {% endif %}

    {% for variants_property in variants_properties %}
        {% if filter_other %}
            <div class="mb-4" data-store="filters-group">
                <h6 class="mb-3">{{ variants_property }}</h6>
                {% for value in variants_properties_values[variants_property] %}
                    <label class="checkbox-container font-weight-bold {% if mobile %}mb-3{% else %}mb-2{% endif %}" onclick="LS.urlAddParam('{{ variants_property|replace("'","%27") }}', '{{ value|replace("'","%27") }}');">
                        <span class="checkbox">
                            <input type="checkbox" autocomplete="off">
                            <span class="checkbox-icon"></span>
                            <span class="checkbox-text">{{value}}</span>
                        </span>
                    </label>
                {% endfor %}
            </div>
        {% endif %}
    {% endfor %}
</div>

Se você não tem essa funcionalidade em seu layout e deseja implementá-la, sugerimos este tutorial.

categories.tpl

Neste snipplet, você encontra tudo relacionado aos filtros de categorias para produtos:

{% if filter_categories %}
    <div class="filters-container mb-5">
        <h6 class="mb-3">{{ "Categorías" | translate }}</h6>
        <ul class="list-unstyled"> 
            {% for category in filter_categories %}
                <li data-item="{{ loop.index }}" class="mb-3">
                    <a href="{{ category.url }}" title="{{ category.name }}" class="text-primary">
                        {{ category.name }}
                    </a>
                </li>

                {% if loop.index == 8 and filter_categories | length > 8 %}
                    <div class="js-accordion-container" style="display: none;">
                {% endif %}
                {% if loop.last and filter_categories | length > 8 %}
                    </div>
                    <a href="#" class="js-accordion-toggle btn-link d-inline-block mt-1 pl-0">
                        <span class="js-accordion-toggle-inactive">
                            {{ 'Ver más' | translate }}
                        </span>
                        <span class="js-accordion-toggle-active" style="display: none;">
                            {{ 'Ver menos' | translate }}
                        </span>
                    </a>
                {% endif %}
            {% endfor %}
        </ul>
    </div>
{% endif %}

Usamos este archivo dentro del template category.tpl

sort-by.tpl

O sort-by.tpl é usado para ordenar produtos de acordo com os seguintes critérios:

  • Preço: maior para menor e menor para maior.
  • Alfabética: A -Z e Z - A.
  • Tempo: do mais recente para o mais antigo e do mais antigo para o mais recente.
  • Os mais vendidos

Usamos o sort by apenas para a página da categoria dentro do arquivo category.tpl

{% set sort_text = {
'user': 'Destacado',
'price-ascending': 'Precio: Menor a Mayor',
'price-descending': 'Precio: Mayor a Menor',
'alpha-ascending': 'A - Z',
'alpha-descending': 'Z - A',
'created-ascending': 'Más Viejo al más Nuevo',
'created-descending': 'Más Nuevo al más Viejo',
'best-selling': 'Más Vendidos',
} %}
{% embed "snipplets/forms/form-select.tpl" with{select_label: false, select_custom_class: 'js-sort-by', select_group_custom_class: 'mb-0', select_aria_label: 'Ordenar por:' | translate } %}
    {% block select_options %}
        {% for sort_method in sort_methods %}
            {# This is done so we only show the user sorting method when the user chooses it #}
            {% if sort_method != 'user' or category.sort_method == 'user' %}
                <option value="{{ sort_method }}" {% if sort_by == sort_method %}selected{% endif %}>{{ sort_text[sort_method] | t }}</option>
            {% endif %}
        {% endfor %}
    {% endblock select_options%}
{% endembed %}

Se você não tem essa funcionalidade em seu layout e deseja implementá-la, sugerimos este tutorial.

item.tpl

O item é o snipplet que representa o produto na lista:

Através deste item, mostramos informações importantes sobre o produto, tais como:

  • Imagem
  • Primeiro nome
  • Preço
  • Taxas

Em alguns casos, incluímos a funcionalidade de “Quickshop” ou “Popup de compras rápidas”, bem como uma imagem secundária quando você passa o mouse sobre o item estando em um desktop.

Neste snipplet, incluímos a implementação para carregamento lento com Lazysizes.

Nós incluímos o item nas seguintes partes do layout:

  • Produtos em destaque da página inicial.
  • Produtos relacionados no detalhe do produto.
  • Listado na página de categorias.
  • Listagem nos resultados da pesquisa.
{# /*============================================================================
  #Item grid
==============================================================================*/

#Properties

#Slide Item

#}

{% set slide_item = slide_item | default(false) %}
{% set columns = settings.grid_columns %}
{% set has_color_variant = false %}
{% if settings.product_color_variants %}
    {% for variation in product.variations if variation.name in ['Color', 'Cor'] and variation.options | length > 1 %}
        {% set has_color_variant = true %}
    {% endfor %}
{% endif %}

<div class="js-item-product {% if slide_item %}js-item-slide swiper-slide{% else %}col{% if columns == 2 %}-6 col-md-3{% else %}-12 col-md-4{% endif %}{% endif %} item item-product{% if not product.display_price %} no-price{% endif %}" data-product-type="list" data-product-id="{{ product.id }}" data-store="product-item-{{ product.id }}">

    {% if settings.quick_shop or settings.product_color_variants %}
        <div class="js-product-container js-quickshop-container {% if product.variations %}js-quickshop-has-variants{% endif %}" data-variants="{{ product.variants_object | json_encode }}" data-quickshop-id="quick{{ product.id }}{% if slide_item and section_name %}-{{ section_name }}{% endif %}">
    {% endif %}

        {% set product_url_with_selected_variant = has_filters ?  ( product.url | add_param('variant', product.selected_or_first_available_variant.id)) : product.url  %}

        {% if has_color_variant %}

            {# Item image will be the first avaiable variant #}

            {% set item_img_spacing = product.featured_variant_image.dimensions['height'] / product.featured_variant_image.dimensions['width'] * 100 %}
            {% set item_img_srcset = product.featured_variant_image %}
            {% set item_img_alt = product.featured_variant_image.alt %}
        {% else %}

            {# Item image will be the first image regardless the variant #}

            {% set item_img_spacing = product.featured_image.dimensions['height'] / product.featured_image.dimensions['width'] * 100 %}
            {% set item_img_srcset = product.featured_image %}
            {% set item_img_alt = product.featured_image.alt %}
        {% endif %}

        <div class="js-item-image item-image mb-2">
            <div style="padding-bottom: {{ item_img_spacing }}%;" class="p-relative" data-store="product-item-image-{{ product.id }}">
                <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}">
                    <img alt="{{ item_img_alt }}" data-sizes="auto" data-expand="-10" src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset="{{ item_img_srcset | product_image_url('small')}} 240w, {{ item_img_srcset | product_image_url('medium')}} 320w, {{ item_img_srcset | product_image_url('large')}} 480w" class="lazyautosizes lazyload img-absolute img-absolute-centered fade-in" /> 
                    <div class="placeholder-fade"></div>
                </a>
                {% if settings.product_color_variants %}
                    {% include 'snipplets/labels.tpl' with {color: true} %}
                    {% include 'snipplets/grid/item-colors.tpl' %}
                {% else %}
                    {% include 'snipplets/labels.tpl' %}
                {% endif %}
            </div>
        </div>
        {% if (settings.quick_shop or settings.product_color_variants) and product.variations %}

            {# Hidden product form to update item image and variants: Also this is used for quickshop popup #}
            
            <div class="js-item-variants hidden">
                <form id="product_form" class="js-product-form" method="post" action="{{ store.cart_url }}">
                    <input type="hidden" name="add_to_cart" value="{{product.id}}" />
                    {% if product.variations %}
                        {% include "snipplets/product/product-variants.tpl" with {quickshop: true} %}
                    {% endif %}
                    {% if product.available and product.display_price and settings.quick_shop %}
                        {% include "snipplets/product/product-quantity.tpl" with {quickshop: true} %}
                    {% endif %}
                    {% set state = store.is_catalog ? 'catalog' : (product.available ? product.display_price ? 'cart' : 'contact' : 'nostock') %}
                    {% set texts = {'cart': "Agregar al carrito", 'contact': "Consultar precio", 'nostock': "Sin stock", 'catalog': "Consultar"} %}

                    {# Add to cart CTA #}

                    <input type="submit" class="js-addtocart js-prod-submit-form btn btn-primary btn-block {{ state }}" value="{{ texts[state] | translate }}" {% if state == 'nostock' %}disabled{% endif %} />

                    {# Fake add to cart CTA visible during add to cart event #}

                    {% include 'snipplets/placeholders/button-placeholder.tpl' with {custom_class: "btn-block"} %}

                </form>
            </div>
        {% endif %}
        <div class="item-description" data-store="product-item-info-{{ product.id }}">
            <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}" class="item-link">
                <div class="js-item-name item-name mb-1" data-store="product-item-name-{{ product.id }}">{{ product.name }}</div>
                {% if product.display_price %}
                    <div class="item-price-container mb-1" data-store="product-item-price-{{ product.id }}">
                        <span class="js-compare-price-display price-compare" {% if not product.compare_at_price or not product.display_price %}style="display:none;"{% else %}style="display:inline-block;"{% endif %}>
                            {{ product.compare_at_price | money }}
                        </span>
                        <span class="js-price-display item-price">
                            {{ product.price | money }}
                        </span>
                    </div>
                {% endif %}
            </a>
        </div>
        {% include 'snipplets/payments/installments.tpl' %}

        {% if settings.quick_shop and product.available and product.display_price %}

            {# Trigger quickshop actions #}
            
            <div class="item-actions mt-2">
                {% if product.variations %}

                    {# Open quickshop popup if has variants #}

                    <a data-toggle="#quickshop-modal" data-modal-url="modal-fullscreen-quickshop" class="js-quickshop-modal-open {% if slide_item %}js-quickshop-slide{% endif %} js-modal-open js-fullscreen-modal-open btn btn-primary btn-small px-4" title="{{ 'Compra rápida de' | translate }} {{ product.name }}" aria-label="{{ 'Compra rápida de' | translate }} {{ product.name }}" >{{ 'Agregar al carrito' | translate }}</a>
                {% else %}

                    {# If not variants add directly to cart #}
                    <form id="product_form" class="js-product-form" method="post" action="{{ store.cart_url }}">
                        <input type="hidden" name="add_to_cart" value="{{product.id}}" />
                        {% set state = store.is_catalog ? 'catalog' : (product.available ? product.display_price ? 'cart' : 'contact' : 'nostock') %}
                        {% set texts = {'cart': "Agregar al carrito", 'contact': "Consultar precio", 'nostock': "Sin stock", 'catalog': "Consultar"} %}

                        <input type="number" name="quantity" value="1" class="js-quantity-input hidden" aria-label="{{ 'Cambiar cantidad' | translate }}" >

                        <input type="submit" class="js-addtocart js-prod-submit-form btn btn-primary btn-small {{ state }} px-4 mb-1" value="{{ texts[state] | translate }}" {% if state == 'nostock' %}disabled{% endif %} />

                        {# Fake add to cart CTA visible during add to cart event #}

                        {% include 'snipplets/placeholders/button-placeholder.tpl' with {custom_class: "js-addtocart-placeholder-inline btn-small mb-1"} %}

                    </form>
                {% endif %}
            </div>
        {% endif %}

        {# Structured data to provide information for Google about the product content #}
        {% include 'snipplets/structured_data/item-structured-data.tpl' %}
    {% if settings.quick_shop or settings.product_color_variants %}
        </div>
    {% endif %}
</div>

quick-shop.tpl

O item é o snipplet que representa o popup de compra rápida para o produto na lista:

{% if settings.quick_shop %}
    {% embed "snipplets/modal.tpl" with{modal_id: 'quickshop-modal', modal_class: 'quickshop text-center', modal_position: 'bottom modal-bottom-sheet', modal_transition: 'slide', modal_header: true, modal_footer: true, modal_width: 'centered modal-docked-md modal-docked-md-centered', modal_mobile_full_screen: 'true' } %}
        {% block modal_body %}
        <div class="js-item-product" data-product-id="">
            <div class="js-product-container js-quickshop-container js-quickshop-modal js-quickshop-modal-shell" data-variants="" data-quickshop-id="">
                <div class="js-item-variants">
                    <div class="js-item-name h1 mb-1" data-store="product-item-name-{{ product.id }}"></div>
                    <div class="item-price-container mb-4" data-store="product-item-price-{{ product.id }}">
                        <span class="js-compare-price-display h4 price-compare"></span>
                        <span class="js-price-display h4"></span>
                    </div>
                    {# Image is hidden but present so it can be used on cart notifiaction #}
                    <img srcset="" class="js-quickshop-img hidden"/>
                    <div id="quickshop-form"></div>
                </div>
            </div>
        </div>
        {% endblock %}
    {% endembed %}
{% endif %}

Se você não tem essa funcionalidade em seu layout e deseja implementá-la, sugerimos este tutorial.

product_grid.tpl

Embora não incluamos este arquivo na pasta Grid (por motivos de backend), é importante mencioná-lo.

Este tpl inclui o item.tpl para listar os itens nas categorias e páginas de resultados de pesquisa, mas sua função principal é adicionar mais produtos à medida que o usuário faz scroll na tela. É por causa dessa funcionalidade que você não deve modificar seu nome ou local nas pastas do layout.

Nós incluímos este snipplet em:

  • A página de categorias
  • A página de resultados da pesquisa
{% if products and pages.is_last %}
    <div class="last-page" style="display:none;"></div>
{% endif %}
{% for product in products %}   
    {% include 'snipplets/grid/item.tpl' %}
{% endfor %}

Forms

Dentro da pasta Forms, localizamos todos os snipplets em relação aos formulários:

form-input.tpl

Para cada entrada em um formulário, usamos este snipplet, seja na página de registro de um usuário ou na calculadora de envio.

Dentro do form-input.tpl você pode escolher quais propriedades usar ao incluí-lo (usando um embed). Entre estes você pode:

  • Use classes personalizadas para o input
  • Mostrar ou não um label acima do input
  • Adicione conteúdo entre o label e o input
  • Defina se o input será uma textarea ou um input normal
  • Escolha o tipo de input: number, text, password, etc.

Para ver detalhadamente todas as propriedades deste snipplet você pode se guiar olhando os comentários no código do mesmo.

{# /*============================================================================
  #Form input
==============================================================================*/

#Properties

#Group
    //input_group_custom_class for custom CSS classes
#Label 
    // input_label_id for ID
    // input_for for label for
    // input_label_custom_class for custom CSS classes
    // input_label_text for label text
#Prepend
    // input_prepend_content to add content before input
#Container (Only if has prepend or append)
    // form_control_container_custom_class for container custom class. E.g: col
#Input 
    // Can be text_area or input
    // input_type to define type (text, tel, number or passowrd)
    // input_id for id
    // input_name for name
    // input_value for val
    // input_placeholder for placeholder
    // input_custom_class for custom CSS classes 
    // input_rows for textarea rows
    // input_data_attr for data attributes
    // input_data_val for input_data_attr value
    // input_aria_label for aria-label attribute
#Append
    // input_append_content to add content after input
#Alerts 
    // input_form_alert to insert alerts
#}

<div class="form-group {{ input_group_custom_class }}">
    {% if input_label_text %}
        <label {% if input_label_id %}id="{{ input_label_id }}"{% endif %} class="form-label {{ input_label_custom_class }}" {% if input_for %}for="{{ input_name }}"{% endif %}>{{ input_label_text }}</label>
    {% endif %}
    {% block input_prepend_content %}
    {% endblock input_prepend_content %}
    {% if input_append_content or input_prepend_content %}
    <div class="form-control-container {{ form_control_container_custom_class }}">
    {% endif %}
    {% if text_area %}
        <textarea
            {% if input_id %}id="{{ input_id }}"{% endif %}
            class="form-control form-control-area {{ input_custom_class }} {% if input_append_content %}form-control-inline{% endif %}" 
            autocorrect="off" 
            autocapitalize="off" 
            {% if input_name %}name="{{ input_name }}"{% endif %}
            {% if input_value %}value="{{ input_value }}"{% endif %}
            {% if input_rows %}rows="{{ input_rows }}"{% endif %}
            {% if input_placeholder %}placeholder="{{ input_placeholder }}"{% endif %}
            {% if input_data_attr %}data-{{ input_data_attr }}="{{ input_data_val }}"{% endif %}></textarea>
    {% else %}
        <input 
            type="{% if type_text %}text{% elseif type_number %}number{% elseif type_tel %}tel{% elseif type_password %}password{% elseif type_hidden %}hidden{% endif %}"
            {% if input_id %}id="{{ input_id }}"{% endif %}
            class="form-control {{ input_custom_class }} {% if input_append_content %}form-control-inline{% endif %}" 
            autocorrect="off" 
            autocapitalize="off" 
            {% if type_password %}autocomplete="off"{% endif %}
            {% if input_name %}name="{{ input_name }}"{% endif %}
            {% if input_value %}value="{{ input_value }}"{% endif %}
            {% if input_min %}min="{{ input_min }}"{% endif %}
            {% if input_placeholder %}placeholder="{{ input_placeholder }}"{% endif %}
            {% if input_data_attr %}data-{{ input_data_attr }}="{{ input_data_val }}"{% endif %}
            {% if input_aria_label %}aria-label="{{ input_aria_label }}"{% endif %}/>
    {% endif %}
    {% if input_append_content or input_prepend_content %}
    </div>
    {% endif %}
    {% block input_append_content %}
    {% endblock input_append_content %}
    {% if input_help %}
    <div class="mt-4 text-center">
        <a href="{{ input_help_link }}" class="btn-link {{ input_link_class }}">{% block input_help_text %}{% endblock input_help_text %}</a>
    </div>
    {% endif %}
    {% block input_form_alert %}
    {% endblock input_form_alert %}
</div>

Nós incluímos este snipplet no newsletter.tpl, product-quantity.tpl, shipping-calculator.tpl e nos templates password.tpl, contact.tpl, reset.tpl, register.tpl, login.tpl, newpass.tpl, info .tpl e endereço.tpl

form-select.tpl

Assim como usamos o form-input.tpl para os inputs, temos o form-select.tpl para o select.

Com esse snipplet, você também pode definir se deseja ou não mostrar um label ou também adicionar classes personalizadas, mas o que o diferencia é a possibilidade de adicionar opções no menu suspenso usando {% block select_options%}. Dentro desta tag Twig, é possível adicionar qualquer opção.

Para mais informações sobre como usar um {% block%}, sugerimos que você leia este artigo sobre o Twig.

{# /*============================================================================
  #Form select
==============================================================================*/

#Properties

#Group
    //select_group_custom_class for custom CSS classes
#Label 
    // select_label_name for name
    // select_label_id for ID
    // select_for for label for
    // select_label_custom_class for custom CSS classes
#Select 
    // select_id for id
    // select_name for name
    // select_custom_class for custom CSS classes 
    // input_rows for textarea rows
    // select_options to insert select options
    // select_aria_label for aria-label attribute


#}


<div class="form-group {{ select_group_custom_class }}">
    {% if select_label %}
        <label {% if select_label_id%}id="{{ select_label_id }}"{% endif %} class="form-label {{ select_label_custom_class }}" {% if select_for %}for="{{ select_for }}"{% endif %}>{{ select_label_name }}</label>
    {% endif %}
    <select 
        {% if select_id %}id="{{ select_id }}"{% endif %}
        class="form-select {{ select_custom_class }} {% if select_inline %}form-control-inline{% endif %}"
        {% if select_data %}data-{{select_data}}="{{select_data_value}}"{% endif %}
        {% if select_name %}name="{{ select_name }}"{% endif %}
        {% if select_aria_label %}aria-label="{{ select_aria_label }}"{% endif %}>
        {% block select_options %}
        {% endblock select_options %}
    </select>
    <div class="form-select-icon">
        {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "icon-inline icon-w-14 icon-lg svg-icon-text"} %}
    </div>
</div>

Incluímos este snipplet mais do que tudo no sort-by e nas variantes do produto.

form.tpl

Usamos o form.tpl para incluir um formulário clássico com o método "post" que, por padrão, mostra um botão para enviar.

Com este snipplet você pode adicionar os campos que você precisa dentro do {% block form_body%} e escolher se quer ou não mostrar um botão “cancelar” usando a condição {% if cancel%}.

Para mais informações sobre como usar um {% block%}, sugerimos que você leia este artigo sobre o Twig.

{# /*============================================================================
  #Form
==============================================================================*/

#Properties
 
    // id
    // action
    // custom_class for custom CSS classes
    // Cancel if cancel button is needed
#}

<form id="{{ form_id }}" action="{{ form_action }}" method="post" class="form {{ form_custom_class }}">
    {% block form_body %}
    {% endblock%}
    {% if cancel %}
        <a href="#" class="{{ cancel_custom_class }} btn btn-default">{{ cancel_text }}</a>
    {% endif %}
    <input class="btn btn-primary {{ submit_custom_class }}" type="submit" value="{{ submit_text }}" name="{{ submit_name }}" {{ submit_prop }}/>
</form>

Nós incluímos este snipplet em todas as formas de layouts clássicos, tais como:

  • Login
  • Registro
  • Atualizar ou criar dados de envio
  • Atualizar ou criar dados do usuário
  • Contato

Metas

Os metas são snipplets que usamos informações ao compartilhar um produto no Facebook e Twitter.

facebook-category-og.tpl

Ele armazena as informações de uma categoria quando ela é compartilhada como o nome, uma URL e uma imagem em destaque.

{{ category.url | og('url') }}
{{ category.name | og('title') }}
{{ category.description | og('description') }}
{{ ('http:' ~ category.featured_image | product_image_url('huge')) | og('image') }}
{{ ('https:' ~ category.featured_image | product_image_url('huge')) | og('image:secure_url') }}

general-og.tpl

Ele contém as informações gerais de uma loja como o nome, a imagem OG e uma URL.

{{ store.name | og('site_name') }}
{% if template == 'home' %}
    {{ 'website' | og('type') }}
    {{ page_title | og('title') }}
    {{ page_description | og('description') }}
    {{ store.url_with_protocol | og('url') }}
    
    {% set og_image_src = store.og_image_src %}
    {% if og_image_src %}
        {{ ('http:' ~ og_image_src) | og('image') }}
        {{ ('https:' ~ og_image_src) | og('image:secure_url') }}
    {% endif %}
{% endif %}

facebook-product-og.tpl

Tem a informação geral de um produto como o nome, o preço, uma descrição e uma url.

{{ product.social_url | og('url') }}
{{ product.name | og('title') }}
{{ page_description | og('description') }}
{{ "#{fb_app.namespace}:product" | og('type') }}
{{ ('http:' ~ product.featured_image | product_image_url('huge')) | og('image') }}
{{ ('https:' ~ product.featured_image | product_image_url('huge')) | og('image:secure_url') }}
{% if product.display_price %}
    {{ (product.price / 100) | og_fb_app('price') }}
{% endif %}
{% if product.stock_control %}
    {{ product.stock | og_fb_app('stock') }}
{% endif %}

twitter-product-og.tpl

Mostra as informações gerais de um produto como o nome, o preço, uma descrição e um URL.

<meta name="twitter:card" content="product">
<meta name="twitter:url" content="{{ product.social_url }}">
<meta name="twitter:image:src" content="{{ ('http:' ~ product.featured_image | product_image_url('huge')) }}">
{% if store.twitter_user %}
    <meta name="twitter:site" content="{{ store.twitter_user }}">
{% endif %}
<meta name="twitter:title" content="{{ product.name }}">
<meta name="twitter:data1" content="{{ product.display_price ? product.price | money_long : 'Consultar' | translate }}">
<meta name="twitter:label1" content="{{ 'Precio' | translate | upper }}">
<meta name="twitter:data2" content="{{ product.stock_control ? (product.stock > 0 ? product.stock : 'No' | translate) : 'Si' | translate }}">
<meta name="twitter:label2" content="{{ 'Stock' | translate | upper }}">

Nós incluímos todos os snipplets Meta no layout.tpl

SVG

Na pasta SVG, temos todos os snipplets do ícone da loja. Estes são arquivos SVG que quando terminados com “.tpl” nos permitem usar o Twig para substituir a propriedade svg_custom_class com qualquer classe que precisamos quando se trata de incluí-la.

Um exemplo de um snipplet SVG é o ícone da lupa para procurar:

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z"/></svg>

Em seguida, o incluímos dentro dos snipplet header-utilities.tpl

{% include "snipplets/svg/shopping-bag.tpl" with {svg_custom_class: "icon-inline icon-w-14 svg-icon-text"} %}
Sempre que usamos um ícone, incluímos desta forma. Para mais informações sobre SVGs, recomendo que você leia este artigo sobre desempenho.

Shipping

Nesta pasta colocamos todos os snipplets em relação a um dos pontos mais críticos do fluxo de compra, meios de envio. Recomendamos modificar esses arquivos o mínimo possível, devido à complexidade e importância deles no layout.

Além dos arquivos nesta pasta, por motivos de backend, temos fora da pasta Shipping:
  • A pasta shipping_suboptions
  • O snipplet shipping_options.tpl
Todo JavaScript em relação a shipping está no arquivo store.js.tpl

branches.tpl

Neste tpl listamos as lojas físicas. Eles ficam visíveis no detalhe do produto e podem ser selecionadas no carrinho.

Esses locais podem ser configurados no Administrador Nuvem na seção Configurações/Envios e lojas físicas.

<div class="js-toggle-branches w-100" data-store="branches">
    <span class="form-row">
        <div class="col-auto">
            {% include "snipplets/svg/store.tpl" with {svg_custom_class: "icon-inline icon-lg link-module-icon svg-icon-text"} %}
        </div>
        <div class="col-6">
            <div {% if store.branches|length > 1 %}class="mb-1"{% endif %}> 
                {% if store.branches|length > 1 %}
                    {{ 'Nuestros locales' | translate }}
                {% else %}
                    {{ 'Nuestro local' | translate }}
                {% endif %}
            </div>
            {% if store.branches|length > 1 %}
                <div class="btn-link float-left">
                    <span class="js-see-branches">
                        {{ 'Ver opciones' | translate }}
                    </span>
                    {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "js-see-branches icon-inline ml-1"} %}

                    <span class="js-hide-branches" style="display: none;">
                        {{ 'Ocultar opciones' | translate }}
                        {% include "snipplets/svg/chevron-up.tpl" with {svg_custom_class: "icon-inline ml-1"} %}
                    </span>
                </div>
            {% endif %}
        </div>
    </span>
</div>

{# Store branches #}
    
<ul class="js-store-branches-container box p-0 list-unstyled mt-4 {% if product_detail %}list-readonly{% else %}radio-button-container{% endif %}" {% if store.branches|length > 1 %}style="display: none;"{% endif %}>

    {% for branch in store.branches %}
        <li class="{% if product_detail %}list-item{% else %}radio-button-item{% endif %}" data-store="branch-item-{{ branch.code }}">


            {# If cart use radiobutton #}
            
            {% if not product_detail %}
                <label class="js-shipping-radio js-branch-radio radio-button" data-loop="branch-radio-{{loop.index}}">
                    <input 
                    class="js-branch-method {% if cart.shipping_data.code == branch.code %} js-selected-shipping-method {% endif %} shipping-method" 
                    data-price="0" 
                    {% if cart.shipping_data.code == branch.code %}checked{% endif %} type="radio" 
                    value="{{branch.code}}" 
                    data-name="{{ branch.name }} - {{ branch.extra }}"
                    data-code="{{branch.code}}" 
                    data-cost="{{ 'Gratis' | translate }}"
                    name="option" 
                    style="display:none">
                    <span class="radio-button-content">
                        <div class="radio-button-icons-container">
                            <span class="radio-button-icons">
                                <span class="radio-button-icon unchecked"></span>
                                <span class="radio-button-icon checked"></span>
                            </span>
                        </div>
                        <div class="radio-button-label">
            {% endif %}
                            <div class="{% if product_detail %}list-item-content{% else %}radio-button-text{% endif %} row"> 
                                <div class="col-8 pr-0">
                                    <div class="font-small">
                                        {{ branch.name }} <span class="ml-1">{{ branch.extra }}</span>
                                    </div>
                                </div>
                                <div class="col-4 text-right">
                                    <span class="h5 shipping-price d-inline-block font-weight-bold text-primary">
                                        {{ 'Gratis' | translate }}
                                    </span>
                                </div>
                            </div>
            {% if not product_detail %}
                        </div>
                    </span>
                </label>
            {% endif %}
        </li>
    {% endfor %}
</ul>

Nós incluímos este tpl no snipplet produto-form.tpl para o detalhe do produto e cart-totals.tpl para o carrinho de compras

shipping-calculator.tpl

O snipplet shipping-calculator.tpl representa a calculadora de envio tanto no detalhe do produto quanto no carrinho.

<div class="{% if product_detail %}product-shipping-calculator{% endif %} mb-2 w-100" data-store="shipping-calculator">

    <div class="js-shipping-calculator-head shipping-calculator-head position-relative transition-soft {% if cart.shipping_zipcode %}with-zip{% else %}with-form{% endif %}">
        <div class="js-shipping-calculator-with-zipcode {% if cart.shipping_zipcode %}js-cart-saved-zipcode transition-up-active{% endif %} mt-3 mb-4 w-100 transition-up position-absolute">
            <div class="container p-0">
                <div class="row align-items-center">
                    <span class="col pr-0">
                        <span class="font-small align-sub">
                            <span>{{ "Entregas para el CP:" | translate }}</span>
                            <strong class="js-shipping-calculator-current-zip">{{ cart.shipping_zipcode }}</strong>
                        </span>
                    </span>
                    <div class="col-auto pl-0">
                        <a class="js-shipping-calculator-change-zipcode btn btn-secondary btn-small float-right py-1 px-2 px-sm-3" href="#">{{ "Cambiar CP" | translate }}</a>
                    </div>
                </div>
            </div>
        </div>
        <div class="js-shipping-calculator-form shipping-calculator-form transition-up position-absolute">

            {# Shipping calcualtor input #}
            
            {% embed "snipplets/forms/form-input.tpl" with{type_tel: true, input_value: cart.shipping_zipcode, input_name: 'zipcode', input_custom_class: 'js-shipping-input', input_placeholder: "Tu código postal" | translate, input_aria_label: 'Tu código postal' | translate, input_label: false, input_append_content: true, input_group_custom_class: 'form-row align-items-center mb-3', form_control_container_custom_class: 'col-5'} %}
                {% block input_prepend_content %}
                    <div class="col-12 mb-2">

                        {% include "snipplets/svg/truck.tpl" with {svg_custom_class: "icon-inline icon-w-18 icon-lg svg-icon-text mr-2"} %}

                        {# Free shipping achieved label #}

                        <span class="js-free-shipping-message font-weight-bold text-accent" {% if not cart.free_shipping.cart_has_free_shipping %}style="display: none;"{% endif %}>
                            {{ "¡Genial! Tenés envío gratis" | translate }}
                        </span>

                        {# Free shipping with min price label #}

                        <span class="js-shipping-calculator-label font-weight-bold" {% if cart.free_shipping.cart_has_free_shipping or not cart.free_shipping.min_price_free_shipping.min_price %}style="display: none;"{% endif %}>
                            {{ "<strong class='text-accent'>Envío gratis</strong> superando los" | translate }} <span>{{ cart.free_shipping.min_price_free_shipping.min_price }}</span>
                        </span>

                        {# Shipping default label #}

                        <span class="js-shipping-calculator-label-default" {% if cart.free_shipping.cart_has_free_shipping or cart.free_shipping.min_price_free_shipping.min_price %}style="display: none;"{% endif %}>

                            {# Regular shipping calculator label #}
                            
                            {{ 'Medios de envío' | translate }}
                        </span>
                    </div>
                {% endblock input_prepend_content %}
                {% block input_form_alert %}
                {% if store.country == 'BR' or 'AR' or 'MX' %}
                    {% set zipcode_help_ar = 'https://www.correoargentino.com.ar/formularios/cpa' %}
                    {% set zipcode_help_br = 'http://www.buscacep.correios.com.br/sistemas/buscacep/' %}
                    {% set zipcode_help_mx = 'https://www.correosdemexico.gob.mx/datosabiertos/gobmx/gobmx_Descarga.html' %}
                    <div class="col-12">
                        <a class="font-small text-primary mt-3 mb-2 d-block" href="{% if store.country == 'AR' %}{{ zipcode_help_ar }}{% elseif store.country == 'BR' %}{{ zipcode_help_br }}{% elseif store.country == 'MX' %}{{ zipcode_help_mx }}{% endif %}" target="_blank">{{ "No sé mi código postal" | translate }}</a>
                    </div>
                {% endif %}
                <div class="col-12">
                    <div class="js-ship-calculator-error invalid-zipcode alert alert-danger" style="display: none;">
                        {# Specific error message considering if store has multiple languages #}


                        {% for language in languages %}
                            {% if language.active %}
                                {% if languages | length > 1 %}
                                    {% set wrong_zipcode_wording = ' para ' | translate ~ language.country_name ~ '. Podés intentar con otro o' | translate %}
                                {% else %}
                                    {% set wrong_zipcode_wording = '. ¿Está bien escrito?' | translate %}
                                {% endif %}
                                {{ "No encontramos este código postal{1}" | translate(wrong_zipcode_wording) }}


                                {% if languages | length > 1 %}
                                    <a href="#" data-toggle="#{% if product_detail %}product{% else %}cart{% endif %}-shipping-country" class="js-modal-open btn-link btn-link-primary text-lowercase">
                                        {{ 'cambiar tu país de entrega' | translate }}
                                    </a>
                                {% endif %}
                            {% endif %}
                        {% endfor %}
                    </div>
                    <div class="js-ship-calculator-error js-ship-calculator-common-error alert alert-danger" style="display: none;">{{ "Ocurrió un error al calcular el envío. Por favor intentá de nuevo en unos segundos." | translate }}</div>
                    <div class="js-ship-calculator-error js-ship-calculator-external-error alert alert-danger" style="display: none;">{{ "El calculo falló por un problema con el medio de envío. Por favor intentá de nuevo en unos segundos." | translate }}</div>
                </div>
                {% endblock input_form_alert %}
                {% block input_append_content %}
                <span class="col-6">
                    <button class="js-calculate-shipping btn btn-default btn-block" aria-label="{{ 'Calcular envío' | translate }}">    
                        <span class="js-calculate-shipping-wording">{{ "Calcular" | translate }}</span>
                        <span class="js-calculating-shipping-wording" style="display: none;">{{ "Calculando" | translate }}</span>
                    </button>
                    {% if shipping_calculator_variant %}
                        <input type="hidden" name="variant_id" id="shipping-variant-id" value="{{ shipping_calculator_variant.id }}">
                    {% endif %}
                </span>
                {% endblock input_append_content %}
            {% endembed %}
        </div>
    </div>
    <div class="js-shipping-calculator-spinner shipping-spinner-container mb-3 float-left w-100 transition-soft text-center" style="display: none;">
        <div class="spinner-ellipsis">
            <div class="point"></div>
            <div class="point"></div>
            <div class="point"></div>
            <div class="point"></div>
        </div>
    </div>
    <div class="js-shipping-calculator-response mb-3 float-left w-100 {% if product_detail %}list list-readonly{% endif %}" style="display: none;"></div>
</div>

{# Shipping country modal #}

{% if languages | length > 1 %}


    {% if product_detail %}
        {% set country_modal_id = 'product-shipping-country' %}
    {% else %}
        {% set country_modal_id = 'cart-shipping-country' %}
    {% endif %}


    {% embed "snipplets/modal.tpl" with{modal_id: country_modal_id, modal_class: 'bottom modal-centered-small js-modal-shipping-country', modal_position: 'center', modal_transition: 'slide', modal_header: true, modal_footer: true, modal_width: 'centered', modal_zindex_top: true, modal_mobile_full_screen: false} %}
        {% block modal_head %}
            {{ 'País de entrega' | translate }}
        {% endblock %}
        {% block modal_body %}
            {% embed "snipplets/forms/form-select.tpl" with{select_label: true, select_label_name: 'País donde entregaremos tu compra' | translate, select_aria_label: 'País donde entregaremos tu compra' | translate, select_custom_class: 'js-shipping-country-select', select_group_custom_class: 'mt-4' } %}
                {% block select_options %}
                    {% for language in languages %}
                        <option value="{{ language.country }}" data-country-url="{{ language.url }}" {% if language.active %}selected{% endif %}>{{ language.country_name }}</option>
                    {% endfor %}
                {% endblock select_options%}
            {% endembed %}
        {% endblock %}
        {% block modal_foot %}
            <a href="#" class="js-save-shipping-country btn btn-primary float-right">{{ 'Aplicar' | translate }}</a>
        {% endblock %}
    {% endembed %}
{% endif %}

Nós incluímos este tpl no snipplet  product-form.tpl para o detalhe do produto e cart-totals.tpl para o carrinho de compras.

shipping_options.tpl

Neste tpl chamamos o snipplet da opção de envio, é o elemento pai da lista. Ao exibir os resultados do cálculo de frete, nós inserimos este arquivo por backend no div js-shipping-calculator-response localizado em shipping-calculator.tpl. É por causa desse comportamento que você não pode alterar o nome ou alterar seu local no repositório do theme.

Dentro da lista priorizamos as remessas mais baratas primeiro e depois as mais rápidas (sempre considerando a combinação de dois parâmetros).

{% if options %}

    {% if store.show_shipping_emergency_message %}
        <div class="alert alert-warning">{{ store.shipping_emergency_message }}</div> 
    {% endif %}

    <div class="{% if cart.items_count > 0 %}js-product-shipping-label{% endif %} font-small mb-4 pb-1" style="display: none;">
        {{ 'Opciones para tu compra <strong>si sumás este producto</strong>.' | translate }}
    </div>

    {# Check for only shipping featured options #}

    {% set has_featured_shipping = false %}

    {% for option in options_to_show if option.shipping_type == 'ship' or option.shipping_type == 'delivery' or (option.method == 'table' and option.shipping_type == 'custom') %}
        {% if option |length >= 1 %}
            {% set has_featured_shipping = true %}
        {% endif %}
    {% endfor %}

    {# Check for only non featured shipping options #}

    {% set has_non_featured_shipping = false %}

    {% for option in options_to_hide if option.shipping_type == 'ship' or option.shipping_type == 'delivery' or (option.method == 'table' and option.shipping_type == 'custom') %}
        {% if option |length >= 1 %}
            {% set has_non_featured_shipping = true %}
        {% endif %}
    {% endfor %}

    {# Pickup featured options #}

    {% set has_non_featured_pickup = false %}
    {% set has_featured_pickup = false %}

    {# Check for only pickup featured options #}

    {% for option in options_to_show if option.shipping_type == 'pickup' and option.method != 'branch' %}
        {% if option |length >= 1 %}
            {% set has_featured_pickup = true %}
        {% endif %}
    {% endfor %}

    {# Check for only non featured pickup options #}

    {% for option in options_to_hide if option.shipping_type == 'pickup' and option.method != 'branch' %}
        {% if option |length >= 1 %}
            {% set has_non_featured_pickup = true %}
        {% endif %}
    {% endfor %}

    {# Shipping options #}

    {% if has_featured_shipping %}

        <div class="full-width-container {% if has_featured_pickup %}mb-4{% endif %}">

            <div class="form-label mb-2">
                {% include "snipplets/svg/truck.tpl" with {svg_custom_class: "icon-inline icon-lg svg-icon-text mr-2 align-bottom"} %}
                {{ "Envío a domicilio" | translate }}
            </div>

            <ul class="box radio-button-container p-0 mb-0 list-unstyled">

                {# Smart shipping hides similar shipping options on a toggle div and also shows an improved shipping item #}

                {# Check if smart shipping is needed #}

                {# Include branch options inside calculador #}

                {% for option in options_to_show if option.shipping_type == 'ship' or option.shipping_type == 'delivery' or (option.method == 'table' and option.shipping_type == 'custom') %}
                    {% include "snipplets/shipping/shipping-calculator-item.tpl" with {'featured_option': true} %}
                {% endfor %}

                {% if has_non_featured_shipping %}

                    <div class="js-other-shipping-options w-100 float-left shipping-extra-options" style="display: none;">

                        {# Smart shipping hides similar shipping options on a toggle div and also shows an improved shipping item #}

                        {# Check if smart shipping is needed #}

                        {# Include branch options inside calculador #}

                        {% for option in options_to_hide if option.shipping_type == 'ship' or option.shipping_type == 'delivery' or (option.method == 'table' and option.shipping_type == 'custom') %}
                            {% include "snipplets/shipping/shipping-calculator-item.tpl" %}
                        {% endfor %}
                    </div>
             
                {% endif %}

            </ul>

            {% if has_non_featured_shipping %}
                <div class="js-toggle-more-shipping-options js-show-more-shipping-options w-100 float-left text-center mt-2">
                    <a href="#" class="btn-link">
                        <span class="js-shipping-see-more">
                            {{ 'Ver más opciones de envío' | translate }}
                        </span>
                        <span class="js-shipping-see-less" style="display: none;">
                            {{ 'Ver menos opciones de envío' | translate }}
                        </span>
                    </a>
                </div>
            {% endif %}
        </div>

    {% endif %}

    {# Pickup featured options #}

    {% if has_featured_pickup %}

        <div class="full-width-container mb-2">

            <div class="form-label mb-2">
                {% include "snipplets/svg/map-marker-alt.tpl" with {svg_custom_class: "icon-inline icon-lg svg-icon-text mr-2 align-bottom"} %}
                {{ "Retirar por" | translate }}
            </div>

            <ul class="list-unstyled box radio-button-container p-0 mb-0">

                {# Smart shipping hides similar shipping options on a toggle div and also shows an improved shipping item #}

                {# List only pickup featured options #}

                {% for option in options_to_show if option.shipping_type == 'pickup' and option.method != 'branch' %}
                    {% include "snipplets/shipping/shipping-calculator-item.tpl" with {'featured_option': true, 'pickup' : true} %}
                {% endfor %}

                {% if has_non_featured_pickup %}

                    <div class="js-other-pickup-options w-100 float-left shipping-extra-options" style="display: none;">

                        {# Smart shipping hides similar shipping options on a toggle div and also shows an improved shipping item #}

                        {# List only pickup featured options: same logic as for featured pickups but for non featured #}

                        {% for option in options_to_hide if option.shipping_type == 'pickup' and option.method != 'branch' %}
                            {% include "snipplets/shipping/shipping-calculator-item.tpl" with {'pickup' : true}  %}
                        {% endfor %}
                    </div>
                {% endif %}
            </ul>

            {% if has_non_featured_pickup %}
                <div class="js-toggle-more-shipping-options js-show-other-pickup-options w-100 float-left text-center mt-2">
                    <a href="#" class="btn-link">
                        <span class="js-shipping-see-more">
                            {{ 'Ver más opciones de retiro' | translate }}
                        </span>
                        <span class="js-shipping-see-less" style="display: none;">
                            {{ 'Ver menos opciones de retiro' | translate }}
                        </span>
                    </a>
                </div>
            {% endif %}
        </div>

    {% endif %}
    {% if store.has_smart_dates and show_time %}
        <div class="font-small float-left w-100 mb-3">{{"El tiempo de entrega <strong>no considera feriados</strong>." | translate}}</div>
    {% endif %}

{% else %}
<span>{{"No hay costos de envío para el código postal dado." | translate}}</span>
{% endif %}

{# Don't remove this #}
<input type="hidden" name="after_calculation" value="1"/>
<input type="hidden" name="zipcode" value="{{zipcode}}"/>

Incluímos este tpl usando backend após calcular o envio dentro da div com a classe js-shipping-calculator-response no shipping-calculator.tpl.

shipping-calculator-item.tpl

Como o nome indica, este snipplet é usado para mostrar cada opção de envio listada. No detalhe do produto eles são apenas informativos, enquanto que no carrinho eles mostram um radio button para que o usuário possa escolhê-lo.

{# On first calculation select as default the first option: If store only has pickup option selects pickup else selects shipping option #}

{% if has_featured_shipping %}
    {% set checked_option = featured_option and loop.first and not pickup %}
{% else %}
    {% set checked_option = featured_option and loop.first and pickup %}
{% endif %}

{% if store.has_smart_shipping_no_auto_select %}
    {% set checked_option = false %}
{% endif %}

<li class="js-shipping-list-item radio-button-item list-item" data-store="shipping-calculator-item-{{ option.code }}">
    <label class="js-shipping-radio radio-button" data-loop="shipping-radio-{{loop.index}}" data-shipping-type="{% if pickup %}pickup{% else %}delivery{% endif %}">
        <input 
        id="{% if featured_option %}featured-{% endif %}shipping-{{loop.index}}" 
        class="js-shipping-method {% if not featured_option %}js-shipping-method-hidden{% endif %} {% if pickup %}js-pickup-option{% endif %} shipping-method" 
        data-price="{{option.cost.value}}" 
        data-code="{{option.code}}" 
        data-name="{{option.name}}" 
        data-cost="{% if option.show_price %} {% if option.cost.value == 0  %}{{ 'Gratis' | translate }}{% else %}{{option.cost}}{% endif %}{% else %} {{ 'A convenir' | translate }} {% endif %}" 
        type="radio" 
        value="{{option.code}}" 
        {% if checked_option %}checked="checked"{% endif %} name="option"
        data-amplitude-event-name="cart_shipping_option_select"
        style="display:none" />
        <span class="radio-button-content">
            <div class="radio-button-icons-container">
                <span class="radio-button-icons">
                    <span class="radio-button-icon unchecked"></span>
                    <span class="radio-button-icon checked"></span>
                </span>
            </div>
            <div class="radio-button-label">

                {# Improved shipping option with no carrier img and ordered shipping info #}

                <div class="radio-button-text row"> 
                    <div class="col-8 pr-0">
                        <div class="font-small {% if option.payment_rules or option.time or option.suboptions is not empty %}mb-1{% endif %}">
                            {{option.short_name}} {% if option.method == 'branch' %}<span class="ml-1">{{ option.extra.extra }}</span>{% endif %}
                        </div>
                        {% if option.time %}
                            <div class="{% if option.suboptions is not empty or option.payment_rules %}mb-1{% endif %}">
                                {% if store.has_smart_dates %}
                                    {{option.dates}}
                                {% else %}
                                    {{option.time}}
                                {% endif %}
                            </div>
                        {% endif %}                        
                        {% if option.suboptions is not empty %}
                            <div {% if option.payment_rules %}class="mb-1"{% endif %}>
                                {% include "snipplets/shipping_suboptions/#{option.suboptions.type}.tpl" with {'suboptions': option.suboptions} %}
                            </div>
                        {% endif %}
                        {% if option.payment_rules %}
                            <div>
                                <span class="d-table float-left mr-1">
                                    {% include "snipplets/svg/info-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-text mr-2"} %}
                                </span>
                                <span class="d-table">
                                    <i>{{option.payment_rules}}</i>
                                </span>
                            </div>
                        {% endif %}
                        {% if option.warning['enable'] %}
                            <div class="w-100 mb-0 mt-3 mx-3 alert alert-warning">
                                {{ option.warning['message'] }}
                            </div>
                        {% endif %}
                    </div>
                    {% if option.show_price %} 
                        <div class="col-4 text-right">
                            <span class="h5 shipping-price d-inline-block font-weight-bold {% if option.cost.value == 0 %}text-accent{% else %}text-primary{% endif %}">
                                <div class="mb-1">
                                    {% if option.cost.value == 0  %}
                                        {{ 'Gratis' | translate }}
                                    {% else %}
                                        {{option.cost}}
                                    {% endif %}
                                </div>
                                {% if option.cost.value == 0 and option.old_cost.value %}
                                    <div class="price-compare text-foreground mr-0 font-weight-normal">{{option.old_cost}}</div>
                                {% endif %}
                            </span>
                        </div>
                    {% endif %}
                </div>
            </div>
        </span>
    </label>
</li>

Incluímos este tpl no snipplet shipping_options.tpl 

shipping_suboptions

Dentro desta pasta encontramos o arquivo select.tpl que usamos por agora somente para o meio de envio Argentino OCA, para listar as ramificações dessa empresa argentina de frete, dentro de um select.

{% set selected_option = loop.first or cart.shipping_option == option.name %}
<div class="js-shipping-suboption {{suboptions.name}}">
    {% if suboptions.options %}

        {# Read only suboptions inside popup #}

        {% set modal_id_val = (suboptions.name | sanitize) ~ '-pickup-modal-' ~ random() %}

        <div data-toggle="#{{ modal_id_val }}" class="js-modal-open mt-2">
            {% include "snipplets/svg/map-marker-alt.tpl" with {svg_custom_class: "icon-inline icon-lg mr-1"} %}
            <span class="btn-link btn-link-primary align-bottom">{{ 'Ver puntos de retiro' | translate }}</span>
        </div>

        {% embed "snipplets/modal.tpl" with{modal_id: modal_id_val, modal_class: 'bottom modal-centered-small js-modal-shipping-suboptions', modal_position: 'center', modal_transition: 'slide', modal_header: true, modal_footer: false, modal_width: 'centered', modal_zindex_top: true} %}
            {% block modal_head %}
                {{ 'Puntos de retiro' | translate }}
            {% endblock %}
            {% block modal_body %}
                <ul class="list-unstyled py-2">
                    {% for option in suboptions.options %}
                        <li class="text-capitalize mb-3">{% include "snipplets/svg/map-marker-alt.tpl" with {svg_custom_class: "icon-inline svg-icon-primary d-flex float-left mr-2"} %} <span class="d-flex">{{ option.name | lower }}</span></li>
                    {% endfor %}
                </ul>
                <div class="mt-4"><span class="opacity-50">{{ 'Cercanos al CP:'}}</span> <span class="text-primary font-weight-bold">{{cart.shipping_zipcode}}</span></div>
                <div class="mt-2 font-small">
                    {% include "snipplets/svg/info-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
                    <i>{{ "Vas a poder elegir estas opciones antes de finalizar tu compra" | translate }}</i>
                </div>
            {% endblock %}
        {% endembed %}
    {% else %}
        <input type="hidden" name="{{suboptions.name}}"/>
        <div>{{ suboptions.no_options_message | translate }}</div>
    {% endif %}
</div>

Incluímos este tpl no snipplet shipping-calculator-item.tpl 

Payments

Na pasta Payments, temos todos os arquivos relacionados aos métodos de pagamento. Assim como na pasta Shipping, recomendamos que você modifique esses arquivos o mínimo possível, devido à complexidade e importância deles no theme.

installments.tpl

Como seu nome em inglês indica, este snipplet é usado para mostrar as melhores parcelas oferecidas pela loja. Elas são exibidas no item da lista de produtos, no detalhamento dos produtos e no total do carrinho de compras (somente em lojas do Brasil).



Dentro deste snipplet usamos a condição {% if product%} para diferenciar entre as parcelas de cada produto e as parcelas do carrinho.

Da mesma forma usamos {% if product_detail%} para diferenciar entre o detalhe do produto e o item da lista, e assim usar JavaScript através das classes “js -...” atualizando o valor das parcelas quando o usuário muda de variante dentro do detalhe de um produto.

{% if product %}

  {# Product installments #}

  {% if product.show_installments and product.display_price %}

    {% set installments_info_base_variant = product.installments_info %}
    {% set installments_info = product.installments_info_from_any_variant %}

    {# If product detail installments, include container with "see installments" link #}

    {% if product_detail and ( installments_info or custom_payment.discount > 0 ) %}
      <div data-toggle="#installments-modal" data-modal-url="modal-fullscreen-payments" class="js-modal-open js-fullscreen-modal-open js-product-payments-container mb-2" {% if (not product.get_max_installments) and (not product.get_max_installments(false)) %}style="display: none;"{% endif %}>
    {% endif %}

    {# Cash discount #}

    {% if product_detail and custom_payment.discount > 0 %}
      <div class="text-center text-md-left mb-2">
        <span><strong class="text-accent">{{ custom_payment.discount }}% {{'de descuento' | translate }}</strong> {{'pagando con' | translate }} {{ custom_payment.name }}</span>
      </div>
    {% endif %}

    {% set product_can_show_installments = product.show_installments and product.display_price and product.get_max_installments.installment > 1 %}

    {% if product_can_show_installments %}

      {% set max_installments_without_interests = product.get_max_installments(false) %}
      {% set max_installments_with_interests = product.get_max_installments %}

      {% set has_no_interest_payments = max_installments_without_interests and max_installments_without_interests.installment > 1 %}

      {% if has_no_interest_payments %}
        {% set card_icon_color = 'svg-icon-accent' %}
      {% else %}
        {% set card_icon_color = 'svg-icon-text' %}
      {% endif %}

      {# If NOT product detail, just include installments alone without link or container #}
      <div class="js-max-installments-container js-max-installments {% if product_detail %}text-center text-md-left mb-2{% else %}item-installments{% endif %}">

        {% if has_no_interest_payments %}

          <div class="js-max-installments">
            {% if product_detail %}

              {# Accent color used on product detail #}

              {{ "<span class='text-accent font-weight-bold'><span class='js-installment-amount installment-amount'>{1}</span> cuotas sin interés</span> de <span class='js-installment-price installment-price'>{2}</span>" | t(max_installments_without_interests.installment, max_installments_without_interests.installment_data.installment_value_cents | money) }}
            {% else %}
              {{ "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas sin interés de <strong class='js-installment-price installment-price'>{2}</strong>" | t(max_installments_without_interests.installment, max_installments_without_interests.installment_data.installment_value_cents | money) }}
            {% endif %}
          </div>
        {% else %}
          {% if store.country != 'AR' or product_detail %}
            {% set max_installments_with_interests = product.get_max_installments %}
            {% if max_installments_with_interests %}
              <div class="js-max-installments">{{ "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas de <strong class='js-installment-price installment-price'>{2}</strong>" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</div>
            {% else %}
              <div class="js-max-installments" style="display: none;">
                {% if product.max_installments_without_interests %}
                  {% if product_detail %}

                    {# Accent color used on product detail #}

                    {{ "<span class='text-accent font-weight-bold'><span class='js-installment-amount installment-amount'>{1}</span> cuotas sin interés</span> de <span class='js-installment-price installment-price'>{2}</span>" | t(null, null) }}
                    
                  {% else %}
                    {{ "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas sin interés de <strong class='js-installment-price installment-price'>{2}</strong>" | t(null, null) }}
                  {% endif %}
                {% else %}
                  {{ "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas de <strong class='js-installment-price installment-price'>{2}</strong>" | t(null, null) }}
                {% endif %}
              </div>
            {% endif %}
          {% endif %}
        {% endif %}
      </div>
    {% endif %}

    {% if product_detail and installments_info %}
      <div class="form-row align-items-center align-items-start-md mb-4">
        {% set has_payment_logos = settings.payments %}
        {% if has_payment_logos %}
          <ul class="list-inline col col-md-auto text-center text-md-left mb-1">
            {% for payment in settings.payments %}
                {# Payment methods flags #}
                {% if store.country == 'BR' %}
                  {% if payment in ['visa', 'mastercard'] %}
                    <li>     
                      {{ payment | payment_new_logo | img_tag('',{class: 'card-img card-img-small lazyload'}) }}
                    </li>
                  {% endif %}
                {% else %}
                    {% if payment in ['visa', 'amex', 'mastercard'] %}
                      <li>
                        {{ payment | payment_new_logo | img_tag('',{class: 'card-img card-img-small lazyload'}) }}
                      </li>
                    {% endif %}
                {% endif %}
            {% endfor %}
              <li>
                {% include "snipplets/svg/credit-card-blank.tpl" with {svg_custom_class: "icon-inline icon-w-18 icon-2x " ~ card_icon_color ~ ""} %}
              </li>
          </ul>
        {% endif %}
        <div class="col-12 col-md-auto text-center">
          <a id="btn-installments" class="btn-link" {% if (not product.get_max_installments) and (not product.get_max_installments(false)) %}style="display: none;"{% endif %}>
            {% set store_set_for_new_installments_view = store.is_set_for_new_installments_view %}
            {% if store_set_for_new_installments_view %}
                {{ "Ver medios de pago" | translate }}
            {% else %}
                {{ "Ver el detalle de las cuotas" | translate }}
            {% endif %}
          </a>
        </div>
      </div>
    </div>
    {% endif %}  
  {% endif %}
{% else %}

  {# Cart installments #}
  
  {% if cart.installments.max_installments_without_interest > 1 %}
    {% set installment =  cart.installments.max_installments_without_interest  %}
    {% set total_installment = cart.total %}
    {% set interest = false %}
    {% set interest_value = 0 %}
  {% else %}
    {% set installment = cart.installments.max_installments_with_interest  %}
    {% set total_installment = (cart.total * (1 + cart.installments.interest)) %}
    {% set interest = true %}
    {% set interest_value = cart.installments.interest %}
  {% endif %}
  <div {% if installment < 2 or ( store.country == 'AR' and interest == true ) %} style="display: none;" {% endif %} data-interest="{{ interest_value }}" data-cart-installment="{{ installment }}" class="js-installments-cart-total {% if template == 'cart' %}text-md-center{% endif %} text-right {% if interest == false %}text-accent font-weight-bold{% endif %}">    
    {{ 'O hasta' | translate }}
    {% if interest == true %}
      {{ "<strong class='js-cart-installments-amount'>{1}</strong> cuotas de <strong class='js-cart-installments installment-price'>{2}</strong>" | t(installment, (total_installment / installment) | money) }}
    {% else %}
      {{ "<span class='js-cart-installments-amount'>{1}</span> cuotas sin interés de <span class='js-cart-installments installment-price'>{2}</span>" | t(installment, (total_installment / installment) | money) }}
    {% endif %}
  </div>
{% endif %}

Incluímos este tpl nos snipplets cart-totals.tpl, item.tpl y product-form.tpl

payments.tpl

Este arquivo é o componente pai do pop-up que mostra os detalhes de cada método de pagamento usando o embed para modals, modal.tpl.

Cada método de pagamento tem uma tab que, quando clicada pelo usuário, mostra seus detalhes.

Neste arquivo, incluímos os tpls payments-info-banks.tpl que mostram informações de pagamento de cada banco (aplica-se apenas a lojas Argentinas) e pagamentos-info.tpl que mostra informações dos métodos de pagamento independentes de bancos, como o PayPal, por exemplo.

{% set installments_info_base_variant = product.installments_info %}
{% set installments_info = product.installments_info_from_any_variant %}
{% if installments_info %}
{% set gateways = installments_info | length %}
{% set store_set_for_new_installments_view = store.is_set_for_new_installments_view %}
{# Get the array that contains the display settings for each payment method #}
{% set payment_methods_config = product.payment_methods_config %}

    {% embed "snipplets/modal.tpl" with{modal_id: 'installments-modal', modal_position: 'bottom', modal_transition: 'slide', modal_header: true, modal_footer: true, modal_width: 'centered', modal_mobile_full_screen: 'true'} %}
        {% block modal_head %}
            {{'Medios de pago' | translate }}
        {% endblock %}
        {% block modal_body %}

            {# Modal header and gateways tab links #}

            <div class="js-tab-container">
                <ul class="js-tab-group tab-group">
                    {% for method, installments in installments_info %}
                        {% set method_clean = method | replace(" ", "_") | lower %}

                        <li id="method_{{ method_clean }}" class="js-refresh-installment-data js-installments-gw-tab js-tab tab {% if loop.first %} active {% endif %}" data-code="{{ method }}">
                            <a href="#installment_{{ method_clean }}_{{ installment }}" class="js-tab-link tab-link">{{ method == 'paypal_multiple' ? 'PAYPAL' : (method == 'itaushopline'? 'ITAU SHOPLINE' : method == 'boleto_paghiper'? 'BOLETO PAGHIPER' : method | upper) }}</a>
                        </li>

                        {# Custom payment method #}

                        {% if loop.last and custom_payment is not null %}
                            <li id="method_{{ custom_payment.code }}" class="js-refresh-installment-data js-installments-gw-tab js-tab tab" data-code="{{ custom_payment.code }}">
                                <a href="#installment_{{ custom_payment.code }}" class="js-tab-link tab-link">
                                    {{ custom_payment.name | upper }}
                                    {% if custom_payment.discount > 0 %}
                                        <span class="label label-accent ml-1"><strong>{{ custom_payment.discount }}% {{'OFF' | translate }}</strong></span>
                                    {% endif %}
                                </a>
                            </li>
                        {% endif %}
                    {% endfor %}
                </ul>

                {# Gateways tab content #}

                <div class="js-tabs-content tab-content">
                    {% for method, installments in installments_info %}
                        {% set method_clean = method | replace(" ", "_") | lower %}
                        {% set discount = product.get_gateway_discount(method) %}
                        <div id="installment_{{ method_clean }}_" class="js-tab-panel tab-panel {% if loop.first %} active {% endif %} js-gw-tab-pane">
                            <div>

                                {% if store_set_for_new_installments_view %}

                                    {# Payments info with readonly #}

                                    {# Evaluate whether the payment method should show complete installments data #}
                                    
                                    {% if payment_methods_config[method].show_full_installments %}

                                        {# Payments Gateways with banks: at the moment only MP AR #}

                                        {% include 'snipplets/payments/payments-info-banks.tpl' %}
                                    {% else %}

                                        {# Payments Gateways with cards only #}

                                        {% include 'snipplets/payments/payments-info.tpl' %}
                                    {% endif %}    

                                {% else %}

                                    {# Installments list for ROLA stores #}

                                    {% for installment, data_installment in installments %}
                                        <div id="installment_{{ method }}_{{ installment }}">
                                            {% set rounded_installment_value = data_installment.installment_value | round(2) %}
                                            {% set total_value = (data_installment.without_interests ? data_installment.total_value : installment * data_installment.installment_value) %}
                                            {% set total_value_in_cents = total_value  | round(2) * 100 %}
                                            <strong class="js-installment-amount">{{ installment }}</strong> {% if store.country != 'BR' %}cuota{% if installment > 1 %}s{% endif %} de{% else %}x{% endif %} <strong class="js-installment-price">{{ (rounded_installment_value * 100) | money }}</strong>
                                            {% if data_installment.without_interests %} {{ 'sin interés' | t }}{% endif %}
                                        </div>
                                    {% endfor %}

                                {% endif %}
                            </div>
                        </div>

                        {# Custom payment method #}

                        {% if loop.last and custom_payment is not null %}
                            <div class="js-tab-panel tab-panel js-gw-tab-pane" id="installment_{{ custom_payment.code }}">
                                <div class="box">

                                    {# Custom method instructions #}

                                    <h6 class="mb-2">{{ 'Cuando termines la compra vas a ver la información de pago en relación a esta opción.' | translate }}</h6>

                                    {% if custom_payment.discount > 0 %}
                                        <div class="mb-1">
                                            <span><strong>{{ custom_payment.discount }}% {{'de descuento' | translate }}</strong> {{'pagando con' | translate }} {{ custom_payment.name }}</span>
                                        </div>
                                    {% endif %}

                                    {# Price total #}

                                    <h4 class="mb-1 font-weight-normal">
                                        <span>{{ 'Total:' | translate }}</span>
                                        {% if custom_payment.discount > 0 %}
                                            {% set price_with_discount = product.price - ((product.price * custom_payment.discount) / 100) %}
                                            <span class="price-compare">{{ product.price | money }}</span>
                                            <strong class="js-installments-one-payment h3 text-brand">{{ price_with_discount | money }}</strong> 
                                        {% else %} 
                                            <strong class="js-installments-one-payment ml-3">{{ product.price | money }}</strong>
                                        {% endif %}
                                    </h4>

                                    {% if custom_payment.discount > 0 %}
                                        <div class="mt-3">{{'El descuento será aplicado sobre el costo total de la compra (sin envío) al finalizar la misma.' | translate }}</div>
                                    {% endif %}
                          
                                </div>
                            </div>
                        {% endif %}
                    {% endfor %}
                </div>
            </div>
            
        {% endblock %}
        {% block modal_foot %}
            <div class="text-right">
                <span class="js-modal-close js-fullscreen-modal-close btn-link pull-right">{{ 'Volver al producto' | translate }}</span>
            </div>
        {% endblock %}
    {% endembed %}

{% endif %}

Incluímos este tpl no snipplet product-form.tpl

payments-info-banks.tpl

Representa as informações dos métodos de pagamento para bancos, agrupados por parcelas sem juros (especificando o valor das parcelas) e parcelas com juros (sem especificar o valor, pois não é a melhor alternativa de pagamento e o usuário pode vê-lo no momento da pagamento), que no momento só se aplica ao Mercado Pago na Argentina.

{% set gateways = installmentsv2['methods'][method] %}

{# Gateways with banks #}

{# Credit cards #}
{% if gateways.cc is not null %}
  <h6 class="mb-1">{{'Tarjetas de crédito' | translate }}</h6>
  <div class="box">
    {# Installments without interest modules by groups, E.g: 3, 6, 9, 12 #}

    {% if gateways.cc is null or gateways.cc is empty is not null %}
      {% for installment, banks in gateways.cc.no_interest %}
        <div>

          {# Installment amount, cost, CFT, 1 payment info and total cost #}

          <h4 class="font-weight-normal mb-1">
            {{ installment }}
            {{ 'cuotas' | translate }}
            <span>{{ 'sin interés' | t }}</span>
            {{'de' | t}}
            <strong class="js-modal-installment-price" data-installment="{{installment}}"> {{ (product.price / installment) | money }}</strong>
          </h4>
          <h6 class="font-weight-normal mb-2">
            <span class="mr-1">
              <span>{{ 'CFT: ' | translate }}</span><strong>0,00%</strong>
            </span>
            <span class="mr-1">
              <span>{{ 'Total: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
            </span>
            <span>
              <span>{{ 'En 1 pago: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
            </span>
          </h6>

          {# Banks with installments without interest flags #}

          <div class="mb-3">
            {% for bank in banks %}
              <span>
                <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ bank | bank_code_by_name | payment_new_logo }}" class="card-img card-img-big lazyload" alt="{{ bank }}">
              </span>
            {% endfor %}
          </div>
          <div class="divider"></div>
        </div>
      {% endfor %}
    {% endif %}

    {# Installments with interest in one module #}

    {% if gateways.cc.interest is not null %}
      <div>

        {# Installment amount #}

        <h4 class="font-weight-normal mb-1">
          {{ gateways.max_with_interests ~ ' cuotas con otras tarjetas' | translate }}
        </h4>
        <h6 class="font-weight-normal mb-2">
          <span>{{ 'O en 1 pago de: ' | translate }}</span>
          <strong class="js-installments-one-payment">{{ product.price | money }}</strong>
        </h6>

        {# Banks with installments with interest flags #}

        {% for bank in gateways.cc.interest %}
          <span class="js-installments-flag-tab js-installments-cash-tab">
            <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ bank | bank_code_by_name | payment_new_logo }}" class="lazyload card-img card-img-big" alt="{{ bank }}">
          </span>
        {% endfor %}
        <div class="divider"></div>
      </div>
    {% endif %}
  </div>
{% endif %}

{# Cash methods #}

{% if gateways.debit is not null or gateways.cash is not null or gateways.transfer is not null %}
  <h6 class="mb-1">{{'Tarjeta de débito y efectivo' | translate }}</h6>
  <div class="box">

    {# Debit card #}

    {% if gateways.debit is not null %}

      {# Debit price #}

      <h4 class="font-weight-normal mb-1">{{ 'Débito' | translate }}</h4>
      <h6 class="font-weight-normal mb-2">
        <span>{{ 'Precio:' | translate }} </span><strong class="js-installments-one-payment"> {{ product.price | money }}</strong>
      </h6>

      {# Debit flags #}

      {% for logo in gateways.debit %}
        <span data-type="dd" data-code="{{ card }}">
          <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ logo | payment_new_logo }}" class="lazyload card-img card-img-big">
        </span>
      {% endfor %}

      <div class="divider"></div>

    {% endif %}

    {# Cash #}

    {% if gateways.cash is not null %}

      {# Cash price #}

      <h4 class="font-weight-normal mb-1">{{'Efectivo' | translate }}</h4>
      <h6 class="font-weight-normal mb-2">
        <span>{{ 'Precio:' | translate }} </span><strong class="js-installments-one-payment"> {{ product.price | money }}</strong>
      </h6>

      {# Cash flags #}

      {% for logo in gateways.cash %}
        <span data-type="dd" data-code="{{ card }}">
          <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ logo | payment_new_logo }}" class="lazyload card-img card-img-big">
        </span>
      {% endfor %}

      <div class="divider"></div>

    {% endif %}

    {# Wire transfer #}

    {% if gateways.transfer is not null %}

      {# Transfer price #}

      <h4 class="font-weight-normal mb-1 ">{{ 'Transferencia o déposito' | translate }}</h4>
      <h6 class="font-weight-normal mb-2">
        <span>{{ 'Precio:' | translate }} </span><span class="js-installments-one-payment"> {{ product.price | money }}</span>
      </h6>

      {# Transfer logos #}

      {% for logo in gateways.transfer %}
        <span class="js-installments-flag-tab js-installments-cash-tab" data-type="dd" data-code="{{ card }}">
          <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ logo | payment_new_logo }}" class="lazyload card-img card-img-big">
        </span>
      {% endfor %}

      <div class="divider"></div>

    {% endif %}
  </div>
{% endif %}

Incluímos este tpl nol snipplet payments.tpl

payments-info.tpl

Este tpl mostra informações sobre métodos de pagamento que não dependem de um banco na Argentina e também inclui uma tabela com os detalhes dos pagamentos por métodos de pagamento no Brasil.

{% set installments_data = installmentsv2['methods'][method] %}

{# Gateways without banks: cards only #}

{% if installments_data['cards'] %}

    {# Credit cards #}

    <h6 class="mb-1">{{'Tarjetas de crédito' | translate }}</h6>
    <div id="installment-credit-card-option-{{ method }}" class="box">

        {# Credit cards max installments only for AR stores #}

        {% if store.country == 'AR' %}

            {% if installments_data['max_without_interests'] != '0' %}
                <h4 class="font-weight-normal mb-1">
                    {{ installments_data['max_without_interests'] }}
                    {{ 'cuotas' | translate }}
                    <span>{{ 'sin interés' | t }}</span>
                    {{'de' | t}}
                    <strong class="js-modal-installment-price" data-installment="{{ installments_data['max_without_interests'] }}"> {{ (product.price / installments_data['max_without_interests']) | money }}</strong>
                </h4>
                <h6 class="font-weight-normal mb-2">
                    <span class="mr-1">
                        <span>{{ 'CFT: ' | translate }}</span><strong>0,00%</strong>
                    </span>
                    <span class="mr-1">
                        <span>{{ 'Total: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
                    </span>
                    <span class="mr-1">
                        <span>{{ 'En 1 pago: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
                    </span>
                </h6>
            {% elseif installments_data['max_with_interests'] > 0 %}
                <h4 class="font-weight-normal mb-1">
                    {{ 'Hasta' | translate }}
                    {{ installments_data['max_with_interests'] }}
                    {{ 'cuotas' | translate }}
                </h4>
                <h6 class="font-weight-normal mb-2">
                    <span>
                        <span>{{ 'O en 1 pago de: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
                    </span>
                </h6>
            {% else %}
                <h4 class="font-weight-normal mb-1">
                    <span>{{ 'En 1 pago: ' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
                </h4>
            {% endif %}

        {% endif %}

        {# Credit cards flags #}

        {% for logo in installments_data['cards'] %}
            <span class="mb-3">
                <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ logo | payment_new_logo }}" class="lazyload card-img card-img-medium">
            </span>
        {% endfor %}

        {% if store.country != 'AR' %}

            {# Installments list for non AR stores #}

            <table class="table">
                <thead>
                    <tr>
                        <th colspan="2">{{ 'Cuotas ' | translate }}</th>
                        <th class="text-right">{{ 'Total' | translate }}</th>
                    </tr>
                </thead>
                <tbody>
                    {% for installment, data_installment in installments %}
                        {% set rounded_installment_value = data_installment.installment_value | round(2) %}
                        {% set total_value = (data_installment.without_interests ? data_installment.total_value : installment * data_installment.installment_value) %}
                        {% set total_value_in_cents = total_value  | round(2) * 100 %}
                        <tr id="installment_{{ method }}_{{ installment }}">

                            {# Installment amount #}

                            <td>
                                <strong><span class="js-installment-amount">{{ installment }}</span></strong>
                                </span>{% if installment > 1 %}{{ 'cuotas' | translate }}{% else %}{{ 'cuota' | translate }}{% endif %}</span>
                            </td>

                            {# Installment price #}

                            <td>
                                <span>{{ 'de ' | translate }}</span>
                                <strong><span class="js-installment-price">{{ (rounded_installment_value * 100) | money }}</span> </strong>


                                {% if data_installment.without_interests or installments_data['max_with_interests'] == 0 %}
                                    {{ 'sin interés' | t }}
                                {% endif %}
                            </td>

                            {# Total price #}


                            <td class="js-installment-total-price text-right">
                                {{ total_value_in_cents | money }}
                            </td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        {% endif %}
    </div>
{% endif %}

{# Cash methods #}

{% if installments_data['direct'] %}

    {# Cash module title #}

    <h6 class="mb-1">
        {% if store.country == 'BR' %}
            {% if wording_method_only_cash %}
                {{'Efectivo' | translate }}
            {% elseif wording_method_only_debit %}
                {{'Débito online' | translate }}
            {% else %}
                {{'Efectivo / Débito online' | translate }}
            {% endif %}
        {% else %}
            {{'Tarjeta de débito y efectivo' | translate }}
        {% endif %}
    </h6>

    {# If has debit card or cash #}

    <div id="installment-cash-option-{{ method }}" class="box">

        {# Cash flags #}

        <div class="">
            {% for logo in installments_data['direct'] %}
                <span>
                    <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ logo | payment_new_logo }}" class="lazyload card-img card-img-medium">
                </span>
            {% endfor %}
        </div>

        {# Cash total #}

        <h4 class="font-weight-normal mb-0">
            <span>{{ 'Total:' | translate }}</span><strong class="js-installments-one-payment">{{ product.price | money }}</strong>
        </h4>

        {# Boleto message #}

        {% if method in ['boleto_paghiper'] and discount > 0.0 %}
            <div> {{'Boleto Paghiper tiene un' | translate }} <strong>{{discount}}% {{'de descuento' | translate }}</strong> {{'que será aplicado sobre el costo total de la compra al finalizar la misma.' | translate }}</div>
        {% endif %}
    </div>
{% endif %}

Incluimos este tpl en el snipplet payments.tpl

Product

Dentro da pasta Product, encontramos todos os snipplets em relação aos detalhes do produto.

product-form.tpl

Neste snipplet é o código do formulário do produto onde incluímos:

  • O nome
  • O preço
  • O texto das promoções
  • As parcelas e o link para ver mais sobre os métodos de pagamento
  • As variantes
  • O botão comprar
  • A calculadora de envio e as lojas físicas

Além desses arquivos, fora do formulário HTML, mas ainda dentro de product-form.tpl, também encontramos:

  • O pop-up com o detalhe do método de pagamento
  • Os links para compartilhar nas redes sociais
  • A descrição do produto adicionada no Administrador Nuvem.

O JavaScript em relação a este formulário pode ser encontrado em store.js.tpl

{# Product name and breadcrumbs #}

{% embed "snipplets/page-header.tpl" %}
    {% block page_header_text %}{{ product.name }}{% endblock page_header_text %}
{% endembed %}

{# Product price #}

<div class="price-container text-center text-md-left" data-store="product-price-{{ product.id }}">
    <span class="d-inline-block">
       <h4 id="compare_price_display" class="js-compare-price-display price-compare {% if product_can_show_installments or (product.promotional_offer and not product.promotional_offer.script.is_percentage_off) %}mb-2{% endif %}" {% 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>
    <span class="d-inline-block">
        <h4 class="js-price-display {% if product_can_show_installments or (product.promotional_offer and not product.promotional_offer.script.is_percentage_off) %}mb-2{% endif %}" id="price_display" {% if not product.display_price %}style="display:none;"{% endif %}>{% if product.display_price %}{{ product.price | money }}{% endif %}</h4>
    </span>
</div>

{# Promotional text #}

{% if product.promotional_offer and not product.promotional_offer.script.is_percentage_off and product.display_price %}
    <div class="js-product-promo-container text-center text-md-left">
        {% if product.promotional_offer.script.is_discount_for_quantity %}
            {% for threshold in product.promotional_offer.parameters %}
                <h4 class="mb-2 text-accent"><strong>{{ "¡{1}% OFF comprando {2} o más!" | translate(threshold.discount_decimal_percentage * 100, threshold.quantity) }}</strong></h4>
            {% endfor %}
        {% else %}
            <h4 class="mb-2 text-accent"><strong>{{ "¡Llevá {1} y pagá {2}!" | translate(product.promotional_offer.script.quantity_to_take, product.promotional_offer.script.quantity_to_pay) }}</strong></h4> 
        {% endif %}
        {% if product.promotional_offer.scope_type == 'categories' %}
            <p>{{ "Válido para" | translate }} {{ "este producto y todos los de la categoría" | translate }}:  
            {% for scope_value in product.promotional_offer.scope_value_info %}
               {{ scope_value.name }}{% if not loop.last %}, {% else %}.{% endif %}
            {% endfor %}</br>{{ "Podés combinar esta promoción con otros productos de la misma categoría." | translate }}</p>
        {% elseif product.promotional_offer.scope_type == 'all'  %}
            <p>{{ "Vas a poder aprovechar esta promoción en cualquier producto de la tienda." | translate }}</p>
        {% endif %}  
    </div> 
{% endif %}

{# Product installments #}

{% include "snipplets/payments/installments.tpl" with {'product_detail' : true} %}

{# Product form, includes: Variants, CTA and Shipping calculator #}

 <form id="product_form" class="js-product-form" method="post" action="{{ store.cart_url }}" data-store="product-form-{{ product.id }}">
    <input type="hidden" name="add_to_cart" value="{{product.id}}" />
     {% if product.variations %}
        {% include "snipplets/product/product-variants.tpl" %}
    {% endif %}


    {% if product.available and product.display_price %}
        {% include "snipplets/product/product-quantity.tpl" %}
    {% endif %}
    {% set state = store.is_catalog ? 'catalog' : (product.available ? product.display_price ? 'cart' : 'contact' : 'nostock') %}
    {% set texts = {'cart': "Agregar al carrito", 'contact': "Consultar precio", 'nostock': "Sin stock", 'catalog': "Consultar"} %}

    {# Add to cart CTA #}

    <div class="mb-4">

        <input type="submit" class="js-addtocart js-prod-submit-form btn btn-primary btn-block mb-4 {{ state }}" value="{{ texts[state] | translate }}" {% if state == 'nostock' %}disabled{% endif %} />

        {# Fake add to cart CTA visible during add to cart event #}

        {% include 'snipplets/placeholders/button-placeholder.tpl' with {custom_class: "btn-block mb-4"} %}

        <div class="js-added-to-cart-product-message float-leftt w-100 mb-3 text-center text-md-left" style="display: none;">
            {{'Ya agregaste este producto.' | translate }}<a href="#" class="js-modal-open js-fullscreen-modal-open btn btn-link ml-1" data-toggle="#modal-cart" data-modal-url="modal-fullscreen-cart">{{ 'Ver carrito' | translate }}</a>
        </div>
    </div>

    {# Define contitions to show shipping calculator and store branches on product page #}

    {% set show_product_fulfillment = settings.shipping_calculator_product_page and (store.has_shipping or store.branches) and not product.free_shipping and not product.is_non_shippable %}

    {% if show_product_fulfillment %}

        <div class="divider"></div>

        {# Shipping calculator and branch link #}

        <div id="product-shipping-container" class="product-shipping-calculator list" {% if not product.display_price or not product.has_stock %}style="display:none;"{% endif %}>

            {# Shipping Calculator #}
            
            {% if store.has_shipping %}
                {% include "snipplets/shipping/shipping-calculator.tpl" with {'shipping_calculator_variant' : product.selected_or_first_available_variant, 'product_detail': true} %}
            {% endif %}

            {% if store.branches %}
                
                {# Link for branches #}
                {% include "snipplets/shipping/branches.tpl" with {'product_detail': true} %}
            {% endif %}
        </div>
        <div class="divider"></div>
    {% endif %} 
 </form>

{# Product payments details #}

{% include 'snipplets/payments/payments.tpl' %}

{# Product share #}

{% include 'snipplets/social/social-share.tpl' %}

{# Product description #}

{% if product.description is not empty %}
    <div class="product-description user-content" data-store="product-description-{{ product.id }}">
        <h5 class="my-3">{{ "Descripción" | translate }}</h5>
        {{ product.description }}
    </div>
{% endif %}


Incluímos este tpl no template product.tpl

product-image.tpl

Dentro do product-image.tpl temos a imagem do produto, os labels de oferta, o estoque e o envio grátis e um espaço reservado para um placeholder de vetores que é exibido até a imagem do slider seja carregada.

Neste snipplet também incluímos as classes necessárias para o zoom com o Fancybox, bem como a implementação para o lazy load com o Lazysizes.

O JavaScript em relação ao slider e zoom pode ser encontrado em store.js.tpl

{% set has_multiple_slides = product.images_count > 1 or product.video_url %}

{% if product.images_count > 0 %}
    <div class="js-swiper-product nube-slider-product swiper-container" style="visibility:hidden; height:0;">
        {% include 'snipplets/labels.tpl' with {'product_detail': true} %}
        <div class="swiper-wrapper">
            {% for image in product.images %}
             <div class="swiper-slide js-product-slide slider-slide" data-image="{{image.id}}" data-image-position="{{loop.index0}}">
                 <a href="{{ image | product_image_url('huge') }}" data-fancybox="product-gallery" class="d-block p-relative" style="padding-bottom: {{ image.dimensions['height'] / image.dimensions['width'] * 100}}%;">
                     <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset='{{  image | product_image_url('large') }} 480w, {{  image | product_image_url('huge') }} 640w' data-sizes="auto" class="js-product-slide-img product-slider-image img-absolute img-absolute-centered lazyautosizes lazyload" {% if image.alt %}alt="{{image.alt}}"{% endif %}/>
                     <img src="{{ image | product_image_url('tiny') }}" class="js-product-slide-img product-slider-image img-absolute img-absolute-centered blur-up" {% if image.alt %}alt="{{image.alt}}"{% endif %} />
                </a>
             </div>
            {% endfor %}
            {% include 'snipplets/product/product-video.tpl' %}
        </div>
        <div class="js-swiper-product-pagination swiper-pagination swiper-pagination-white"></div>
        {% if has_multiple_slides %}
            <div class="js-swiper-product-prev swiper-button-prev d-none d-md-block">{% include "snipplets/svg/chevron-left.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
            <div class="js-swiper-product-next swiper-button-next d-none d-md-block">{% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
        {% endif %}
    </div>
    {% snipplet 'placeholders/product-detail-image-placeholder.tpl' %}
{% endif %}

Incluímos este tpl no template product.tpl

product-video.tpl

Neste tpl temos o código para o vídeo do produto.

{% if product.video_url %}
    {% if product.images_count > 1 %}
        {% set video_index = product.images_count %}
    {% else %}
        {% set video_index = 1 %}
    {% endif %}
    <div class="js-product-slide js-product-video-slide swiper-slide slider-slide" data-image-position="{{ video_index }}">
        <div class="product-video-container">
            <div class="product-video">
                {# Visible video inside slider #}
                {% include 'snipplets/video-item.tpl' with {product_modal_trigger: true, product_video: true} %}

                {# Hidden video inside modal #}
                {% include 'snipplets/video-item.tpl' with {product_modal: true, product_video: true} %}
            </div>
        </div>
    </div>
{% endif %}

Incluímos este tpl no snipplet product-image.tpl

product-quantity.tpl

Como o nome indica, neste tpl temos o código com o número de unidades a adicionar ao carrinho.

Você pode encontrar o JavaScript das unidades dentro do store.js.tpl.

{# Product quantity #}

{% if not quickshop %}
    <div class="row">
        <div class="col col-md-4">
{% endif %}
{% embed "snipplets/forms/form-input.tpl" with{type_number: true, input_value: '1', input_name: 'quantity' ~ item.id, input_custom_class: 'js-quantity-input text-center', input_label: false, input_append_content: true, input_group_custom_class: 'js-quantity form-row align-items-center', form_control_container_custom_class: 'col-6', input_min: '1', input_aria_label: 'Cambiar cantidad' | translate } %}
    {% block input_prepend_content %}
        <span class="js-quantity-down col-3 text-center">
            {% include "snipplets/svg/minus.tpl" with {svg_custom_class: "icon-inline icon-w-12 icon-lg svg-icon-text"} %}
        </span>
    {% endblock input_prepend_content %}
    {% block input_append_content %}
        <span class="js-quantity-up col-3 text-center">
            {% include "snipplets/svg/plus.tpl" with {svg_custom_class: "icon-inline icon-w-12 icon-lg svg-icon-text"} %}
        </span>
    {% endblock input_append_content %}
{% endembed %}
{% if not quickshop %}
        </div>
    </div>
{% endif %}

Incluímos este tpl nos snipplets product-form.tpl e item.tpl

product-variants.tpl

Neste arquivo listamos todas as variantes de um produto (no máximo 3) e suas propriedades na forma de um select.

O JavaScript em relação à quantidade é encontrado no store.js.tpl

<div class="js-product-variants{% if quickshop %} js-product-quickshop-variants text-left{% endif %} form-row">
    {% for variation in product.variations %}
        <div class="js-product-variants-group {% if variation.name in ['Color', 'Cor'] %}js-color-variants-container{% endif %} {% if loop.length == 3 %} {% if quickshop %}col-4{% else %}col-12{% endif %} col-md-4 {% elseif loop.length == 2 %} col-6 {% else %} col {% if quickshop %}col-md-12{% else %}col-md-6{% endif %}{% endif %}">
            {% embed "snipplets/forms/form-select.tpl" with{select_label: true, select_label_name: '' ~ variation.name ~ '', select_for: 'variation_' ~ loop.index , select_data: 'variant-id', select_data_value: 'variation_' ~ loop.index, select_name: 'variation' ~ '[' ~ variation.id ~ ']', select_custom_class: 'js-variation-option js-refresh-installment-data'} %}
                {% block select_options %}
                    {% for option in variation.options %}
                        <option value="{{ option.id }}" {% if product.default_options[variation.id] == option.id %}selected="selected"{% endif %}>{{ option.name }}</option>
                    {% endfor %}
                {% endblock select_options%}
            {% endembed %}
        </div>
    {% endfor %}
</div>

Incluímos o tpl nos snipplets product-form.tpl e item.tpl

product-related.tpl 

Neste snipplet, temos a funcionalidade de produtos relacionados os quais são mostrados em um slider.

Você pode encontrar o JavaScript do slider de produtos relacionados no store.js.tpl

{# /*============================================================================
  #Product Related Grid
==============================================================================*/

#Properties

#Related Slider

#}

{% set related_products_ids = product.metafields.related_products.related_products_ids %}
{% if related_products_ids %}
    {% set related_products = related_products_ids | get_products %}
    {% set show = (related_products | length > 0) %}
{% endif %}
{% if not show %}
    {% set related_products = category.products | shuffle | take(8) %}
    {% set show = (related_products | length > 1) %}
{% endif %}

<section id="related-products" class="section-products-related">
    {% if show %}
        <div class="container">
            <div class="row">
                {% if settings.products_related_title %}
                    <div class="col-12 text-center">
                        <h3>{{ settings.products_related_title }}</h3>
                    </div>
                {% endif %}
                <div class="col-12">
                    <div class="js-swiper-related swiper-container">
                        <div class="swiper-wrapper">
                            {% for related in related_products %}
                                {% if product.id != related.id %}
                                    {% include 'snipplets/grid/item.tpl' with {'product': related, 'slide_item': true} %}
                                {% endif %}
                            {% endfor %}
                        </div>
                        {% if related_products | length < 4 %}
                        <div class="d-md-none">
                        {% endif %}
                            <div class="js-swiper-related-pagination swiper-pagination"></div>
                            <div class="js-swiper-related-prev swiper-button-prev">{% include "snipplets/svg/chevron-left.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
                            <div class="js-swiper-related-next swiper-button-next">{% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
                        {% if related_products | length < 4 %}
                        </div>
                        {% endif %}
                    </div>
                </div>
            </div>
        </div>
    {% endif %}
</section>

Incluímos este tpl no snipplet product-form.tpl

Header

Dentro da pasta header estão todos os arquivos em relação ao head da loja, que é a parte onde estão a navegação, o logotipo, o mecanismo de busca e o ícone do carrinho.

header.tpl

Este é o tpl “pai” do header da loja, onde, além do que mencionamos antes, temos também o modal que mostra o carrinho de compras, cart-panel.tpl, que é incluído usando um embed.

{# Site Overlay #}
<div class="js-overlay site-overlay" style="display: none;"></div>

{# Header #}

{% set show_transparent_head = template == 'home' and settings.head_transparent and settings.slider and not settings.slider is empty %}

<header class="js-head-main head-main {% if show_transparent_head %}head-transparent {% if settings.head_fix %}head-transparent-fixed{% else %}head-transparent-absolute{% endif %}{% endif %} head-{{ settings.head_background }} {% if settings.head_fix %}head-fix{% endif %} {% if not settings.head_fix and show_transparent_head %}head-absolute{% endif %}" data-store="head">

    {# Advertising #}
    
    {% if settings.ad_bar and settings.ad_text %}
        {% snipplet "header/header-advertising.tpl" %}
    {% endif %}

    <div class="container">
        <div class="row no-gutters align-items-center">
            <div class="col">{% snipplet "navigation/navigation.tpl" %}</div>
            <div class="col text-center">{% snipplet "header/header-logo.tpl" %}</div>
            <div class="col text-right">{% snipplet "header/header-utilities.tpl" %}</div>
        </div>
    </div>    
    {% include "snipplets/notification.tpl" with {order_notification: true} %}
    {% if settings.head_fix and settings.ajax_cart %}
        {% include "snipplets/notification.tpl" with {add_to_cart: true} %}
    {% endif %}
</header>

{% if not settings.head_fix %}
    {% include "snipplets/notification.tpl" with {add_to_cart: true, add_to_cart_fixed: true} %}
{% endif %}

{# Hamburger panel #}

{% embed "snipplets/modal.tpl" with{modal_id: 'nav-hamburger',modal_class: 'nav-hamburger modal-docked-small', modal_position: 'left', modal_transition: 'fade', modal_width: 'full'  } %}
    {% block modal_body %}
        {% snipplet "navigation/navigation-panel.tpl" %}
    {% endblock %}
{% endembed %}

{# Notifications #}

{# Modal Search #}

{% embed "snipplets/modal.tpl" with{modal_id: 'nav-search', modal_position: 'right', modal_transition: 'slide', modal_width: 'docked-md' } %}
    {% block modal_body %}
        {% snipplet "header/header-search.tpl" %}
    {% endblock %}
{% endembed %}

{% if not store.is_catalog and settings.ajax_cart and template != 'cart' %}           

    {# Cart Ajax #}

    {% embed "snipplets/modal.tpl" with{modal_id: 'modal-cart', modal_position: 'right', modal_transition: 'slide', modal_width: 'docked-md', modal_form_action: store.cart_url, modal_form_class: 'js-ajax-cart-panel', modal_mobile_full_screen: true, modal_form_hook: 'cart-form' } %}
        {% block modal_head %}
            {% block page_header_text %}{{ "Carrito de Compras" | translate }}{% endblock page_header_text %}
        {% endblock %}
        {% block modal_body %}
            {% snipplet "cart-panel.tpl" %}
        {% endblock %}
    {% endembed %}

{% endif %}

Incluímos este tpl no template layout.tpl

header-advertising.tpl

Nesse tpl temos o código de uma barra de anúncios em que a pessoa que gerencia a loja pode adicionar um texto com um link.

<section class="section-advertising">
    <div class="container">
        <div class="row-fluid">
            <div class="col text-center">
                   {% if settings.ad_bar and settings.ad_text %}
                       {% if settings.ad_url %}
                        <a class="link-contrast" href="{{ settings.ad_url }}">
                    {% endif %}  
                        {% if settings.ad_text %}
                            {{ settings.ad_text }}
                        {% endif %} 
                    {% if settings.ad_url %}
                        </a>
                    {% endif %}  
                {% endif %}           
            </div>
        </div>
    </div>
</section>

Incluímos este tpl no snipplet header.tpl

header-logo.tpl

Neste arquivo temos o logotipo da loja, tanto quando a loja tem uma imagem carregada como quando não tem e mostramos o seu nome por padrão.

{% if template == 'home' %}
    <h1 class="m-0">
{% endif %}
<div id="logo" class="logo-img-container {% if not has_logo %}hidden{% endif %}">
    {{ store.logo('medium') | img_tag(store.name, {class: 'logo-img  transition-soft-slow'}) | a_tag(store.url) }}
</div>
<div id="no-logo" class="logo-text-container {% if has_logo %} hidden{% endif %}">
    <a class="logo-text h1" href="{{ store.url }}">{{ store.name }}</a>
</div>
{% if template == 'home' %}
    </h1>
{% endif %}

Incluímos este tpl no snipplet header.tpl e no template password.tpl

header-search-results.tpl

Usamos este snipplet para mostrar sugestões quando o usuário procura por produtos. Exibe imagem, nome, preço e parcelas dos produtos sugeridos, bem como um link para ir para a página de resultados de pesquisa onde mostramos todos os resultados.

Nós mostramos até 6 sugestões dentro deste arquivo, mas podemos modificá-lo alterando a variável search_suggestions.

<ul class="search-suggest-list">
    {% set search_suggestions = products | take(6) %}
    {% for product in search_suggestions %}
        <li class="search-suggest-item container-fluid">
            <a href="{{ product.url }}" class="search-suggest-link row justify-content-md-center">
                <div class="search-suggest-image-container col-xs-auto">
                    {{ product.featured_image | product_image_url("tiny") | img_tag(product.featured_image.alt, {class: 'search-suggest-image'}) }}
                </div>
                <div class="search-suggest-text col">
                    <p class="search-suggest-name">
                        {{ product.name | highlight(query) }}
                    </p>
                    {% if product.display_price %}
                        <p>
                            {{ product.price | money }}

                            {% set product_can_show_installments = product.show_installments and product.display_price and product.get_max_installments.installment > 1 %}
                            {% if product_can_show_installments %}
                                {% set max_installments_without_interests = product.get_max_installments(false) %}
                                {% if max_installments_without_interests and max_installments_without_interests.installment > 1 %}
                                    <span>| {{ "Hasta <strong class='installment-amount'>{1}</strong> cuotas sin interés" | t(max_installments_without_interests.installment) }}</span>
                                {% endif %}
                            {% endif %}
                        </p>
                    {% endif %}
                </div>
                <div class="col-xs-auto">
                    {% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline search-suggest-icon"} %}
                </div>
            </a>
        </li>
    {% endfor %}
    <a href="#" class="js-search-suggest-all-link btn btn-primary d-block">{{ 'Ver todos los resultados' | translate }}</a>
</ul>

É adicionado dentro da div com a classe js-search-suggest usando JavaScript dentro do arquivo store.js.tpl

header-search.tpl

Este arquivo representa o formulário de pesquisa que possui um campo e um botão submit. Além disso, ele tem uma div com a classe js-search-suggest onde o header-search-results.tpl que mostra as sugestões de busca é inserido.

<form class="js-search-container js-search-form" action="{{ store.search_url }}" method="get">
    <div class="form-group m-0">
        <input class="js-search-input form-control search-input" autocomplete="off" type="search" name="q" placeholder="{{ 'Buscar' | translate }}" aria-label="{{ 'Buscador' | translate }}"/>
        <button type="submit" class="btn search-input-submit" value="{{ 'Buscar' | translate }}" aria-label="{{ 'Buscar' | translate }}">
            {% include "snipplets/svg/search.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
        </button>
    </div>
</form>
<div class="js-search-suggest search-suggest">
    {# AJAX container for search suggestions #}
</div>

Incluímos este tpl no snipplet header.tpl

header-utilities.tpl

Dentro deste snipplet incluímos os ícones principais do theme, exceto o ícone que abre a navegação (hamburger), pois está dentro do grupo de snipplets de navegação.

<div class="utilities-container">
    <div class="utilities-item">
        <a href="#" class="js-modal-open js-toggle-search utilities-link" data-toggle="#nav-search" aria-label="{{ 'Buscador' | translate }}">
            {% include "snipplets/svg/search.tpl" with {svg_custom_class: "icon-inline icon-w-16 svg-icon-text"} %}
        </a>
    </div>
    {% if not store.is_catalog %}    
    <div class="utilities-item">
        <div id="ajax-cart" class="cart-summary">
            <a href="#" {% if template != 'cart' %}class="js-modal-open js-toggle-cart"{% endif %} data-toggle="#modal-cart">
                {% include "snipplets/svg/shopping-bag.tpl" with {svg_custom_class: "icon-inline icon-w-14 svg-icon-text"} %}
                <span class="js-cart-widget-amount cart-widget-amount">{{ "{1}" | translate(cart.items_count ) }}</span>
            </a>
        </div>
    </div>
    {% endif %}
</div>

Incluímos este tpl no snipplet header.tpl

Footer

Footer.tpl

O footer do theme está incluído neste tpl, que inclui:

  • O formulário de newsletter, que é um snipplet em si
  • Os ícones (com links) das redes sociais, que também tem seu próprio snipplet
  • Footer de navegação (Contido em seu próprio snipplet)
  • Links de contato (um snipplet também usado na página de contato)
  • Logotipos de meios de pagamento e envio
  • Informações de direitos autorais
  • Selos personalizados, que são imagens carregadas pelo administrador da loja no rodapé

{% set has_social_network = store.facebook or store.twitter or store.pinterest or store.instagram %}
{% set has_footer_contact_info = store.phone or store.email or store.blog or store.address %}          

{% set has_footer_menu = settings.footer_menu %}
{% set has_payment_logos = settings.payments %}
{% set has_shipping_logos = settings.shipping %}
{% set has_shipping_payment_logos = has_payment_logos or has_shipping_logos %}
<footer class="js-hide-footer-while-scrolling display-when-content-ready" data-store="footer">
    <div class="container">

        {% if template != 'password' %}

            {# Newsletter #}
            {% if settings.news_show %}
                {% include "snipplets/newsletter.tpl" %}
            {% endif %}

        {% endif %}
        
        {# Social #}
         {% if has_social_network %}
             <div class="row element-footer">
                 <div class="col text-center">{% include "snipplets/social/social-links.tpl" %}</div>
            </div>
        {% endif %}

        {% if template != 'password' %}

            {# Foot Nav #}
            {% if has_footer_menu %}
                <div class="row element-footer">
                     <div class="col text-center">{% include "snipplets/navigation/navigation-foot.tpl" %}</div>
                </div>
            {% endif %}

        {% endif %}

        {# Contact #}
         {% if has_footer_contact_info %}
             <div class="row element-footer">
                 <div class="col text-center">{% include "snipplets/contact-links.tpl" %}</div>
            </div>
        {% endif %}

        {# Logos Payments and Shipping #}
         {% if has_shipping_payment_logos %}
             <div class="row element-footer footer-payments-shipping-logos">
                 {% if has_payment_logos %}
                     <div class="col text-center">{% include "snipplets/logos-icons.tpl" with {'payments': true} %}</div>
                {% endif %}
                 <div class="w-100 my-2"></div>
                 {% if has_shipping_logos %}
                     <div class="col text-center">{% include "snipplets/logos-icons.tpl" with {'shipping': true} %}</div>
                 {% endif %}
            </div>
        {% endif %}


        <div class="row element-footer">
            <div class="col-md-6 text-center text-md-left">
                {#
                La leyenda que aparece debajo de esta linea de código debe mantenerse
                con las mismas palabras y con su apropiado link a Tienda Nube;
                como especifican nuestros términos de uso: http://www.tiendanube.com/terminos-de-uso .
                Si quieres puedes modificar el estilo y posición de la leyenda para que se adapte a
                tu sitio. Pero debe mantenerse visible para los visitantes y con el link funcional.
                Os créditos que aparece debaixo da linha de código deverá ser mantida com as mesmas
                palavras e com seu link para Nuvem Shop; como especificam nossos Termos de Uso:
                http://www.nuvemshop.com.br/termos-de-uso. Se você quiser poderá alterar o estilo
                e a posição dos créditos para que ele se adque ao seu site. Porém você precisa
                manter visivél e com um link funcionando.
                #}
                {{ new_powered_by_link }}
            </div>
            <div class="col-md-6 copyright text-center text-md-right pt-4 pt-md-0">
                {{ "Copyright {1} - {2}. Todos los derechos reservados." | translate( (store.business_name ? store.business_name : store.name), "now" | date('Y') ) }}
            </div>
        </div>


        {# AFIP - EBIT - Custom Seal #}
        {% if store.afip or ebit or settings.custom_seal_code or ("seal_img.jpg" | has_custom_image) %}
            {% if store.afip or ebit %}
                <div class="row element-footer">
                     <div class="col text-center">
                         {% if store.afip %}
                            <div class="footer-logo afip seal-afip">
                                {{ store.afip | raw }}
                            </div>
                        {% endif %}
                        {% if ebit %}
                            <div class="footer-logo ebit seal-ebit">
                                {{ ebit }}
                            </div>
                        {% endif %}
                     </div>
                 </div>
             {% endif %}
             {% if "seal_img.jpg" | has_custom_image or settings.custom_seal_code %}
                <div class="row element-footer">
                     <div class="col text-center">
                        {% if "seal_img.jpg" | has_custom_image %}
                            <div class="footer-logo custom-seal">
                                {% if settings.seal_url != '' %}
                                    <a href="{{ settings.seal_url }}" target="_blank">
                                {% endif %}
                                    <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ "seal_img.jpg" | static_url }}" class="custom-seal-img lazyload" alt="{{ 'Sello de' | translate }} {{ store.name }}"/>
                                {% if settings.seal_url != '' %}
                                    </a>
                                {% endif %}
                            </div>
                        {% endif %}
                        {% if settings.custom_seal_code %}
                            <div class="custom-seal custom-seal-code">
                                {{ settings.custom_seal_code | raw }}
                            </div>
                        {% endif %}
                    </div>
                </div>
            {% endif %}
        {% endif %}

    </div>
</footer>

Incluímos este tpl nos templates layout.tpl e password.tpl

Navigation

navigation.tpl

Neste tpl incluímos o ícone que abre o modal de navegação.

<div class="utilities-container">
    <div class="utilities-item">
        <a href="#" class="js-modal-open utilities-link" data-toggle="#nav-hamburger" aria-label="{{ 'Menú' | translate }}">
            {% include "snipplets/svg/bars.tpl" with {svg_custom_class: "icon-inline icon-w-14 svg-icon-text"} %}
        </a>
    </div>
</div>

Incluímos este tpl no snipplet header.tpl 

navigation-panel.tpl

Este tpl mostra o conteúdo do modal onde temos os links para as páginas e categorias, para efetuar login, criar uma conta e alterar o idioma da loja.

Dentro desse arquivo nós chamamos snipplet para a lista de links navigation-nav-list.tpl.

<div class="nav-primary">
    <ul class="nav-list" data-store="navigation">
        {% snipplet "navigation/navigation-nav-list.tpl" %}
    </ul>
</div>

<div class="nav-secondary">
    {% if languages | length > 1 %}
        <div class="languages">
            {% for language in languages %}
                {% set class = language.active ? "" : "opacity-50" %}
                <a href="{{ language.url }}" class="{{ class }}">
                    <img class="lazyload" src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ language.country | flag_url }}" alt="{{ language.name }}" />
                </a>
            {% endfor %}
        </div>
    {% endif %}
    <ul class="nav-account" data-store="account-links">
        {% if not customer %}
            {% if 'mandatory' not in store.customer_accounts %}
            <li class="nav-accounts-item">{{ "Crear cuenta" | translate | a_tag(store.customer_register_url, '', 'nav-accounts-link') }}</li>
            {% endif %}
            <li class="nav-accounts-item">{{ "Iniciar sesión" | translate | a_tag(store.customer_login_url, '', 'nav-accounts-link') }}</li>
        {% else %}
            <li class="nav-accounts-item">{{ "Mi cuenta" | translate | a_tag(store.customer_home_url, '', 'nav-accounts-link') }}</li>
            <li class="nav-accounts-item">{{ "Cerrar sesión" | translate | a_tag(store.customer_logout_url, '', 'nav-accounts-link') }}</li>
        {% endif %}
    </ul>
</div>

Incluímos este tpl no snipplet header.tpl

navigation-nav-list.tpl

Este é o for que itera ou percorre todos os links dentro do Menu Principal de uma loja. Neste arquivo nós misturamos as duas coisas em um único for, para páginas e categorias.

{% for item in navigation %}
    {% if item.subitems %}
        <li class="item-with-subitems">
            <div class="js-nav-list-toggle-accordion">
                <a class="nav-list-link" href="{{ item.url }}">{{ item.name }}</a>
                <span class="js-toggle-page-accordion nav-list-arrow transition-soft">
                    {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
                </span>
            </div>
            <ul class="js-pages-accordion list-subitems nav-list-accordion" style="display:none;">
                {% snipplet "navigation/navigation-nav-list.tpl" with navigation = item.subitems %}
            </ul>
        </li>
    {% else %}
        <li>
            <a class="nav-list-link" href="{{ item.url }}">{{ item.name }}</a>
        </li>
    {% endif %}
{% endfor %}

Incluímos este tpl no snipplet navigation-panel.tpl e dentro de si mesmo navigation-nav-list.tpl

navigation-foot.tpl

Esse snipplet mostra os links de navegação do footer, escolhidos pelo administrador da loja na seção ‘Personalizar meu layout atual”.

<ul class="footer-menu m-0 p-0">
    {% for item in menus[settings.footer_menu] %}
        <li class="footer-menu-item my-4">
            <a class="footer-menu-link" href="{{ item.url }}" {% if item.url | is_external %}target="_blank"{% endif %}>{{ item.name }}</a>
        </li>
    {% endfor %}
</ul>

Incluímos este tpl no snipplet footer.tpl 

Cart

cart-panel.tpl

Dentro deste arquivo está o conteúdo do modal do carrinho incluindo o for que chama os itens do carrinho, as mensagens para quando o carrinho está vazio ou não há mais estoque de um produto e está incluso também o snipplet cart-totals.tpl

<div class="js-ajax-cart-list cart-row">
    {# Cart panel items #}
    {% if cart.items %}
      {% for item in cart.items %}
        {% include "snipplets/cart-item-ajax.tpl" %}
      {% endfor %}
    {% endif %}
</div>
<div class="js-empty-ajax-cart cart-row" {% if cart.items_count > 0 %}style="display:none;"{% endif %}>
     {# Cart panel empty #}
    <div class="alert alert-info">{{ "El carrito de compras está vacío." | translate }}</div>
</div>
<div id="error-ajax-stock" style="display: none;">
    <div class="alert alert-warning">
         {{ "¡Uy! No tenemos más stock de este producto para agregarlo al carrito. Si querés podés" | translate }}<a href="{{ store.products_url }}" class="btn-link ml-1">{{ "ver otros acá" | translate }}</a>
    </div>
</div>
<div class="cart-row">
    {% include "snipplets/cart-totals.tpl" %}
</div>

Incluímos este tpl no snipplet header.tpl 

cart-item-ajax.tpl

Este é o item de cada produto que é adicionado ao carrinho, não apenas usado para o carrinho em sua versão "pop-up", mas também na página Carrinho de Compras.

Embora o layout Base não exiba o carrinho de compras na sua versão "página" por padrão, ele tem o modelo cart.tpl pronto para ser utilizado.

Este item mostra:

  • Uma imagem do produto adicionado
  • Seu nome e variante
  • Seu preço
  • Um botão para removê-lo do carrinho
  • Controles para aumentar ou diminuir a quantidade

<div class="js-cart-item cart-item {% if item.product.is_non_shippable %}js-cart-item-non-shippable{% else %}js-cart-item-shippable{% endif %} {% if cart_page %}row align-items-md-center {% if loop.last %}mb-2{% else %}mb-5{% endif %} {% else %}form-row{% endif %}" data-item-id="{{ item.id }}" data-store="cart-item-{{ item.product.id }}">

  {% set show_free_shipping_label = item.product.free_shipping and not (cart.free_shipping.cart_has_free_shipping or cart.free_shipping.min_price_free_shipping.min_price) %}

  {# Cart item image #}
  <div class="{% if cart_page %}col-3 col-md-2{% else %}col-3 pr-3{% endif %}">
    <a href="{{ item.url }}">
      <img src="{{ item.featured_image | product_image_url('medium') }}" class="img-fluid" />
    </a>
  </div>
  <div class="{% if cart_page %}col-9 col-md pl-0 pl-md-3{% else %}col-9 d-flex align-items-center{% endif %}">

    {# Cart item name #}
    <div class="{% if cart_page %}row align-items-center{% else %}w-100{% endif %}">
      <h6 class="font-weight-normal {% if cart_page %}col-12 col-md-6 h4-md mb-2 mb-md-0{% else %}cart-item-name mb-0{% endif %}">
        <a href="{{ item.url }}">
          {{ item.short_name }}
        </a>
        <small>{{ item.short_variant_name }}</small>
        {% if show_free_shipping_label %}
          <div class="my-2">
            <span class="label label-secondary font-smallest">{{ "Envío gratis" | translate }}</span>
          </div>
        {% endif %}
      </h6>
      
      {% if cart_page %}
        {% set cart_quantity_class = 'float-md-none m-auto ' %}
      {% else %}
        {% set cart_quantity_class = 'float-left ' %}
      {% endif %}

      <div class="cart-item-quantity {% if cart_page %}col-7 col-md-3{% endif %}">
        {% embed "snipplets/forms/form-input.tpl" with{
          type_number: true, 
          input_value: item.quantity, 
          input_name: 'quantity[' ~ item.id ~ ']', 
          input_data_attr: 'item-id',
          input_data_val: item.id,
          input_group_custom_class: cart_quantity_class ~ 'form-quantity w-auto mb-2', 
          input_custom_class: 'js-cart-quantity-input cart-item-input form-control', 
          input_label: false, input_append_content: true} %}
            {% block input_prepend_content %}
            <div class="row m-0 justify-content-md-center {% if cart_page %}align-items-center{% endif %}">
              <span class="js-cart-quantity-btn cart-item-btn btn" onclick="LS.minusQuantity({{ item.id }}{% if not cart_page %}, true{% endif %})">
                {% include "snipplets/svg/minus.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
              </span>
            {% endblock input_prepend_content %}
            {% block input_append_content %}
              <span class="js-cart-input-spinner cart-item-spinner" style="display: none;">
                {% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-spin svg-icon-text"} %}
              </span>
              <span class="js-cart-quantity-btn cart-item-btn btn" onclick="LS.plusQuantity({{ item.id }}{% if not cart_page %}, true{% endif %})">
                {% include "snipplets/svg/plus.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
              </span>
            </div>
            {% endblock input_append_content %}
        {% endembed %}
      </div>

      {# Cart item subtotal #}
      <h6 class="js-cart-item-subtotal cart-item-subtotal {% if cart_page %}col-5 col-md-3 text-right text-md-center h4-md font-weight-bold{% endif %}" data-line-item-id="{{ item.id }}">{{ item.subtotal | money }}</h6>
    </div>
  </div>

  {# Cart item delete #}
  <div class="cart-item-delete {% if cart_page %}position-relative-md col-auto col-md-1{% else %}col-1{% endif %} text-right">
    <button type="button" class="btn h6 {% if cart_page %}h5-md{% endif %} m-0" onclick="LS.removeItem({{ item.id }}{% if not cart_page %}, true{% endif %})">
      {% include "snipplets/svg/trash-alt.tpl" with {svg_custom_class: "icon-inline icon-lg svg-icon-text"} %}
    </button>
  </div>
</div>

Incluimos o tpl no snipplet cart-panel.tpl e no template cart.tpl. Não é possível mudar seu nome e localização pelo backend da Nuvemshop.

cart-totals.tpl

Este snipplet inclui:

  • O subtotal do carrinho, que não inclui os custos de envio nem as promoções
  • Calculadora de envio
  • As lojas/locais físicos (não aplicáveis no Brasil)
  • A mensagem de promoções, por exemplo, 2x1
  • O total do carrinho que inclui o custo de envio e promoções
  • As parcelas com base no total (aplicam-se apenas no Brasil)
  • O botão para finalizar a compra
  • O link para continuar comprando

Também usamos a condição {% if cart_page%}, já que o snipplet é usado tanto para o carrinho em seu formato modal ou pop-up, quanto no formato "página".

{# IMPORTANT Do not remove this hidden subtotal, it is used by JS to calculate cart total #}
<div class="subtotal-price hidden" data-priceraw="{{ cart.total }}"></div>

{# Define contitions to show shipping calculator and store branches on cart #}

{% set show_calculator_on_cart = settings.shipping_calculator_cart_page and store.has_shipping %}
{% set show_cart_fulfillment = settings.shipping_calculator_cart_page and (store.has_shipping or store.branches) %}

{# Used to assign currency to total #}
<div id="store-curr" class="hidden">{{ cart.currency }}</div>

{% if not cart_page %}
  {# Cart popup subtotal #}
  <h5 class="js-visible-on-cart-filled {% if not cart_page %}row no-gutters{% else %}text-right{% endif %} mb-1 {% if cart_page %}text-center-xs{% endif %}" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>
    <span {% if not cart_page %}class="col"{% endif %}>
      {{ "Subtotal" | translate }}
      <small class="js-subtotal-shipping-wording" {% if not (cart.has_shippable_products or show_calculator_on_cart) %}style="display: none"{% endif %}>{{ " (sin envío)" | translate }}</small>
      :
    </span>
    <strong class="js-ajax-cart-total js-cart-subtotal {% if not cart_page %}col{% endif %} text-right" data-priceraw="{{ cart.subtotal }}">{{ cart.subtotal | money }}</strong>
  </h5>

  {# Cart popup promos #}
  <div class="js-total-promotions text-accent font-weight-bold">
    <span class="js-promo-title" style="display:none;">{{ "Promo" | translate }}</span>
    <span class="js-promo-in" style="display:none;">{{ "en" | translate }}</span>
    <span class="js-promo-all" style="display:none;">{{ "todos los productos" | translate }}</span>
    <span class="js-promo-buying" style="display:none;"> {{ "comprando" | translate }}</span>
    <span class="js-promo-units-or-more" style="display:none;"> {{ "o más" | translate }}</span>
    {% for promotion in cart.promotional_discount.promotions_applied %}
      {% if(promotion.scope_value_id) %}
        {% set id = promotion.scope_value_id %}
      {% else %}
        {% set id = 'all' %}
      {% endif %}
        <span class="js-total-promotions-detail-row row" id="{{ id }}">
          <span class="col">
            {% if promotion.discount_script_type == "NAtX%off" %}
              {{ promotion.selected_threshold.discount_decimal_percentage * 100 }}% OFF
            {% else %}
              {{ "Promo" | translate }} {{ promotion.discount_script_type }} 
            {% endif %}


            {{ "en" | translate }} {% if id == 'all' %}{{ "todos los productos" | translate }}{% else %}{{ promotion.scope_value_name }}{% endif %}


            {% if promotion.discount_script_type == "NAtX%off" %}
              <span>{{ "Comprando {1} o más" | translate(promotion.selected_threshold.quantity) }}</span>
            {% endif %}
            :
          </span>
          <span class="col text-right">-{{ promotion.total_discount_amount_short }}</span>
        </span>
    {% endfor %}
  </div>
{% endif %}
{% if cart_page %}
  <div class="divider {% if cart_page %}d-none d-md-block{% endif %}"></div>
  <div class="container p-0">
    <div class="row">
{% endif %}
    {% if cart_page %}
      <div class="col-12 col-md-5">
    {% endif %}
      {% if show_cart_fulfillment %}
        <div class="js-fulfillment-info js-allows-non-shippable" {% if not cart.has_shippable_products %}style="display: none"{% endif %}>
          <div class="js-visible-on-cart-filled divider {% if cart_page %}d-md-none{% endif %}" {% if cart.items_count == 0 %}style="display:none;"{% endif %}></div>

          <div class="js-visible-on-cart-filled js-has-new-shipping js-shipping-calculator-container container-fluid">

            {# Saved shipping not available #}

            <div class="js-shipping-method-unavailable alert alert-warning row" style="display: none;">
              <div>
                <strong>{{ 'El medio de envío que habías elegido ya no se encuentra disponible para este carrito. ' | translate }}</strong>
              </div>
              <div>
                {{ '¡No te preocupes! Podés elegir otro.' | translate}}
              </div>
            </div>

            {# Shipping calculator and branch link #}

            <div id="cart-shipping-container" class="row" {% if cart.items_count == 0 %} style="display: none;"{% endif %} data-shipping-url="{{ store.shipping_calculator_url }}">

              {# Used to save shipping #}

              <span id="cart-selected-shipping-method" data-code="{{ cart.shipping_data.code }}" class="hidden">{{ cart.shipping_data.name }}</span>

              {# Shipping Calculator #}

              {% if store.has_shipping %}
                {% include "snipplets/shipping/shipping-calculator.tpl" with {'product_detail': false} %}
              {% endif %}

              {# Store branches #}

              {% if store.branches %}

                {# Link for branches #}

                {% include "snipplets/shipping/branches.tpl" with {'product_detail': false} %}
              {% endif %}
            </div>
          </div>

          <div class="js-visible-on-cart-filled divider {% if cart_page %}d-md-none{% endif %} {% if not store.branches %} mt-0{% endif %}" {% if cart.items_count == 0 %}style="display:none;"{% endif %}></div>
        </div>
      {% endif %}
    {% if cart_page %}
      </div>
    {% endif %}
    {% if cart_page %}
      <div class="col-12 col-md-7" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>
        <div id="cart-sticky-summary" class="position-sticky-md container-fluid">
          <div class="row justify-content-md-end mt-4 mt-md-0">
            <div class="col-12 col-md-auto">
              {# Cart page subtotal #}
              <h5 class="js-visible-on-cart-filled row no-gutters justify-content-end justify-content-md-center mb-1" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>
                <span class="col col-md-auto">
                  {{ "Subtotal" | translate }}
                  {% if settings.shipping_calculator_cart_page %}
                    <small>{{ " (sin envío)" | translate }}</small>
                  {% endif %}
                  :
                </span>
                <strong class="js-cart-subtotal col col-md-auto text-right" data-priceraw="{{ cart.subtotal }}">{{ cart.subtotal | money }}</strong>
              </h5>

              {# Cart page promos #}
              <div class="js-total-promotions">
                <span class="js-promo-title" style="display:none;">{{ "Promo" | translate }}</span>
                <span class="js-promo-in" style="display:none;">{{ "en" | translate }}</span>
                <span class="js-promo-all" style="display:none;">{{ "todos los productos" | translate }}</span>
                <span class="js-promo-buying" style="display:none;"> {{ "comprando" | translate }}</span>
                <span class="js-promo-units-or-more" style="display:none;"> {{ "o más" | translate }}</span>
                {% for promotion in cart.promotional_discount.promotions_applied %}
                  {% if(promotion.scope_value_id) %}
                    {% set id = promotion.scope_value_id %}
                  {% else %}
                    {% set id = 'all' %}
                  {% endif %}
                    <span class="js-total-promotions-detail-row row" id="{{ id }}">
                      <span class="col">
                        {% if promotion.discount_script_type == "NAtX%off" %}
                          {{ promotion.selected_threshold.discount_decimal_percentage * 100 }}% OFF
                        {% else %}
                          {{ "Promo" | translate }} {{ promotion.discount_script_type }} 
                        {% endif %}

                        {{ "en" | translate }} {% if id == 'all' %}{{ "todos los productos" | translate }}{% else %}{{ promotion.scope_value_name }}{% endif %}

                        {% if promotion.discount_script_type == "NAtX%off" %}
                          <span>{{ "Comprando {1} o más" | translate(promotion.selected_threshold.quantity) }}</span>
                        {% endif %}
                        :
                      </span>
                      <span class="col text-right">-{{ promotion.total_discount_amount_short }}</span>
                    </span>
                {% endfor %}
              </div>
    {% endif %}

              {# Cart total #}

              <div class="js-cart-total-container js-visible-on-cart-filled mb-3" {% if cart.items_count == 0 %}style="display:none;"{% endif %} data-store="cart-total">
                <h2 class="row no-gutters text-primary mb-0 {% if cart_page %}justify-content-end justify-content-md-center{% endif %}">
                  <span class="col {% if cart_page %}col-md-auto{% endif %} mr-1">{{ "Total" | translate }}:</span>
                  <span class="js-cart-total {% if cart.free_shipping.cart_has_free_shipping %}js-free-shipping-achieved{% endif %} {% if cart.shipping_data.selected %}js-cart-saved-shipping{% endif %} col {% if cart_page %}col-md-auto{% endif %} text-right">{{ cart.total | money }}</span>
                </h2>

                {# IMPORTANT Do not remove this hidden total, it is used by JS to calculate cart total #}
                <div class='total-price hidden'>
                  {{ "Total" | translate }}: {{ cart.total | money }}
                </div>
                {% include "snipplets/payments/installments.tpl" with {'product': false} %}
              </div>

              <div class="js-visible-on-cart-filled {% if not cart_page %}container-fluid{% endif %}" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>

                {# No stock alert #}

                <div id="error-ajax-stock" class='alert alert-warning' role='alert' style="display:none;">
                   {{ "¡Uy! No tenemos más stock de este producto para agregarlo al carrito. Si querés podés" | translate }}<a href="{{ store.products_url }}" class="btn-link">{{ "ver otros acá" | translate }}</a>
                </div>

                {# Cart panel CTA #}
                
                {% set cart_total = (settings.cart_minimum_value * 100) %}

                {# Cart CTA Module for cart popup or cart page #}

                {% if cart_page %}
                  {% if cart.checkout_enabled %}
                    <input id="go-to-checkout" class="btn btn-primary btn-block mb-3" type="submit" name="go_to_checkout" value="{{ 'Iniciar Compra' | translate }}"/>
                  {% else %}

                    {# Cart minium alert #}

                    <div class="alert alert-warning mt-4">
                      {{ "El monto mínimo de compra es de {1} sin incluir el costo de envío" | t(cart_total | money) }}
                    </div>
                  {% endif %}
                {% else %}
                  <div class="js-ajax-cart-submit row mb-3" {{ not cart.checkout_enabled ? 'style="display:none"' }} id="ajax-cart-submit-div">
                    <input class="btn btn-primary btn-block" type="submit" name="go_to_checkout" value="{{ 'Iniciar Compra' | translate }}"/>
                  </div>

                  {# Cart minium alert #}

                  <div class="js-ajax-cart-minimum alert alert-warning mt-4" {{ cart.checkout_enabled ? 'style="display:none"' }} id="ajax-cart-minumum-div">
                    {{ "El monto mínimo de compra es de {1} sin incluir el costo de envío" | t(cart_total | money) }}
                  </div>
                  <input type="hidden" id="ajax-cart-minimum-value" value="{{ cart_total }}"/>
                {% endif %}

                {# Cart panel continue buying link #}

                {% if settings.continue_buying %}
                  <div class="row mb-2">
                    <div class="text-center w-100">
                      <a href="{% if cart_page %}{{ store.products_url }}{% else %}#{% endif %}" class="{% if not  cart_page %}js-modal-close js-fullscreen-modal-close{% endif %} btn btn-link">{{ 'Ver más productos' | translate }}</a>
                    </div>
                  </div>
                {% endif %}
              </div>
{% if cart_page %}
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
{% endif %}

Incluímos este tpl no snipplet cart-panel.tpl e o template cart.tpl 

Home

Todos os arquivos dentro da pasta home referem-se às funcionalidades da home page da loja. Elas são:

  • Banners (com imagem, texto e um botão)
  • Produtos em destaque
  • Feed do Instagram
  • Módulos com imagem e texto
  • Slider de imagens
  • Vídeo
  • Mensagem de boas vindas

home-banners.tpl

Como o nome diz, eles são banners dentro da página inicial (até 4) e, como os módulos de imagem e texto, eles mostram uma imagem, um título, um parágrafo e um botão (com um link).

<section class="section-banners-home" data-store="banner-home-categories">
    <div class="container{% if settings.banners_full %}-fluid p-0{% endif %}">
        <div class="row {% if settings.banners_full %}no-gutters{% endif %} align-items-center">
            {% set num_banners = 0 %}
            {% for banner in ['banner_01', 'banner_02', 'banner_03'] %}
                {% set banner_show = attribute(settings,"#{banner}_show") %}
                {% set banner_title = attribute(settings,"#{banner}_title") %}
                {% set banner_button_text = attribute(settings,"#{banner}_button") %}
                {% set has_banner =  banner_show and (banner_title or banner_description or "#{banner}.jpg" | has_custom_image) %}
                {% if has_banner %}
                    {% set num_banners = num_banners + 1 %}
                {% endif %}
            {% endfor %}

            {% for banner in ['banner_01', 'banner_02', 'banner_03'] %}
                {% set banner_show = attribute(settings,"#{banner}_show") %}
                {% set banner_title = attribute(settings,"#{banner}_title") %}
                {% set banner_description = attribute(settings,"#{banner}_description") %}
                {% set banner_button_text = attribute(settings,"#{banner}_button") %}
                {% set banner_url = attribute(settings,"#{banner}_url") %}
                {% set has_banner =  banner_show and (banner_title or banner_description or "#{banner}.jpg" | has_custom_image) %}
                {% set has_banner_text =  banner_title or banner_description or banner_button_text %}
                {% if has_banner %}
                    <div class="col-md">
                        <div class="textbanner">
                            {% if banner_url %}
                                <a class="textbanner-link" href="{{ banner_url }}"{% if banner_title %} title="{{ banner_title }}" aria-label="{{ banner_title }}"{% else %} title="{{ 'Banner de' | translate }} {{ store.name }}" aria-label="{{ 'Banner de' | translate }} {{ store.name }}"{% endif %}>
                            {% endif %}
                            <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %}">
                                <img class="textbanner-image-background lazyautosizes lazyload blur-up-big" src="{{ "#{banner}.jpg" | static_url | settings_image_url('tiny') }}" data-srcset="{{ "#{banner}.jpg" | static_url | settings_image_url('large') }} 480w, {{ "#{banner}.jpg" | static_url | settings_image_url('huge') }} 640w" data-sizes="auto" data-expand="-10" {% if banner_title %}alt="{{ banner_title }}"{% else %}alt="{{ 'Banner de' | translate }} {{ store.name }}"{% endif %} />
                            </div>
                            <div class="textbanner-text{% if textoverimage %} over-image{% endif %}">
                                {% if banner_title %}
                                    <div class="h1 textbanner-title">{{ banner_title }}</div>
                                {% endif %}
                                {% if banner_description %}
                                    <div class="textbanner-paragraph">{{ banner_description }}</div>
                                {% endif %}
                                {% if banner_url and banner_button_text %}
                                    <button class="btn btn-line btn-small">{{ banner_button_text }}</button>
                                {% endif %}
                            </div>
                            {% if banner_url %}
                                </a>
                            {% endif %}
                        </div>
                    </div>
                {% endif %}
            {% endfor %}
        </div>
    </div>
</section>

Incluimos o tpl no template home.tpl 

home-featured-products.tpl 

Neste tpl temos o slider que mostra os produtos relacionados na página de detalhes do produto.

{# /*============================================================================
  #Home featured grid
==============================================================================*/


#Properties

#Featured Slider

#}

{% if sections.primary.products %}
    <section class="section-featured-home" data-store="products-home-featured">
        <div class="container">
            <div class="row">
                {% if settings.featured_products_title %}
                    <div class="col-12 text-center">
                        <h3>{{ settings.featured_products_title }}</h3>
                    </div>
                {% endif %}
                <div class="col-12">
                    <div class="js-swiper-featured swiper-container">
                        <div class="swiper-wrapper">
                            {% for product in sections.primary.products %}
                                {% include 'snipplets/grid/item.tpl' with {'slide_item': true} %}
                            {% endfor %}


                        </div>
                        <div class="js-swiper-featured-pagination swiper-pagination"></div>
                        <div class="js-swiper-featured-prev swiper-button-prev d-none d-md-block">{% include "snipplets/svg/chevron-left.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
                        <div class="js-swiper-featured-next swiper-button-next d-none d-md-block">{% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-2x svg-icon-text"} %}</div>
                    </div>
                </div>
            </div>
        </div>
    </section>
    {% set section_name = 'primary' %}
{% endif %}

Incluímos este tpl no template home.tpl 

home-instafeed.tpl

Acá incluimos todo lo que tiene que ver con notificaciones dentro del Storefront, las cuales por ahora son dos: el mensaje cuando un producto es agregado al carrito, y el mensaje cuando el usuario finalizó su compra y puede hacer un seguimiento.

{% if settings.show_instafeed and store.instagram %}
    <section class="section-instafeed-home" data-store="instagram-feed">
        <div class="container">
            <div class="row">
                {% set instuser = store.instagram|split('/')|last %}
                <div class="col-12 text-center">
                    {% if store.instagram %}
                        <a target="_blank" href="{{ store.instagram }}" class="instafeed-title" aria-label="{{ 'Instagram de' | translate }} {{ store.name }}">
                            {% include "snipplets/svg/instagram.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-text"} %}
                            <h3 class="instafeed-user">{{ instuser }}</h3>
                        </a>
                    {% else %}
                        <div class="instafeed-title">
                            {% include "snipplets/svg/instagram.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-text"} %}
                            <h3 class="instafeed-user">{{ "Instagram" | translate }}</h3>
                        </div>
                    {% endif %}
                </div>
            </div>
        </div>
        <div id="instafeed" class="row no-gutters">  
        </div>
    </section>
{% endif %}

Incluímos este tpl no template home.tpl

home-modules.tpl

Usamos este tpl para exibir até 2 módulos que permitem exibir uma imagem (alinhada à esquerda ou à direita na área de trabalho), um título, um parágrafo e um botão (com um link).

<section class="section-home-modules">
    <div class="container{% if settings.modules_full %}-fluid p-0{% endif %}">
        {% set num_modules = 0 %}
        {% for module in ['module_01', 'module_02'] %}
            {% set module_show = attribute(settings,"#{module}_show") %}
            {% set module_title = attribute(settings,"#{module}_title") %}
            {% set module_button_text = attribute(settings,"#{module}_button") %}
            {% set has_module =  module_show and (module_title or module_description or "#{module}.jpg" | has_custom_image) %}
            {% if has_module %}
                {% set num_modules = num_modules + 1 %}
            {% endif %}
        {% endfor %}


        {% for module in ['module_01', 'module_02'] %}
            {% set module_show = attribute(settings,"#{module}_show") %}
            {% set module_align = attribute(settings,"#{module}_align") %}
            {% set module_title = attribute(settings,"#{module}_title") %}
            {% set module_description = attribute(settings,"#{module}_description") %}
            {% set module_button_text = attribute(settings,"#{module}_button") %}
            {% set module_url = attribute(settings,"#{module}_url") %}
            {% set has_module =  module_show and (module_title or module_description or "#{module}.jpg" | has_custom_image) %}
            {% set has_module_text =  module_title or module_description or module_button_text %}
            {% if has_module %}
                {% if module_url %}
                    <a class="module-with-text-link" href="{{ module_url }}"{% if module_title %} title="{{ module_title }}" aria-label="{{ module_title }}"{% else %} title="{{ 'Módulo de' | translate }} {{ store.name }}" aria-label="{{ 'Módulo de' | translate }} {{ store.name }}"{% endif %}>
                {% endif %}
                <div class="row {% if settings.modules_full %}no-gutters{% endif %} align-items-center">               
                    
                    <div class="col-md {% if module_align == 'right' %}order-md-2{% endif %}">
                        <div class="textbanner">
                            <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %}">
                                <img class="textbanner-image-background lazyautosizes lazyload fade-in" src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset='{{ "#{module}.jpg" | static_url | settings_image_url('large') }} 480w, {{ "#{module}.jpg" | static_url | settings_image_url('huge') }} 640w' data-sizes="auto" {% if module_title %}alt="{{ module_title }}"{% else %}alt="{{ 'Módulo de' | translate }} {{ store.name }}"{% endif %} data-expand="-10"/>
                            </div>
                        </div>
                    </div>
                    <div class="col-md">
                        <div class="textbanner-text{% if textoverimage %} over-image{% endif %}">
                            {% if module_title %}
                                <div class="h1 textbanner-title">{{ module_title }}</div>
                            {% endif %}
                            {% if module_description %}
                                <div class="textbanner-paragraph">{{ module_description }}</div>
                            {% endif %}
                            {% if module_url and module_button_text %}
                                <button class="btn btn-primary btn-small">{{ module_button_text }}</button>
                            {% endif %}
                        </div>
                    </div>
                {% if module_url %}
                    </a>
                {% endif %}
            {% endif %}
        {% endfor %}
    </div>
</section>

Incluímos este tpl no template home.tpl 

home-slider.tpl

Usamos esse snipplet para o Slider principal do Storefront, mostrado na página inicial.

<section class="js-home-slider-container section-slider {% if not settings.slider or settings.slider is empty %} hidden {% endif %}" data-store="slider-main">
    <div class="js-home-slider nube-slider-home swiper-container swiper-container-horizontal">
        <div class="swiper-wrapper">
            {% for slide in settings.slider %}
                <div class="swiper-slide slide-container">
                    {% if slide.link %}
                        <a href="{{ slide.link }}" aria-label="{{ 'Carrusel' | translate }} {{ loop.index }}">
                    {% endif %}
                        <div class="slider-slide">
                            <img {% if loop.first %}src="{{ slide.image | static_url | settings_image_url('1080p') }}" class="slider-image"{% else %}src="{{ slide.image | static_url | settings_image_url('tiny') }}" data-src="{{ slide.image | static_url | settings_image_url('1080p') }}" class="slider-image blur-up-big swiper-lazy" data-sizes="auto"{% endif %} alt="{{ 'Carrusel' | translate }} {{ loop.index }}"/>
                        </div>
                    {% if slide.link %}
                        </a>
                    {% endif %}
                </div>
            {% endfor %}
        </div>
        <div class="js-swiper-home-pagination swiper-pagination swiper-pagination-bullets swiper-pagination-white">
            {% if settings.slider > 1 and not params.preview %}
                {% for slide in settings.slider %}
                    <span class="swiper-pagination-bullet"></span>
                {% endfor %}
            {% endif %}
        </div>
        <div class="js-swiper-home-prev swiper-button-prev d-none d-md-block">{% include "snipplets/svg/chevron-left.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-lg svg-icon-invert"} %}</div>
        <div class="js-swiper-home-next swiper-button-next d-none d-md-block">{% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline icon-w-8 icon-lg svg-icon-invert"} %}</div>
    </div>
</section>

Incluímos este tpl no template home.tpl 

home-video.tpl

Como o nome diz, é um snipplet para a funcionalidade do vídeo exibido na página inicial, que está pronto para aceitar URLs do YouTube e do Vimeo.

{% if settings.video_embed %}
    <section class="section-video-home" data-store="video-home">
        <div class="container{% if settings.video_full %}-fluid p-0{% endif %}">
            <div class="row no-gutters">
                <div class="col">
                    {% include 'snipplets/video-item.tpl' %}
                </div>
            </div>
        </div>
    </section>
{% endif %}

Incluímos este tpl no template home.tpl

home-welcome-message.tpl

A través del home-welcome-message.tpl mostramos un mensaje de bienvenida compuesto por un título y un párrafo en la página inicial del Storefront.

{% if settings.welcome_message %}
    <section class="section-welcome-home">
        <div class="container">
            <div class="row">
                <div class="col-md-8 offset-md-2">
                    <h2 class="welcome-title">{{ settings.welcome_message }}</h2>
                    {% if settings.welcome_text %}
                        <p class="welcome-text">{{ settings.welcome_text }}</p>
                    {% endif %}
                </div>
            </div>
        </div>
    </section>
{% endif %}

Incluímos este tpl no template home.tpl

modal.tpl

Este snipplet representa todos os popups ou modos modais, neste caso nós o usamos para 5 partes:

  • Meios de pagamento
  • Navegação
  • Carrinho de compras
  • Filtros
  • Pesquisar

É um componente com parâmetros que permitem adicionar classes, IDs, definir como a animação modal será e de qual parte da tela ela aparece, entre outras coisas. No próprio arquivo há mais mais detalhes.

{# /*============================================================================
  #Modal
==============================================================================*/

#Properties
    // ID
    // Position - Top, Right, Bottom, Left
    // Transition - Slide and Fade
    // Width - Full and Box
    // modal_form_action - For modals that has a form

#Head
    // Block - modal_head
#Body
    // Block - modal_body
#Footer
    // Block - modal_footer
#}

{% set modal_overlay = modal_overlay | default(true) %}

<div id="{{ modal_id }}" class="js-modal {% if modal_mobile_full_screen %}js-fullscreen-modal{% endif %} modal modal-{{ modal_class }} modal-{{modal_position}} transition-{{modal_transition}} modal-{{modal_width}} transition-soft" style="display: none;">
    {% if modal_form_action %}
    <form action="{{ modal_form_action }}" method="post" class="{{ modal_form_class }}" {% if modal_form_hook %}data-store="{{ modal_form_hook }}"{% endif %}>
    {% endif %}
    <div class="js-modal-close {% if modal_mobile_full_screen %}js-fullscreen-modal-close{% endif %} modal-header">
        <span class="modal-close">
            {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
        </span>
        {% block modal_head %}{% endblock %}
    </div>
    <div class="modal-body">
        {% block modal_body %}{% endblock %}
    </div>
    {% if modal_footer %}
        <div class="modal-footer d-md-block">
            {% block modal_foot %}{% endblock %}
        </div>
    {% endif %}
    {% if modal_form_action %}
    </form>
    {% endif %}
</div>

Incluímos este tpl nos snipplets header.tpl, payments.tpl e category.tpl 

notification.tpl

Aqui incluímos tudo relacionado às notificações no Storefront, que, por enquanto são duas: a mensagem quando um produto é adicionado ao carrinho e a mensagem quando o usuário terminou a compra e um link para a página de rastreamento.

{# Order notification #}

{% if order_notification and status_page_url %}
    <div data-url="{{ status_page_url }}" class="js-notification notification notification-secondary" style="display:none;">
        <div class="container">
            <div class="row">
                <div class="col">
                    {{ "Seguí acá" | translate | a_tag(status_page_url, {class: 'btn btn-link'}) }}
                    <span>{{ "tu última compra" | translate }}</span>
                    <a class="js-notification-close ml-3" href="#">
                        {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-primary icon-lg"} %}
                    </a>
                </div>
            </div>
        </div>
    </div>
{% endif %}

{# Add to cart notification #}

{% if add_to_cart %}
    <div class="js-alert-added-to-cart notification-floating notification-hidden {% if add_to_cart_fixed %}notification-fixed{% endif %}" style="display: none;">
        <div class="notification notification-primary notification-with-arrow position-relative {% if not add_to_cart_mobile %}col-12 float-right{% endif %}">
            <div class="h6 text-center mb-3 mr-3">
                <strong>{{ '¡Ya agregamos tu producto al carrito!' | translate }}</strong>
            </div>
            <div class="js-cart-notification-close notification-close">
                {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-primary"} %}
            </div>
            <div class="js-cart-notification-item row">
                <div class="col-3 pr-0 notification-img">
                    <img src="" class="js-cart-notification-item-img img-fluid" />
                </div>
                <div class="col-9 text-left">
                    <div class="mb-1">
                        <span class="js-cart-notification-item-name"></span>
                        <span class="js-cart-notification-item-variant-container" style="display: none;">
                            (<span class="js-cart-notification-item-variant"></span>)
                        </span>
                    </div>
                    <div class="mb-1">
                        <span class="js-cart-notification-item-quantity"></span>
                        <span> x </span>
                        <span class="js-cart-notification-item-price"></span>
                    </div>
                </div>
            </div>
            <div class="row text-primary h5 font-weight-normal mt-2 mb-3">
                <span class="col-auto text-left">
                    <strong>{{ "Total" | translate }}</strong> 
                    (<span class="js-cart-widget-amount">
                        {{ "{1}" | translate(cart.items_count ) }} 
                    </span>
                    <span class="js-cart-counts-plural" style="display: none;">
                        {{ 'productos' | translate }}):
                    </span>
                    <span class="js-cart-counts-singular" style="display: none;">
                        {{ 'producto' | translate }}):
                    </span>
                </span>
                <strong class="js-cart-total col text-right">{{ cart.total | money }}</strong>
            </div>
            <a href="#" class="js-modal-open js-cart-notification-close js-fullscreen-modal-open btn btn-primary btn-medium w-100 d-inline-block" data-toggle="#modal-cart" data-modal-url="modal-fullscreen-cart">
                {{'Ver carrito' | translate }}
            </a>
        </div>
    </div>
{% endif %}

Incluímos este tpl no template header.tpl 

labels.tpl

Os labels são os mini banners indicando oferta, promoções, sem estoque e frete grátis que são mostrados no item da lista de produtos e nos detalhes do produto.

Nesse tpl usamos o condicional {% if product_detail%} para determinar se usamos ou não JavaScript no detalhe do produto quando as variantes são alteradas, por exemplo, quando uma delas não tem estoque ou tem um preço diferente que afeta 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 color %}
  {% set show_labels = settings.product_color_variants %}
{% else %}
  {% set show_labels = not product.has_stock or product.free_shipping or product.compare_at_price or product.promotional_offer %}
{% endif %}

{% if show_labels %}
  <div class="{% if product.video_url and product %}js-labels-group{% endif %} 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_detail or color %}
        <div class="js-stock-label label label-default" {% if product.has_stock %}style="display:none;"{% endif %}>{{ "Sin stock" | translate }}</div>
      {% endif %}
      {% if product.compare_at_price or product.promotional_offer %}
        <div class="{% if not product.promotional_offer and product %}js-offer-label{% endif %} label label-accent" {% if (not product.compare_at_price and not product.promotional_offer) or not product.display_price %}style="display:none;"{% endif %}>
          {% if product.promotional_offer.script.is_percentage_off %}
            {{ product.promotional_offer.parameters.percent * 100 }}% OFF
          {% elseif product.promotional_offer.script.is_discount_for_quantity %}
            <div>{{ product.promotional_offer.selected_threshold.discount_decimal_percentage * 100 }}% OFF</div>
            <div class="label-small p-right-quarter p-left-quarter">{{ "Comprando {1} o más" | translate(product.promotional_offer.selected_threshold.quantity) }}</div>
          {% elseif product.promotional_offer %}
            {% if store.country == 'BR' %}
              {{ "Leve {1} Pague {2}" | translate(product.promotional_offer.script.quantity_to_take, product.promotional_offer.script.quantity_to_pay) }}
            {% else %}
              {{ "Promo" | translate }} {{ product.promotional_offer.script.type }} 
            {% endif %}
          {% else %}
            <span {% if product_detail or color %}class="js-offer-percentage"{% endif %}>{{ price_discount_percentage |round }}</span>% OFF
          {% endif %}
        </div>
      {% endif %}
      {% if product.free_shipping %}
        <div class="label label-secondary">{{ "Envío gratis" | translate }}</div>
      {% endif %}
    {% endif %}
  </div>
{% endif %}

Incluímos este tpl no snipplet product-image.tpl e item.tpl 

logos-icons.tpl

São as bandeiras que mostram meios de pagamento e envio

{% if payments %}
    {% for payment in settings.payments %}
        <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ payment | payment_new_logo }}" class="icon-logo lazyload" alt="{{ payment }}">
    {% endfor %}
{% elseif shipping %}
    {% for shipping in settings.shipping %}
        <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ shipping | shipping_logo }}" class="icon-logo lazyload" alt="{{ shipping }}">
    {% endfor %}
{% endif %}

Incluímos este tpl no snipplet footer.tpl 

social-links.tpl

Ele contém todos os links e ícones de redes sociais que são mostrados no rodapé. Eles devem ser configurados no Administrador Nuvem na seção Minha conta/Redes Sociais.

Inclui:

  • Facebook
  • Google+
  • Twitter
  • Instagram
  • Pinterest

{% for sn in ['facebook', 'twitter', 'google_plus', 'pinterest', 'instagram'] %}
    {% set sn_url = attribute(store,sn) %}
    {% if sn_url %}
        <a class="social-icon" href="{{ sn_url }}" target="_blank" {% if sn == 'google_plus' %}rel="publisher"{% endif %} aria-label="{{ sn }} {{ store.name }}">
            {% if sn == "google_plus" %}
                {% include "snipplets/svg/google-plus.tpl" with {svg_custom_class: "icon-inline"} %}
            {% elseif sn == "facebook" %}
                {% include "snipplets/svg/facebook-f.tpl" with {svg_custom_class: "icon-inline"} %}
            {% elseif sn == "instagram" %}
                {% include "snipplets/svg/instagram.tpl" with {svg_custom_class: "icon-inline"} %}
            {% elseif sn == "pinterest" %}
                {% include "snipplets/svg/pinterest.tpl" with {svg_custom_class: "icon-inline"} %}
            {% else %}
                {% include "snipplets/svg/twitter.tpl" with {svg_custom_class: "icon-inline"} %}
            {% endif %}
        </a>
    {% endif %}
{% endfor %}

Incluímos este tpl no snipplet footer.tpl 

social-share.tpl

São os links para compartilhar um produto nas seguintes redes sociais:

  • Facebook
  • WhatsApp
  • Twitter
  • Pinterest

{# Mobile Sharing #}
<div class="social-share text-center">
    <h5 class="my-3">{{ "Compartir" | translate }}</h5>

    {# Whatsapp button #}
    <a class="social-share-button" data-network="whatsapp" target="_blank" href="whatsapp://send?text={{ product.social_url }}" title="{{ 'Compartir en WhatsApp' | translate }}" aria-label="{{ 'Compartir en WhatsApp' | translate }}">
         {% include "snipplets/svg/whatsapp.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
    </a>

    {# Facebook button #}
    <a class="social-share-button" data-network="facebook" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u={{ product.social_url }}" title="{{ 'Compartir en Facebook' | translate }}" aria-label="{{ 'Compartir en Facebook' | translate }}">
         {% include "snipplets/svg/facebook-f.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
    </a>

    {# Twitter button #}
    <a class="social-share-button" data-network="twitter" target="_blank" href="https://twitter.com/share?url={{ product.social_url }}" title="{{ 'Compartir en Twitter' | translate }}" aria-label="{{ 'Compartir en Twitter' | translate }}">
         {% include "snipplets/svg/twitter.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
    </a>
    
    {# Pinterest button #}
     <a class="js-pinterest-share social-share-button" data-network="pinterest" target="_blank" href="#" title="{{ 'Compartir en Pinterest' | translate }}" aria-label="{{ 'Compartir en Pinterest' | translate }}">
        {% include "snipplets/svg/pinterest.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
     </a>
     <div class="pinterest-hidden social-share-button" style="display: none;" data-network="pinterest">
        {{product.social_url | pin_it('https:' ~ product.featured_image | product_image_url('large'))}}
    </div>
</div>

Incluímos este tpl no snipplet product-form.tpl 

Placeholders

Placeholders são ícones vetorizados que são mostrados com uma animação de opacidade até que o slider de imagens ou as imagens que eles substituem estejam prontos para serem vistos. Depois que o slider ou a imagem são carregados, o placeholder desaparece.

O JavaScript que oculta e mostra espaços reservados está no arquivo store.js.tpl.

home-slider-placeholder.tpl

Ele é exibido até que o slider principal da página inicial seja carregado.

{# Mobile home slider placeholder: to be hidden after content loaded #}

{% if settings.slider and settings.slider is not empty %}
    <div class="js-home-slider-placeholder placeholder-full-height placeholder-container d-md-none overflow-hidden">
        <div class="container home-placeholder-icons">
            <div class="row">
                <div class="col-10 offset-1 mb-3 placeholder-line-medium placeholder-color">
                </div>
                <div class="col-8 offset-2 mb-3 placeholder-line-medium placeholder-color">
                </div>
                <div class="col-6 offset-3 mb-3 placeholder-line-medium placeholder-color">
                </div>
            </div>
        </div>
        <div class="placeholder-shine">
        </div>
    </div>
    <div class="js-slider-desktop-placeholder slider-desktop-placeholder">
    </div>
{% endif %}

Incluimos este tpl en el snipplet home-slider.tpl

product-detail-image-placeholder.tpl

Ele é exibido até que o slider do detalhe do produto seja carregado.

{# Mobile product detail placeholder: to be hidden after content loaded #}

{# Define sizes of mobile img placeholder based on the tallest element #}

{% set max_product_height = product.featured_image.dimensions['height'] %}
{% set max_product_width = product.featured_image.dimensions['width'] %}

{% if product.images_count > 1 %}
    {% for image in product.images %}
        {% set max_product_height = max(image.dimensions['height'], max_product_height) %}
        {% if image.dimensions['height'] == max_product_height %}
            {% set max_product_width = max(image.dimensions['width'], max_product_width) %}
        {% endif %}
    {% endfor %}
{% endif %}

{% set has_image_sizes = max_product_width > 0 %}

<div class="js-product-slider-placeholder d-md-none product-placeholder-container placeholder-container {% if product.images_count == 1 %}hidden-when-content-ready{% endif %}">
    <div class="p-relative overflow-none" {% if has_image_sizes %}style="padding-bottom: {{ max_product_height / max_product_width * 100}}%;"{% endif %}>
        <div class="product-placeholder img-absolute">
        </div>
    </div>
    <div class="placeholder-icon">
        {% include "snipplets/svg/shopping-bag.tpl" with {svg_custom_class: "icon-inline icon-w-14 icon-8x svg-icon-text"} %}
    </div>
    <div class="placeholder-shine">
    </div>
</div>

Incluímos este tpl no snipplet product-image.tpl 

page-header.tpl

Representa todos os títulos de todas as páginas do layout. No interior inclui o snipplet breadcrumbs.

{# /*============================================================================
  #Page header
==============================================================================*/

#Properties

#Title

#Breadcrumbs 

#}

<section class="page-header {% if template == 'product' %}mt-md-3{% else %}mt-3{% endif %}" {% if template != 'product' %}data-store="page-title"{% endif %}>
    {% if template != 'product' %}
    <div class="container">
        <div class="row">
    {% endif %}
            <div class="{% if template != 'product' %}col text-center{% endif %} {% if template == 'product' %}text-center text-md-left{% endif %} {% if template == 'category' %}col-lg-6 offset-lg-3{% endif %}">
                {% include 'snipplets/breadcrumbs.tpl' %}
                <h1 {% if template == 'product' %}class="js-product-name" data-store="product-name-{{ product.id }}"{% endif %} >{% block page_header_text %}{% endblock %}</h1>
                {% if template == 'category' and category.description %}
                    <p class="page-header-text font-md-normal">{{ category.description }}</p>
                    <div class="divider col-2 offset-5 background-primary"></div>
                {% endif %}
            </div>
    {% if template != 'product' %}
        </div>
    </div>
    {% endif %}
</section>

Incluímos este tpl nos templates 404.tpl, address.tpl, addresses.tpl, info.tpl, login.tpl, newpass.tlp, order.tpl, orders.tpl, register.tpl, reset.tpl, cart.tpl, category.tpl, contact.tpl, page.tpl y search.tpl. Também no snipplet product-form.tpl 

breadcrumbs.tpl

São os breadcrumbs de uma página incluídos no snipplet product-header.tpl, mas funcionam se usados separadamente.

{# /*============================================================================
  #Page breadcrmubs
==============================================================================*/
#Properties
#Breadcrumb
    //breadcrumbs_custom_class for custom CSS classes
#}

{% if breadcrumbs %}
    <div class="breadcrumbs {{ breadcrumbs_custom_class }}" itemprop="breadcrumb" itemscope itemtype="http://www.schema.org/WebPage" itemid="body">
        <a class="crumb" href="{{ store.url }}" title="{{ store.name }}">{{ "Inicio" | translate }}</a>
        <span class="divider">></span>
        {% if template == 'page' %}
            <span class="crumb active">{{ page.name }}</span>
        {% elseif template == 'cart' %}
            <span class="crumb active">{{ "Carrito de compras" | translate }}</span>
        {% elseif template == 'search' %}
            <span class="crumb active">{{ "Resultados de búsqueda" | translate }}</span>
        {% elseif template == 'account.order' %}
             <span class="crumb active">{{ 'Orden {1}' | translate(order.number) }}</span>
        {% else %}
            {% for crumb in breadcrumbs %}
                {% if crumb.last %}
                    <span class="crumb active">{{ crumb.name }}</span>
                {% else %}
                    <a class="crumb" href="{{ crumb.url }}" title="{{ crumb.name }}">{{ crumb.name }}</a>
                    <span class="divider">></span>
                {% endif %}
            {% endfor %}
        {% endif %}
    </div>
{% endif %}

Incluímos este tpl no snipplet page-header.tpl 

whatsapp-chat.tpl

Como o nome indica, usamos este snipplet para exibir um botão do WhatsApp que permite ao usuário conversar com o administrador da loja. O que ele faz é abrir o WhatsApp na web se o usuário estiver navegando de um computador e o aplicativo se for do celular.

Para que este botão seja exibido é necessário ativar a funcionalidade do Administrador Nuvem na seção Configurações/WhatsApp.

{% if store.whatsapp %}
    <a href="{{ store.whatsapp }}" target="_blank" class="btn-whatsapp" aria-label="{{ 'Comunicate por WhatsApp' | translate }}">
        {% include "snipplets/svg/whatsapp.tpl" with {svg_custom_class: "icon-inline icon-2x"} %}
    </a>
{% endif %}

Incluímos este tpl no snipplet layout.tpl 

contact-links.tpl

Estes são os links de contato, configurados a partir do Administrador Nuvem na seção Personalizar/Informações de Contato.

Eles são exibidos no rodapé e na página de contato, exibindo informações sobre:

  • Telefone ou WhatsApp
  • Email
  • Endereço
  • URL de um blog

{# /*============================================================================
  #Contact links
==============================================================================*/#}

<ul class="contact-info text-center{% if columns %} row{% endif %}">
{% if store.whatsapp %}
    <li class="contact-item{% if columns %} col-6 col-md{% endif %}">
        {% include "snipplets/svg/whatsapp.tpl" with {svg_custom_class: "icon-inline icon-lg icon-w mx-2 svg-icon-text"} %}
        <a href="{{ store.whatsapp }}" class="contact-link">{{ store.whatsapp |trim('https://wa.me/') }}</a>
    </li>
{% elseif store.phone %}
    <li class="contact-item{% if columns %} col-6 col-md{% endif %}">
        {% include "snipplets/svg/phone.tpl" with {svg_custom_class: "icon-inline icon-lg icon-w mx-2 svg-icon-text"} %}
        <a href="tel:{{ store.phone }}" class="contact-link">{{ store.phone }}</a>
    </li>
{% endif %}
{% if store.email %}
    <li class="contact-item{% if columns %} col-6 col-md{% endif %}">
        {% include "snipplets/svg/envelope.tpl" with {svg_custom_class: "icon-inline icon-lg icon-w mx-2 svg-icon-text"} %}
        <a href="mailto:{{ store.email }}" class="contact-link">{{ store.email }}</a>
    </li>
{% endif %}
{% if store.address %}
    <li class="contact-item{% if columns %} col-6 col-md{% endif %}">
        {% include "snipplets/svg/map-marker-alt.tpl" with {svg_custom_class: "icon-inline icon-lg icon-w mx-2 svg-icon-text"} %}
        {{ store.address }}
    </li>
{% endif %}
{% if store.blog %}
    <li class="contact-item{% if columns %} col-6 col-md{% endif %}">
        {% include "snipplets/svg/comments.tpl" with {svg_custom_class: "icon-inline icon-lg icon-w mx-2 svg-icon-text"} %}
        <a target="_blank" href="{{ store.blog }}" class="contact-link">{{ "Visita nuestro Blog!" | translate }}</a>
    </li>
{% endif %}
</ul>

Incluímos este tpl no snipplet footer.tpl e no template contact.tpl

logo-icons.tpl

Inclui os logotipos de meios de pagamento e meios de entrega exibidos dentro do rodapé.

{% if payments %}
    {% for payment in settings.payments %}
        <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ payment | payment_new_logo }}" class="icon-logo lazyload">
    {% endfor %}
{% elseif shipping %}
    {% for shipping in settings.shipping %}
        <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="{{ shipping | shipping_logo }}" class="icon-logo lazyload">
    {% endfor %}
{% endif %}

Incluímos este tpl no snipplet footer.tpl 

facebook-login.tpl

Inclua o botão para entrar ou criar uma conta usando o Facebook.

{% if store_fb_app_id %}

    <a class="btn btn-primary btn-facebook d-block mb-4" onclick="loginFacebook();" >
        {% include "snipplets/svg/facebook.tpl" with {svg_custom_class: "icon-inline icon-2x mr-1 svg-fb-icon align-middle"} %}
        <span class="align-middle">{{ 'Facebook login' | translate }}</span>
    </a>
    {% if result.facebook and result.invalid %}
        <div class="alert alert-danger">{{ 'Hubo un problema con el login de Facebook.' | translate }}</div>
    {% endif %}

{% endif %}

Incluímos este tpl nos templates login.tpl y register.tpl 

card.tpl

É um componente que consiste em um cartão, com head, body e footer; semelhante aos “panels” de Bootstrap.

{# /*============================================================================
  #Card
==============================================================================*/
#Head
    // Block - card_head
#Body
    // Block - card_body
#Footer
    // Block - card_footer
#}


<div class="card">
    <div class="card-header">
        {% block card_head %}{% endblock %}
    </div>
    <div class="card-body">
        {% block card_body %}{% endblock %}
    </div>
    {% if card_footer %}
        <div class="card-footer">
            {% block card_foot %}{% endblock %}
        </div>
    {% endif %}
</div>

Incluímos este tpl no template orders.tpl 

newsletter.tpl

É o formulário de newsletter que usamos no footer do theme.

Inclui um único campo de email, bem como a possibilidade de adicionar um título e um texto personalizado.

{% set newsletter_contact_error = contact.type == 'newsletter' and not contact.success %}

<div class="row justify-content-md-center">
    <div class="col-md-8 text-center">
        <div class="js-newsletter newsletter section-footer">
            {% if settings.news_title %}
                <h3>{{ settings.news_title }}</h3>
            {% endif %}
            {% if settings.news_text %}
                <p>{{ settings.news_text }}</p>
            {% endif %}
        
            {% if contact and contact.type == 'newsletter' %}
                {% if contact.success %}
                    <div class="alert alert-success">{{ "¡Gracias por suscribirte! A partir de ahora vas a recibir nuestras novedades en tu email" | translate }}</div>
                {% else %}
                    <div class="alert alert-danger">{{ "Necesitamos tu email para enviarte nuestras novedades." | translate }}</div>
                {% endif %}
            {% endif %}

            <form method="post" action="/winnie-pooh" onsubmit="$(this).attr('action', '');">
                <div class="input-append">
                  
                    {% embed "snipplets/forms/form-input.tpl" with{input_for: 'email', type_email: true, input_name: 'email', input_id: 'email', input_placeholder: 'Email' | translate, input_aria_label: 'Email' | translate } %}
                    {% endembed %}

                <div class="winnie-pooh" style="display: none;">
                    <label for="winnie-pooh-newsletter">{{ "No completar este campo" | translate }}</label>
                    <input id="winnie-pooh-newsletter" type="text" name="winnie-pooh"/>
                </div>
                <input type="hidden" name="name" value="{{ "Sin nombre" | translate }}" />
                <input type="hidden" name="message" value="{{ "Pedido de inscripción a newsletter" | translate }}" />
                <input type="hidden" name="type" value="newsletter" />
                <input type="submit" name="contact" class="btn newsletter-btn" value='{{ "Enviar" | translate }}'>    
                </div>
            </form>
        </div>
    </div>
</div>

Incluímos este tpl no snipplet footer.tpl 

Banners services

Os tpls dentro desta pasta mostram o código dos banners que mostram informações de:

  • Pagamentos
  • Envíos
  • Segurança
  • Trocas e Devoluções
  • Promoções
  • Pagamento em dinheiro
  • Whatsapp

banner-services.tpl

Es el archivo que incluye el for para cada item dentro de estos banners.

{% macro for_each_banner_include(template) %}
    {% set num_banners_services = 0 %}
    {% set available_banners = []%}
    {% for banner in ['banner_services_01', 'banner_services_02', 'banner_services_03'] %}
        {% set banner_services_icon = attribute(settings,"#{banner}_icon") %}
        {% set banner_services_title = attribute(settings,"#{banner}_title") %}
        {% set banner_services_description = attribute(settings,"#{banner}_description") %}
        {% set banner_services_url = attribute(settings,"#{banner}_url") %}
        {% set has_banner_services =  banner_services_title or banner_services_description %}
        {% if has_banner_services %}
            {% set num_banners_services = num_banners_services + 1 %}
            {% set available_banners = available_banners | merge([banner]) %}
        {% endif %}
    {% endfor %}
    {% for banner in available_banners %}
        {% set banner_services_title = attribute(settings,"#{banner}_title") %}
        {% set banner_services_icon = attribute(settings,"#{banner}_icon") %}
        {% set banner_services_description = attribute(settings,"#{banner}_description") %}
        {% set banner_services_url = attribute(settings,"#{banner}_url") %}
        {% include template %}
    {% endfor %}
{% endmacro %}
{% import _self as banner_services %}
{% if settings.banner_services %}
    <section class="section-informative-banners" data-store="banner-services">
        <div class="container">
            <div class="row">
                <div class="js-informative-banners swiper-container">
                    <div class="swiper-wrapper">
                        {{ banner_services.for_each_banner_include('snipplets/banner-services/banner-services-item.tpl') }}
                    </div>
                    <div class="js-informative-banners-pagination service-pagination swiper-pagination swiper-pagination-black"></div>
                </div>
            </div>
        </div>
    </section>
{% endif %}

Incluímos este tpl no template home.tpl 

banner-services-item.tpl

Este tpl é para cada item dentro do grupo de banners informativos.

<div class="service-item-container col-md swiper-slide p-0 px-md-3">
    <div class="service-item row justify-content-md-center text-md-left">
        
        <div class="col-md-auto">
            {% if banner_services_icon == 'shipping' %}
                {% include "snipplets/svg/truck.tpl" with {svg_custom_class: "icon-inline icon-w-20 icon-2x service-icon"} %}
            {% elseif banner_services_icon == 'card' %}
                {% include "snipplets/svg/credit-card-blank.tpl" with {svg_custom_class: "icon-inline icon-w-18 icon-2x service-icon"} %}
            {% elseif banner_services_icon == 'security' %}
                {% include "snipplets/svg/lock.tpl" with {svg_custom_class: "icon-inline icon-w-14 icon-2x service-icon"} %}
            {% elseif banner_services_icon == 'returns' %}
                {% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-w-16 icon-2x service-icon"} %}
            {% elseif banner_services_icon == 'whatsapp' %}
                {% include "snipplets/svg/whatsapp.tpl" with {svg_custom_class: "icon-inline icon-w-16 icon-2x service-icon service-icon-big"} %}
            {% elseif banner_services_icon == 'promotions' %}
                {% include "snipplets/svg/tag.tpl" with {svg_custom_class: "icon-inline icon-w-16 icon-2x service-icon"} %}
            {% elseif banner_services_icon == 'cash' %}
                {% include "snipplets/svg/dollar-sign.tpl" with {svg_custom_class: "icon-inline icon-w-9 icon-2x service-icon"} %}
            {% endif %}
        </div>
        <div class="col">
            {% if banner_services_url %}
                <a href="{{ banner_services_url }}">
            {% endif %}
            <h3 class="service-title">{{ banner_services_title }}</h3>
            <p>{{ banner_services_description }}</p>
            {% if banner_services_url %}
                </a>
            {% endif %}
        </div>
    </div>
</div>

Incluímos este tpl no snipplet banner-services.tpl 

video-item.tpl

Este tpl tem o componente de vídeo aplicado tanto na página dei inicio quanto aos produtos.

{% if product_modal %}

    {# Product video modal wrapper #}

    <div id="product-video-modal" class="js-product-video-modal product-video" style="display: none;">
{% endif %}
        <div class="js-video {% if product_video %}js-video-product{% endif %} embed-responsive embed-responsive-16by9 visible-when-content-ready">

            {% if product_modal_trigger %}

                {# Open modal in mobile with product video inside #}

                <a href="#product-video-modal" data-fancybox="product-gallery" class="js-play-button video-player d-block d-md-none">
                    <div class="video-player-icon">{% include "snipplets/svg/play-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-invert"} %}</div>
                </a>
            {% endif %}
            <a href="#" class="js-play-button video-player {% if product_modal_trigger %}d-none d-md-block{% endif %}">
                <div class="video-player-icon">
                    {% include "snipplets/svg/play-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-invert"} %}
                </div>
            </a>
            <div class="js-video-image">
                <img src="{{ 'images/empty-placeholder.png' | static_url }}" data-src="" class="lazyload video-image fade-in" alt="{{ 'Video de' | translate }} {% if template != 'product' %}{{ product.name }}{% else %}{{ store.name }}{% endif %}" style="display: none;">
                <div class="placeholder-fade">
                </div>
            </div>
        </div>
            
        {# Empty iframe component: will be filled with JS on play button click #}

        <div class="js-video-iframe embed-responsive embed-responsive-16by9" style="display: none;" data-video-color="{{ settings.primary_color | trim('#') }}">
        </div>
{% if product_modal %}
    </div>
{% endif %}

Incluímos este tpl nos snipplets home-video.tpl  y product-video.tpl