Usando o Twig, podemos incluir snipplets, que são os arquivos “.tpl” dentro da pasta com o mesmo nome, de três maneiras.
Isso nos dá a possibilidade de reutilizar o mesmo componente em mais de um lugar, otimizando o código e facilitando sua manutenção.
Podemos incluir snipplets usando:
- {% snipplet %}
- {% include %}
- {% embed %}
{% snipplet %}
Se precisarmos apenas chamar um snipplet sem nenhum parâmetro extra ou condicional, então este caminho é indicado.
{% if settings.ad_bar and settings.ad_text %} {% snipplet "header/header-advertising.tpl" %} {% endif %}
No exemplo, simplesmente chamamos o snippet header-advertising.tpl dentro da pasta header, apenas para mostrar uma mensagem acima da navegação.
Como estamos usando {% snipplet%} não é necessário esclarecer que a pasta de cabeçalho está dentro da pasta snipplets.
{% include %}
Include é uma maneira um pouco mais complexa de chamar snipplets, onde podemos usar certas condições dentro do próprio snipplet ao usá-lo, vamos ver um exemplo.
No layout Base temos um snipplet chamado notifications.tpl onde temos o HTML para todas as notificações do Storefront, que até agora são duas:
Adicionar ao carrinho
Seguir os detalhes do pedido:
Dentro do snipplet nós temos algo parecido com isto:
{# Order notification #} {% if order_notification %} content {% endif %} {# Add to cart notification #} {% if add_to_cart %} content {% endif %}
Podemos ver duas condições, uma para mostrar a mensagem "Seguir pedido" com a condição "order_notification"; e outra para a mensagem “Produto adicionado ao carrinho” com a condição “add_to_cart”.
Ambas as condições são personalizadas, ou seja, são nomes que definimos arbitrariamente e não dependem de uma alteração no PHP.
Usamos essas condições ao chamar o arquivo notification.tpl para escolher qual notificação queremos exibir.
Por exemplo, se quisermos mostrar os dois no mesmo lugar (falando em termos de posição no HTML), fazemos o seguinte:
{% include "snipplets/notification.tpl" with {order_notification: true, add_to_cart: true} %}
Se precisarmos mostrar mais de uma notificação, podemos fazer isso chamando o mesmo snipplet em lugares diferentes:
{% include "snipplets/notification.tpl" with {order_notification: true} %} ... {% include "snipplets/notification.tpl" with {add_to_cart: true} %}
No primeiro exemplo, mostramos apenas a notificação "Seguir seu pedido" e, abaixo, usamos o mesmo snipplet apenas para mostrar a notificação "Produto adicionado ao carrinho".
Usamos o include também para mostrar todos os ícones SVG do layout.
Nossos ícones estão em arquivos ".tpl" que contêm um código SVG como qualquer outro:
<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>
Só que deixamos a classe CSS dentro de um parâmetro com em Twig:
<svg class="{{ svg_custom_class }}"
Fazemos isso para escolher a classe que precisamos quando usamos o include, substituindo o que está entre chaves, então queremos:
{% include "snipplets/svg/search.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
Para fechar, é importante notar que precisamos especificar que o arquivo está na pasta “snipplets”, diferente de quando usamos {% snipplet%} onde não é necessário.
{% embed %}
O embeded é muito semelhante ao include, porém um pouco mais complexo. Vamos ver isso com um exemplo:
No layout Base, usamos o embeded para o componente “select” (entre muitos outros).
O snipplet é form-select.tpl e seu código é o seguinte:
<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>
Neste arquivo, usamos classes às quais passamos parâmetros quando eles são incluídos (como no exemplo de SVGs com um include).
<div class="form-group {{ select_group_custom_class }}">
Também usamos condições personalizadas como na inclusão.
{% 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 %}
Mas a diferença com o include está no uso de um "block"
<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>
O block nos permite deixar um espaço vazio ao qual podemos adicionar o conteúdo que precisamos ao usar o snipplet.
No caso do select, nós o usamos para adicionar as opções de que precisamos, pois podem ser duas ou mais.
Um exemplo de como chamar form-select.tpl usando embed é a seguinte:
{% embed "snipplets/forms/form-select.tpl" with{select_label: false, select_custom_class: 'js-sort-by'} %} {% block select_options %} <option value="1">{{ 'texto 1' | translate }}</option> <option value="2">{{ 'texto 2' | translate }}</option> <option value="3">{{ 'texto 3' | translate }}</option> <option value="4">{{ 'texto 4' | translate }}</option> {% endblock select_options%} {% endembed %}
Neste caso, mostramos um select sem um label (já que tem a condição select_label: false) com uma classe customizada “js-sort-by” e dentro do block tem quatro opções estáticas.
Outro exemplo é o componente para as variantes de um produto:
{% for variation in product.variations %} <div class="col-12"> {% 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 %}
Aqui há muito mais propriedades, mas a maior diferença está dentro do block em que não temos mais conteúdo estático, mas usamos um for para iterar sobre as propriedades de cada variante.
Para fechar, devemos esclarecer que o snipplet está dentro da pasta snipplets, da mesma forma que fazemos em um include.
Tip:
Se precisarmos usar texto estático em um embeded (e em um include também), podemos fazer da seguinte maneira
select_label_name: 'text' | translate,
Se quisermos um texto dinâmico, fazemos desta maneira:
select_label_name: '' ~ variation.name ~ '',