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
  • sort-by.tpl
  • item.tpl

filters.tpl

Neste snipplet, você encontra tudo relacionado aos filtros de 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">
    {% if filter_colors %}
        <div class="mb-4">
            <h6 class="mb-2">{{ 'Color' | translate }}</h6>
            {% for name,color in insta_colors %}
                <button type="button" class="btn btn-secondary btn-circle mr-2 mb-2" style="background-color: {{ color[name] }};" title="{{ name }}" onclick="LS.urlAddParam('{{ color_name|replace("'","%27") }}', '{{ name|replace("'","%27") }}');">
                </button>
            {% endfor %}
        </div>
    {% endif %}
    {% if filter_more_colors %}
        <div class="mb-4">
            <h6 class="mb-2">
                {% if filter_colors %}
                    {{ 'Más colores' | translate }}
                {% else %}
                    {{ 'Color' | translate }}
                {% endif %}
            </h6>
            {% for color in other_colors %}
                <button type="button" class="btn btn-secondary mr-2 mb-2" onclick="LS.urlAddParam('{{ color_name|replace("'","%27") }}', '{{ color|replace("'","%27") }}');">{{ color }}
                </button>
            {% endfor %}
        </div>
    {% endif %}
    {% if filter_sizes %}
        <div class="mb-4">
            <h6 class="mb-2">{{ 'Talle' | translate }}</h6>
            {% for size in size_properties_values %}
                <button type="button" class="btn btn-secondary mr-2 mb-2" onclick="LS.urlAddParam('{{ size_name|replace("'","%27") }}', '{{ size|replace("'","%27") }}');">{{ size }}
                </button>
            {% endfor %}
        </div>
    {% endif %}


    {% for variants_property in variants_properties %}
        {% if filter_other %}
            <div class="mb-4">
                <h6 class="mb-2">{{ variants_property }}</h6>
                {% for value in variants_properties_values[variants_property] %}
                    <button type="button" class="btn btn-secondary mr-2 mb-2" onclick="LS.urlAddParam('{{ variants_property|replace("'","%27") }}', '{{ value|replace("'","%27") }}');">{{value}}
                    </button>
                {% endfor %}
            </div>
        {% endif %}
    {% endfor %}
</div>

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

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'} %}
    {% 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 %}

<div class="{% if slide_item %}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 %}">
    {% set product_url_with_selected_variant = has_filters ?  ( product.url | add_param('variant', product.selected_or_first_available_variant.id)) : product.url  %}
    <div class="item-image mb-2">
        <div style="padding-bottom: {{ product.featured_image.dimensions['height'] / product.featured_image.dimensions['width'] * 100}}%;" class="p-relative">
            <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}">
                <img alt="{{ product.featured_image.alt }}" data-sizes="auto" src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset="{{ product.featured_image | product_image_url('small')}} 240w, {{ product.featured_image | product_image_url('medium')}} 320w, {{ product.featured_image | product_image_url('large')}} 480w" class="lazyautosizes lazyload img-absolute img-absolute-centered" /> 


                {# Low quality img until final img is lazyloaded #}
                <img alt="{{ product.featured_image.alt }}" src="{{ product.featured_image | product_image_url('tiny')}}" class="img-absolute img-absolute-centered blur-up">
            </a>
            {% include 'snipplets/labels.tpl' %}
        </div>
    </div>
    <div class="item-description">
        <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}" class="item-link">
            <div itemprop="name" class="item-name mb-1">{{ product.name }}</div>
            <meta itemprop="url" content="{{ product.url }}" />
            {% if product.display_price %}
                <div class="item-price-container mb-1" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
                    <meta itemprop="priceCurrency" content="{{ product.currency }}" />
                    {% if product.compare_at_price %}
                        <span class="price-compare">
                            {{ product.compare_at_price | money }}
                        </span>
                    {% endif %}
                    <span class="item-price" itemprop="price" content="{{ product.price / 100 }}">
                        {{ product.price | money }}
                    </span>
                </div>
            {% endif %}
        </a>
    </div>
    {% include 'snipplets/payments/installments.tpl' %}
</div>

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
#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 %}/>
    {% 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
#}


<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_name %}name="{{ select_name }}"{% 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 }}" />
</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') }}

facebook-og.tpl

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

 {{ store.name | og('site_name') }}
{% if template == 'home' and store.logo %}
    {{ ('http:' ~ store.logo) | og('image') }}
    {{ ('https:' ~ store.logo) | og('image:secure_url') }}
{% 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/pontos físicos (pickup) somente em lojas que não são do Brasil. 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.

Se você quiser mostrar as premissas no Brasil, você irá deletar o condicional store.country! = 'BR' onde este snipplet está incluído e você também terá que aplicar outra alteração explicada no snipplet shipping_options.tpl
<div class="js-toggle-branches w-100">
    <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 class="mb-1"> 
                {% if store.branches|length > 1 %}
                    {{ 'Retirá gratis en nuestros locales' | translate }}
                {% else %}
                    {{ 'Retirá gratis en nuestro local' | translate }}
                {% endif %}
            </div>
            <div class="btn-link float-left">
                {% if product_detail %}
                    <span class="js-see-branches">
                        {% if store.branches|length > 1 %}
                            {{ 'Ver locales' | translate }}
                        {% else %}
                            {{ 'Ver local' | translate }}
                        {% endif %}
                    </span>
                {% else %}
                    <span>
                        {{ 'Elegir local' | translate }}
                    </span>
                {% endif %}
                {% 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;">
                    {% if product_detail %}
                        {% if store.branches|length > 1 %}
                            {{ 'Ocultar locales' | translate }}
                        {% else %}
                            {{ 'Ocultar local' | translate }}
                        {% endif %}
                    {% endif %}
                    {% include "snipplets/svg/chevron-up.tpl" with {svg_custom_class: "icon-inline ml-1"} %}
                </span>
            </div>
        </div>
    </span>
</div>


{# Store branches #}


{% if not product_detail %}
    
    <ul class="js-store-branches-container list-unstyled radio-button-container mt-3" style="display: none;">


        {# Selectable branches #}


        {% for branch in store.branches %}
            <li class="radio-button-item">
                <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="shipping-option row-fluid radio-button-content">
                       <span class="radio-button-icons">
                            <span class="radio-button-icon unchecked"></span>
                            <span class="radio-button-icon checked"></span>
                            <span class="radio-button-icon checked checked-invert"></span>
                        </span>
                        <span class="radio-button-label">
                            <h6 class="text-primary mb-1 d-inline-block">{{ 'Gratis' | translate }}</h6>
                            <span class="radio-button-text">
                                {{ branch.name }} - {{ branch.extra }}
                            </span>
                        </span>
                    </span>
                </label>
            </li>
        {% endfor %}
    </ul>
{% else %}
    <ul class="js-store-branches-container list-unstyled list mt-3" style="display: none;">
        {% for branch in store.branches %}
            <li class="list-item">
                <span class="list-item-content">
                    <h6 class="text-primary mb-1">{{ 'Gratis' | translate }}</h6>
                    <div>{{ branch.name }} - {{ branch.extra }}</div>
                </span>
            </li>
        {% endfor %}
    </ul>
{% endif %}

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.

{% if shipping_calculator_show %}
    <div class="{% if product_detail %}product-shipping-calculator{% endif %} {% if store.branches and store.country != 'BR' %}mb-4{% else %}mb-2{% endif %}">
        <div class="js-shipping-calculator-form">

            {# 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: "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 %}
                    <span class="col-1">
                        {% include "snipplets/svg/truck.tpl" with {svg_custom_class: "icon-inline icon-w-18 icon-lg svg-icon-text"} %}
                     </span>
                {% endblock input_prepend_content %}
                {% block input_form_alert %}
                <div class="col-12">
                    <div class="js-ship-calculator-error invalid-zipcode alert alert-danger" style="display: none;">{{ "No encontramos este código postal. ¿Está bien escrito?" | translate }}</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">    
                        <span class="js-calculate-shipping-wording">{{ "Calcular envío" | translate }}</span>
                        <span class="js-calculating-shipping-wording" style="display: none;">{{ "Calculando" | translate }}</span>
                        <span class="loading" style="display: none;">
                            {% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline svg-icon-text icon-spin"} %}
                        </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 class="js-shipping-calculator-response mb-3 float-left w-100 {% if product_detail %}list{% endif %}" style="display: none;"></div>
    </div>
{% 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).

Além disso, separamos entre envios principais e secundários quando a loja tem métodos de envio não personalizados semelhantes, por exemplo: Correios SEDEX, Correios PAC e Envío Fácil (com Correios).

Nesse caso, priorizamos o melhor dos dois para não confundir o usuário, e o outro envio está oculto sob um link "Ver mais opções".

Chamamos de "Smart shipping" essa funcionalidade de filtragem de opção.

{% if options %}
    {% if store.has_smart_dates and show_time %}
        <div class="radio-group-label mb-3">{{"El tiempo de entrega no considera feriados." | translate}}</div>
    {% endif %}
    <ul class="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 #}

        {% set has_options_to_hide = false %}


        {% for option in options_to_hide %}
            {% if options_to_hide|length >= 1 %}
                {% set has_options_to_hide = true %}
            {% endif %}
        {% endfor %}

        {% for option in options_to_show if store.country == 'BR' or option.img_code != "branch" %}
            {% include "snipplets/shipping/shipping-calculator-item.tpl" with {'featured_option': true} %}
        {% endfor %}

        {% if has_options_to_hide %}
            <div class="js-show-more-shipping-options d-inline-block w-100 mt-3 text-center">
                <a href="#" class="btn-link">
                    <span class="js-shipping-see-more">
                        {{ 'Ver más opciones' | translate }}
                        {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "icon-inline ml-1"} %}
                    </span>
                    <span class="js-shipping-see-less" style="display: none;">{{ 'Ver menos opciones' | translate }}
                        {% include "snipplets/svg/chevron-up.tpl" with {svg_custom_class: "icon-inline ml-1"} %}
                    </span>
                </a>
            </div>
            <div class="js-other-shipping-option w-100 mt-3" style="display: none;">
                {% for option in options_to_hide if store.country == 'BR' or option.img_code != "branch" %}
                    {% include "snipplets/shipping/shipping-calculator-item.tpl" %}
                {% endfor %}
                </div>
        {% endif %}
    </ul>

    <div class="js-product-shipping-label font-small mt-3 pull-left" style="display: none;">
        <span class="js-shipping-filled-cart js-visible-on-cart-filled" {% if cart.items_count == 0 %}style="display:none;"{% endif%}>
            {% include "snipplets/svg/info-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
            <span>{{ 'El precio de envío incluye este producto y todos los que agregaste al carrito.' | translate }}</span>
        </span>
    </div>
{% 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.

<li class="js-shipping-list-item radio-button-item">
    <label class="js-shipping-radio radio-button list-item" data-loop="shipping-radio-{{loop.index}}">
        <input 
        id="{% if featured_option %}featured-{% endif %}shipping-{{loop.index}}" 
        class="js-shipping-method {% if not featured_option %}js-shipping-method-hidden{% 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 featured_option and loop.first %}checked="checked"{% endif %} name="option" 
        style="display:none" />
        <span class="radio-button-content">
            <span class="radio-button-icons">
                <span class="radio-button-icon unchecked"></span>
                <span class="radio-button-icon checked"></span>
            </span>
            <span class="radio-button-label">


                {# Improved shipping option with no carrier img and ordered shipping info #}
                
                <div class="radio-button-text"> 
                    {% if option.show_price %} 
                        <div class="mb-1 d-inline-block">
                            <span class="text-primary h6">
                                {% if option.cost.value == 0  %}
                                    {{ 'Gratis' | translate }}
                                {% else %}
                                    {{option.cost}}
                                {% endif %}
                            </span>
                            {% if option.cost.value == 0 and option.old_cost.value %}
                                <span class="price-compare text-foreground font-small ml-1">{{option.old_cost}}</span>
                            {% endif %}
                        </div>
                    {% endif %}
                    {% if option.time %}
                        <div>
                            <strong>
                            {% if store.has_smart_dates %}
                                {{option.dates}}
                            {% else %}
                                {{option.time}}
                            {% endif %}
                            </strong>
                        </div>
                    {% endif %}
                </div>
                <div class="radio-button-text">
                    {{option.short_name}} {{ option.method == 'branch'  ? option.extra.extra  :  '' }}
                </div>
                {% if option.payment_rules %}
                    <div>
                        {% include "snipplets/svg/info-circle.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
                        <i>{{option.payment_rules}}</i>
                    </div>
                {% endif %}


                {% if option.suboptions is not empty %}
                    {% include "snipplets/shipping_suboptions/#{option.suboptions.type}.tpl" with {'suboptions': option.suboptions} %}
                {% endif %}


                {% if option.warning['enable'] %}
                    <div class="alert alert-warning">
                      <p>{{ option.warning['message'] }}</p>
                    </div>
                {% endif %}
            </span>
        </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 %}


        <p class="js-shipping-suboption-product mb-1" style="display: none;">{{ 'Podrás elegir alguna de las siguientes opciones antes de finalizar la compra:' | translate }}</p>

        {# Read only suboptions #}
        <ul class="js-shipping-suboption-list" name="{{suboptions.name}}" style="display: none;">
            {% for option in suboptions.options %}
                <li class="text-capitalize">{{ option.name | lower }}</li>
            {% endfor %}
        </ul>

        {# Select suboptions for cart page #}

        <div class="js-shipping-suboption-select" style="display:none;">
        {% embed "snipplets/forms/form-select.tpl" with{ select_name: suboptions.name, select_group_custom_class: 'm-0'} %}
            {% block select_options %}
               <option {% if not suboptions.selected %}selected{% endif %} disabled>{{ suboptions.default_option | translate }}</option>
                {% for option in suboptions.options %}
                    <option value="{{option.value}}">{{ option.name | lower }}</option>
                {% endfor %}
            {% endblock select_options%}
        {% endembed %}
        </div>

    {% 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 %}
      <div data-toggle="#installments-modal" class="js-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 %}

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

    {% if product_can_show_installments %}

      {# If NOT product detail, just include installments alone without link or container #}
      <div class="{% if product_detail %}js-max-installments-container js-max-installments text-center text-md-left{% else %}item-installments{% endif %}">
        {% set max_installments_without_interests = product.get_max_installments(false) %}
        {% set max_installments_with_interests = product.get_max_installments %}
        {% if store.country == 'AR' %}
          {% if max_installments_with_interests %}
            <div>{{ "Hasta <strong class='installment-amount'>{1}</strong> cuotas" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</div>
          {% else %}
            <div style="display: none;">
            {% if product.max_installments_without_interests %}
              {{ "Hasta <strong class='js-installment-amount installment-amount'>{1}</strong> cuotas sin interés" | t(null, null) }}
            {% else %}
              {{ "Hasta <strong class='js-installment-amount installment-amount'>{1}</strong> cuotas sin interés" | t(null, null) }}
            {% endif %}
            </div>
          {% endif %}
        {% else %}
            {% if max_installments_without_interests and max_installments_without_interests.installment > 1 %}
              <div class="js-max-installments">{{ "<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) }}</div>
            {% else %}
              {% 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 %}
                    {{ "<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) }}
                  {% 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 svg-icon-text"} %}
              </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 store.country == 'BR' %}
  {% 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 %} style="display: none;" {% endif %} data-interest="{{ interest_value }}" data-cart-installment="{{ installment }}" class="js-installments-cart-total text-right"> 
    {{ 'O hasta' | translate }}
    <span class="js-cart-installments-amount">{{ installment }}</span> 
    {{ 'cuotas de' | translate }} 
    <span class="js-cart-installments">{{ (total_installment / installment) | money }}</span> 
    <span {% if interest == true %} style="display: none;" {% endif %}class="js-installments-type-interest">{{ 'sin interés' | translate}}</span>
  </div>
  {% endif %}
{% 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 %}

    {% embed "snipplets/modal.tpl" with{modal_id: 'installments-modal', modal_position: 'bottom', modal_transition: 'slide', modal_header: true, modal_footer: true, modal_width: 'centered'  } %}
        {% 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 %}
                        <li id="method_{{ method }}" class="js-refresh-installment-data js-installments-gw-tab js-tab tab {% if loop.first %} active {% endif %}" data-code="{{ method }}">
                            <a href="#installment_{{ method }}_{{ 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 }}</a>
                            </li>
                        {% endif %}
                    {% endfor %}
                </ul>

                {# Gateways tab content #}

                <div class="js-tabs-content tab-content">
                    {% for method, installments in installments_info %}
                        {% set discount = product.get_gateway_discount(method) %}
                        <div id="installment_{{ method }}_" 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 #}

                                    {% if method == 'mercadopago' and store.country == 'AR' %}

                                        {# 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-1">{{ 'Cuando termines la compra vas a ver la información de pago en relación a esta opción.' | translate }}</h6>

                                    {# Price total #}

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

                                    {% if custom_payment.discount > 0 %}
                                        <div> {{ custom_payment.name }}: {{ 'tiene un' | translate }} <strong>{{ custom_payment.discount }}% {{'de descuento' | translate }}</strong> {{'que será aplicado sobre el costo total de la compra 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 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 #}

<div itemprop="name">
    {% embed "snipplets/page-header.tpl" %}
        {% block page_header_text %}{{ product.name }}{% endblock page_header_text %}
    {% endembed %}
</div>

{# Product price #}

<div class="price-container text-center text-md-left" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
    <span class="d-inline-block">
       <h4 id="compare_price_display" class="js-compare-price-display price-compare {% if 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" itemprop="price"{% if product.display_price %} content="{{ product.price / 100 }}"{% endif %} {% if not product.display_price %}style="display:none;"{% endif %}>{% if product.display_price %}{{ product.price | money }}{% endif %}</h4>
    </span>
    <meta itemprop="priceCurrency" content="{{ product.currency }}" />
    {% if product.stock_control %}
        <meta itemprop="inventoryLevel" content="{{ product.stock }}" />
        {% set schema_org_availability = "http://schema.org/#{ product.stock ? 'InStock' : 'OutOfStock' }" %}
        <meta itemprop="availability" href="{{ schema_org_availability }}" content="{{ schema_org_availability }}" />
    {% endif %}
</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"><strong>{{ "¡{1}% OFF comprando {2} o más!" | translate(threshold.discount_decimal_percentage * 100, threshold.quantity) }}</strong></h4>
            {% endfor %}
        {% else %}
            <h4 class="mb-2"><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 }}">
    <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"} %}
    <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 %} />

    {% if settings.shipping_calculator_product_page and not product.free_shipping %}

        <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_show': settings.shipping_calculator_cart_page and not product.free_shipping, 'shipping_calculator_variant' : product.selected_or_first_available_variant} %}
            {% endif %}

            {% if store.branches and store.country != 'BR' %}
                
                {# 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">
        <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

{% 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" />
                     <img src="{{ image | product_image_url('tiny') }}" class="js-product-slide-img product-slider-image img-absolute img-absolute-centered blur-up" />
                </a>
             </div>
            {% endfor %}
        </div>
        <div class="js-swiper-product-pagination swiper-pagination swiper-pagination-white"></div>
        {% if product.images_count > 1 %}
            <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-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 #}
        
<div class="row">
    <div class="col col-md-4">
        {% 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'} %}
            {% 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 %}
    </div>
</div>

Incluímos este tpl no snipplet product-form.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 form-row">
    {% for variation in product.variations %}
        <div class="{% if loop.length == 3 %} col-12 col-md-4 {% elseif loop.length == 2 %} col-6 {% else %} col col-md-6{% endif %}">
            {% embed "snipplets/forms/form-select.tpl" with{select_label: true, select_label_name: '' ~ variation.name ~ '', select_for: 'variation_' ~ loop.index , select_id: '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>

Incluimos este tpl en el snipplet product-form.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{% endif %} head-{{ settings.head_background }} {% if settings.head_fix %}head-fix{% endif %}">

    {# 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, add_to_cart: true} %}
</header>

{# 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 %}

{# 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 %}           

    {# 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' } %}
        {% 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.

<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>

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 store.country == 'AR' %}
                                    {% set max_installments_with_interests = product.get_max_installments %}
                                    {% if max_installments_with_interests %}
                                        <span>| {{ "Hasta <strong class='installment-amount'>{1}</strong> cuotas" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</span>
                                    {% endif %}
                                {% else %}
                                    {% if max_installments_without_interests and max_installments_without_interests.installment > 1 %}
                                        <span>| {{ "<strong class='installment-amount'>{1}</strong> cuotas sin interés de <strong class='installment-price'>{2}</strong>" | t(max_installments_without_interests.installment, max_installments_without_interests.installment_data.installment_value_cents | money) }}</span>
                                    {% else %}
                                        {% set max_installments_with_interests = product.get_max_installments %}
                                        {% if max_installments_with_interests %}
                                            <span>| {{ "<strong class='installment-amount'>{1}</strong> cuotas de <strong class='installment-price'>{2}</strong>" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</span>
                                        {% endif %}
                                    {% endif %}
                                {% 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 }}"/>
        <button type="submit" class="btn search-input-submit" value="">
            {% 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">
            {% 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.google_plus 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">
    <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) ~ (store.business_id ? ' - ' ~ store.business_id : ''), "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="Empty placeholder"/>
                                {% 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>

Incluimos este tpl en los templates layout.tpl y password.tpl 

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">
            {% 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">
        {% 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 }}">{{ language.country | flag_url | img_tag(language.name) }}</a>
            {% endfor %}
        </div>
    {% endif %}
    <ul class="nav-account">
        {% if not customer %}
            {% if store.customer_accounts != 'mandatory' %}
            <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 form-row" data-item-id="{{ item.id }}">

  {# Cart item image #}
  <div class="col-2 {% if cart_page %}col-md-1{% endif %}">
    <img src="{{ item.featured_image | product_image_url('medium') }}" class="img-fluid" />
  </div>
  <div class="col-10 {% if cart_page %}col-md-11{% endif %}">

    {# Cart item name #}
    <div class="cart-item-name">
      <a href="{{ item.url }}">
        {{ item.short_name }}
      </a>
      <small>{{ item.short_variant_name }}</small>
    </div>

    {# Cart item quantity controls #}
    <span class="pull-left">
      <button type="button" 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"} %}
      </button>
      <span>
        <input type="number" name="quantity[{{ item.id }}]" data-item-id="{{ item.id }}" value="{{ item.quantity }}" class="js-cart-quantity-input cart-item-input form-control"/>
      </span>
      <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>
      <button type="button" 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"} %}
      </button>
    </span>

    {# Cart item subtotal mobile #}
    <h6 class="js-cart-item-subtotal cart-item-subtotal" data-line-item-id="{{ item.id }}">{{ item.subtotal | money }}</h6>
  </div>

  {# Cart item delete #}
  <div class="col-1 cart-item-delete text-right">
    <button type="button" class="btn" 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.subtotal }}"></div>

{# Used to assign currency to total #}
<div id="store-curr" class="hidden">{{ cart.currency }}</div>
    
{# Cart panel subtotal #}
<h5 class="js-visible-on-cart-filled {% if not cart_page %}row{% 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 }}
    {% if settings.shipping_calculator_cart_page %}
      <small>{{ " (sin envío)" | translate }}</small>
    {% endif %}
    :
  </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 panel 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>

{% if settings.shipping_calculator_cart_page %}
  <div class="js-visible-on-cart-filled divider" {% 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 ' | translate }}</strong>{{ 'porque el total de los items del carrito superan el peso máximo.' | translate }}
      </div>
      <div>
        {{ '¡No te preocupes! Podés elegir otro medio de envío.' | 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 {'shipping_calculator_show': settings.shipping_calculator_cart_page, 'product_detail': false} %}
      {% endif %}

      {# Store branches #}

      {% if store.branches and store.country != 'BR' %}

        {# Link for branches #}

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

  <div class="js-visible-on-cart-filled divider {% if not store.branches or store.country == 'BR' %} mt-0{% endif %}" {% if cart.items_count == 0 %}style="display:none;"{% endif %}></div>

{% endif %}

{# Cart panel total #}


<div class="js-cart-total-container js-visible-on-cart-filled mb-3" {% if cart.items_count == 0 %}style="display:none;"{% endif %}>
  <h2 class="{% if not cart_page %}row{% else %}text-right{% endif %} text-primary mb-0">
    <span {% if not cart_page %}class="col"{% endif %}>{{ "Total" | translate }}:</span>
    <span class="js-cart-total {% if cart.shipping_data.selected %}js-cart-saved-shipping{% endif %} {% if not cart_page %}col{% 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 container-fluid" {% 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 agregar este producto al carrito. Si querés podés" | translate }}<a href="{{ store.products_url }}" class="btn-link">{{ "ver otros acá" | translate }}</a>
  </div>
  <div>
    {% if cart_page %}
    <div class="row justify-content-end">
      <div class="col col-md-3">
    {% endif %}

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

    <div class="js-ajax-cart-submit row mb-3" {{ cart.total < cart_total ? '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 panel continue buying link #}

    {% if settings.continue_buying %}
      <div class="row mb-2">
        <div class="text-center w-100">
          <a href="#" class="js-modal-close btn btn-link">{{ 'Seguir comprando' | translate }}</a>
        </div>
      </div>
    {% endif %}

    {# Cart minium alert #}

    <div class="js-ajax-cart-minimum alert alert-warning mt-4" {{ cart.total >= cart_total ? 'style="display:none"' }} id="ajax-cart-minumum-div">
      {{ "El monto mínimo de compra (subtotal) es de" | translate }} {{ cart_total | money }}
    </div>
    <input type="hidden" id="ajax-cart-minimum-value" value="{{ cart_total }}"/>
    {% if cart_page %}
    </div>
    </div>
    {% endif %}
  </div>
</div>

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">
    <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 %} alt="{{ banner_title }}" title="{{ banner_title }}"{% endif %}>
                            {% endif %}
                            {% if store.thumbnails_enabled %}
                                <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %} lazyautosizes lazyload blur-up"{% if "#{banner}.jpg" | has_custom_image %} data-bgset='{{ "#{banner}.jpg" | static_url | settings_image_url('large') }} 480w, {{ "#{banner}.jpg" | static_url | settings_image_url('huge') }} 640w' data-sizes="auto" style="background-image: url({{ "#{banner}.jpg" | static_url | settings_image_url('tiny') }});"{% endif %}>
                            {% else %}
                                <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %} lazyload blur-up"{% if "#{banner}.jpg" | has_custom_image %} data-bg='{{ "#{banner}.jpg" | static_url }}' style="background-image: url({{ "#{banner}.jpg" | static_url | settings_image_url('tiny') }});" {% endif %}>
                            {% 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 %}
                                    <div class="btn btn-line btn-small">{{ banner_button_text }}</div>
                                {% 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">
        <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>
{% 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.video_embed %}
    <section class="section-video-home">
        <div class="container{% if settings.video_full %}-fluid p-0{% endif %}">
            <div class="row no-gutters">
                <div class="col">
                    <div class="js-video-home embed-responsive embed-responsive-16by9">
                        <div class="js-play-button video-player">
                            <div class="video-player-icon">
                                {% include "snipplets/svg/play-circle.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-invert"} %}
                            </div>
                        </div>
                        <div class="js-video-image">
                            <img data-src="" class="lazyload js-lazy-loading img-fluid video-image">
                        </div>
                    </div>
                </div>
            </div>
        </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 %}
            <div class="row {% if settings.modules_full %}no-gutters{% endif %} align-items-center">               
                
                {% if banner_url %}
                    <a class="module-with-text-link" href="{{ module_url }}"{% if module_title %} alt="{{ module_title }}" title="{{ module_title }}"{% endif %}>
                {% endif %}
                    <div class="col-md {% if module_align == 'right' %}order-md-2{% endif %}">
                        <div class="textbanner">
                        {% if store.thumbnails_enabled %}
                            <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %} lazyautosizes lazyload blur-up"{% if "#{module}.jpg" | has_custom_image %} data-bgset='{{ "#{module}.jpg" | static_url | settings_image_url('large') }} 480w, {{ "#{module}.jpg" | static_url | settings_image_url('huge') }} 640w' data-sizes="auto" style="background-image: url({{ "#{module}.jpg" | static_url | settings_image_url('tiny') }});"{% endif %}>
                        {% else %}
                            <div class="textbanner-image{% if has_banner_text and textoverimage %} overlay{% endif %} lazyload blur-up"{% if "#{module}.jpg" | has_custom_image %} data-bg='{{ "#{module}.jpg" | static_url }}' style="background-image: url({{ "#{module}.jpg" | static_url | settings_image_url('tiny') }});" {% endif %}>
                        {% endif %}
                            </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 %}
                                <div class="btn btn-primary btn-small">{{ module_button_text }}</div>
                            {% endif %}
                        </div>
                    </div>  
                {% if module_url %}
                    </a>
                {% endif %}


            </div>
            {% 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 %}">
    <div class="js-home-slider nube-slider-home swiper-container" style="visibility:hidden; height:0;">
        <div class="swiper-wrapper">
            {% for slide in settings.slider %}
                <div class="swiper-slide slide-container">
                    {% if slide.link %}
                        <a href="{{ slide.link }}">
                    {% endif %}        
                        <div data-background="{{ slide.image | static_url | settings_image_url('1080p') }}" class="slider-slide swiper-lazy">
                        </div>
                        {% if not params.preview %}
                        <div style="background-image: url({{ slide.image | static_url | settings_image_url('tiny') }});" class="js-slider-preloader slider-slide preloader-bg-img"></div>
                        {% endif %}
                    {% if slide.link %}
                        </a>
                    {% endif %}
                </div>
            {% endfor %}
        </div>
        <div class="js-swiper-home-pagination swiper-pagination swiper-pagination-white"></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>
    {% snipplet 'placeholders/home-slider-placeholder.tpl' %}
</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">
        <div class="container{% if settings.video_full %}-fluid p-0{% endif %}">
            <div class="row no-gutters">
                <div class="col">
                    <div class="js-video-home embed-responsive embed-responsive-16by9">
                        <div class="js-play-button video-player">
                            <div class="video-player-icon">
                                {% include "snipplets/svg/play-circle.tpl" with {svg_custom_class: "icon-inline icon-2x svg-icon-invert"} %}
                            </div>
                        </div>
                        <div class="js-video-image">
                            <img data-src="" class="lazyload js-lazy-loading img-fluid video-image">
                        </div>
                    </div>
                </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 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 }}">
    {% endif %}
    <div class="js-modal-close 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">
                    <span>{{ "Seguí acá" | translate | a_tag(status_page_url) }}</span> <span class="btn btn-link">{{ "tu última compra" | translate }}</span>
                    <a class="js-notification-close ml-2" href="#">
                        {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-primary"} %}
                    </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" style="display: none;">
        <div class="js-toggle-cart notification notification-primary"> 
            {% include "snipplets/svg/shopping-bag.tpl" with {svg_custom_class: "icon-inline svg-icon-primary mr-1"} %}
            <span>{{ '¡Excelente! Ya agregamos tu producto al carrito.' | translate }}</span>
        </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 not product.has_stock or product.free_shipping or product.compare_at_price or product.promotional_offer %}
  <div class="labels">
    {% if not product.has_stock %}
      <div class="{% if product_detail %}js-stock-label {% endif %}label label-default">{{ "Sin stock" | translate }}</div>
    {% else %}
      {% if product.compare_at_price or product.promotional_offer %}
        <div class="{% if not product.promotional_offer and product %}js-offer-label{% endif %} label label-primary" {% 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 %}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 %}>
            {% 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 }}">
         {% 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="Share on Facebook">
         {% 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="Share on Twitter">
         {% 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" href="#" target="_blank" data-network="pinterest">
        {% 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' %}
    <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 %}">
                {% include 'snipplets/breadcrumbs.tpl' %}
                <h1>{% block page_header_text %}{% endblock %}</h1>
            </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">
        {% 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: 'E-mail' } %}
                        {% block input_label_text %}{{ 'E-mail' | translate }}{% endblock input_label_text %}
                    {% 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">
        <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