Dependendo do seu layout, talvez seja necessário ter as categorias mais visíveis no celular. Neste tutorial, vamos ver como adicionar uma navegação apenas para categorias, veja como fica:

HTML
A primeira coisa que vamos fazer é criar a pasta de navigation dentro da pasta snipplets.
1. Na navigation, adicionamos os dois snipplets a seguir com seus respectivos códigos:
navigation-categories.tpl
Neste arquivo listamos todas as categorias e subcategorias da loja.
{# All store categories and subcategories with links #}
{% for category in categories %}
{% if category.subcategories %}
<a href="#" class="js-modal-open modal-list-item" data-toggle="#category-{{ category.id }}">
{{ category.name }}
{% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline icon-lg modal-list-icon"} %}
</a>
{% else %}
<a href="{{ category.url }}" class="modal-list-item">
{{ category.name }}
</a>
{% endif %}
{% endfor %}navigation-categories-panel.tpl
Aqui nós chamamos o componente modal ou popup por meio de um embed. Este snipplet chama a si mesmo iterando por cada subcategoria.
{# Modals for each subcategory #}
{% embed "snipplets/modal.tpl" with{modal_id: 'category-' ~ category.id, modal_class: 'categories', modal_position: 'right', modal_transition: 'slide', modal_width: 'full', modal_head: true, modal_overlay: false, modal_close_left: true, modal_helper: 'pb-5'} %}
{% block modal_head %}
{{ category.name }}
{% endblock %}
{% block modal_body %}
<a href="{{ category.url }}" class="modal-list-item font-weight-bold">
{{ "Ver toda esta categoría" | translate }}
</a>
{% snipplet "navigation/navigation-categories.tpl" with categories = category.subcategories %}
{% endblock %}
{% endembed %}
{% for subcategory in category.subcategories %}
{% snipplet "navigation/navigation-categories-panel.tpl" with category = subcategory %}
{% endfor %}2. Temos que chamar o link que abre o popup que engloba todas as categorias. No layout Base nós colocamos dentro do snipplet header.tpl dentro da pasta snipplets/header, mas no seu caso pode ser outro arquivo. O importante é que esteja dentro da navegação principal do site.
{# Main tab link #}
<a href="#" id="toggle-mobile-categories" class="js-modal-open btn btn-block nav-tab" data-toggle="#main-categories">
{{ 'Categorías' | translate }}
{% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "js-toggle-icon icon-inline icon-lg"} %}
{% include "snipplets/svg/chevron-up.tpl" with {svg_custom_class: "js-toggle-icon icon-inline icon-lg hidden"} %}
</a>3. Em seguida, adicionamos a classe js-head-main ao div que contém todo o had do site.
4. Dentro do mesmo tpl que editamos na etapa 2, mas fora da navegação do site, chamaremos os snipplets criados na etapa 1, da seguinte maneira:
{# Main categories modal #}
<div id="nav-mobile-categories" style="display: none;">
{% embed "snipplets/modal.tpl" with{modal_id: 'main-categories', modal_class: 'categories', modal_position: 'top', modal_transition: 'slide', modal_width: 'full', modal_overlay: false} %}
{% block modal_head %}
{% endblock %}
{% block modal_body %}
<a href="{{ store.products_url }}" class="modal-list-item font-weight-bold">
{{ 'Ver todos los productos' | translate }}
</a>
{% snipplet "navigation/navigation-categories.tpl" %}
{% endblock %}
{% endembed %}
{# Subcategories modals #}
{% for category in categories %}
{% snipplet "navigation/navigation-categories-panel.tpl" %}
{% endfor %}
</div>Podemos observar que novamente usamos um embed para o modal das categorias principais e, em seguida, adicionamos ao resto dos modais para as outras subcategorias, usando um for.
5. Agora precisamos criar o snipplet para o componente modal ou pop-up dentro da pasta snipplets. Este tpl é chamado modal.tpl e o código é:
{# /*============================================================================
#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
// modal_overlay - used for modals with an overlay behind
// modal_head - to show a header on the modal
// modal_close_left - If true shows arrow left on modal header, else shows an X to close
#Head
// Block - modal_head
#Body
// Block - modal_body
#Footer
// Block - modal_footer
#}
<div id="{{ modal_id }}" class="js-modal modal modal-{{ modal_class }} modal-{{modal_position}} transition-{{modal_transition}} modal-{{modal_width}} transition-soft {% if not modal_overlay %}js-no-overlay modal-no-overlay{% endif %}" style="display: none;">
{% if modal_form_action %}
<form action="{{ modal_form_action }}" method="post" class="{{ modal_form_class }}">
{% endif %}
{% if modal_head %}
<div class="js-modal-close modal-header">
<span class="modal-close">
{% if modal_close_left %}
{% include "snipplets/svg/chevron-left.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
{% else %}
{% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %}
{% endif %}
</span>
{% block modal_head %}{% endblock %}
</div>
{% endif %}
<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>Se você já estava usando este snipplet antes, provavelmente precisará atualizar os outros locais onde o usou, adicionando os parâmetros modal_head: true e modal_overlay: true na incorporação.
5. Por último, para a parte HTML, precisamos adicionar uma pasta SVG dentro da pasta snipplets, onde adicionaremos os sniplpets para os ícones usados. Neste caso, eles serão os seguintes:
times.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>chevron-down.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"/></svg>chevron-up.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M6.101 359.293L25.9 379.092c4.686 4.686 12.284 4.686 16.971 0L224 198.393l181.13 180.698c4.686 4.686 12.284 4.686 16.971 0l19.799-19.799c4.686-4.686 4.686-12.284 0-16.971L232.485 132.908c-4.686-4.686-12.284-4.686-16.971 0L6.101 342.322c-4.687 4.687-4.687 12.285 0 16.971z"/></svg>chevron-right.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M24.707 38.101L4.908 57.899c-4.686 4.686-4.686 12.284 0 16.971L185.607 256 4.908 437.13c-4.686 4.686-4.686 12.284 0 16.971L24.707 473.9c4.686 4.686 12.284 4.686 16.971 0l209.414-209.414c4.686-4.686 4.686-12.284 0-16.971L41.678 38.101c-4.687-4.687-12.285-4.687-16.971 0z"/></svg>chevron-left.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M231.293 473.899l19.799-19.799c4.686-4.686 4.686-12.284 0-16.971L70.393 256 251.092 74.87c4.686-4.686 4.686-12.284 0-16.971L231.293 38.1c-4.686-4.686-12.284-4.686-16.971 0L4.908 247.515c-4.686 4.686-4.686 12.284 0 16.971L214.322 473.9c4.687 4.686 12.285 4.686 16.971-.001z"/></svg>CSS
Requisito:
Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).
1. Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou no stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu design:
@mixin prefix($property, $value, $prefixes: ()) {
@each $prefix in $prefixes {
#{'-' + $prefix + '-' + $property}: $value;
}
#{$property}: $value;
}
{# /* // Modals */ #}
.modal{
color: $main-foreground;
background-color:$main-background;
&-list-item{
border-bottom: 1px solid rgba($main-foreground, .1);
}
}
{# /* // Buttons */ #}
.btn{
text-decoration: none;
text-align: center;
border: 0;
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
text-transform: uppercase;
background: none;
@include prefix(transition, all 0.4s ease, webkit ms moz o);
&:hover,
&:focus{
outline: 0;
opacity: 0.8;
}
&[disabled],
&[disabled]:hover{
opacity: 0.5;
cursor: not-allowed;
outline: 0;
}
}
.nav-tab{
border-top: 1px solid $main-foreground;
}2. Adicione os estilos no arquivo static/style-critical.tpl
Se em seu layout você usar um stylesheet para o CSS crítico, precisaremos do seguinte código dentro dele, mas se não for o caso, você poderá unificar o CSS dos passos 2 e 3 em um único arquivo.
.nav-tab{
padding: 10px;
font-weight: bold;
}3. Adicione os estilos no arquivo static/style-async.tpl
{# /* // Modals */ #}
.modal {
position: fixed;
top: 0;
display: block;
width: 80%;
height: 100%;
padding: 10px;
-webkit-overflow-scrolling: touch;
overflow-y: auto;
transition: all .2s cubic-bezier(.16,.68,.43,.99);
z-index: 20000;
&-header{
width: calc(100% + 20px);
margin: -10px 0 10px -10px;
padding: 10px 15px;
font-size: 20px;
}
&-footer{
padding: 10px;
clear: both;
}
&-full {
width: 100%;
}
&-docked-sm{
width: 100%;
}
&-docked-small{
width: 80%;
}
&-top{
top: -100%;
left: 0;
}
&-bottom{
top: 100%;
left: 0;
}
&-left{
left: -100%;
}
&-right{
right: -100%;
&.modal-categories{
top: auto;
}
}
&-centered{
height: 100%;
width: 100%;
}
&-top.modal-show,
&-bottom.modal-show {
top: 0;
&.modal-categories{
top: auto;
box-shadow: -4px 0 17px 0 rgba(0, 0, 0, 0.23);
}
}
&-left.modal-show {
left: 0;
}
&-right.modal-show {
right: 0;
}
&-close {
display: inline-block;
padding: 1px 5px 5px 0;
margin-right: 5px;
vertical-align: middle;
cursor: pointer;
}
.tab-group{
margin: 0 -10px 20px -10px;
}
&-list-item{
position: relative;
display: block;
width: 100%;
padding: 15px 5px;
text-align: left;
font-size: 14px;
}
&-list-icon{
position: absolute;
right: 10px;
}
&-categories .modal-header{
margin-bottom: 0;
}
}
.modal-overlay{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #00000047;
z-index: 10000;
}JS
⚠️ A partir do dia 30 de janeiro de 2023, a biblioteca jQuery será removida do código de nossas lojas, portanto, a função "$" não poderá ser utilizada.
1. Precisamos adicionar os JavaScript no arquivo store.js.tpl (ou onde você tem suas funções JS). O código que precisamos é o seguinte:
{# Full screen mobile modals back events #}
if (window.innerWidth < 768) {
{# Clean url hash function #}
cleanURLHash = function(){
const uri = window.location.toString();
const clean_uri = uri.substring(0, uri.indexOf("#"));
window.history.replaceState({}, document.title, clean_uri);
};
{# Go back 1 step on browser history #}
goBackBrowser = function(){
cleanURLHash();
history.back();
};
{# Clean url hash on page load: All modals should be closed on load #}
if(window.location.href.indexOf("modal-fullscreen") > -1) {
cleanURLHash();
}
{# Open full screen modal and url hash #}
jQueryNuvem(document).on("click", ".js-fullscreen-modal-open", function(e) {
e.preventDefault();
var modal_url_hash = jQueryNuvem(this).data("modalUrl");
window.location.hash = modal_url_hash;
});
{# Close full screen modal: Remove url hash #}
jQueryNuvem(document).on("click", ".js-fullscreen-modal-close", function(e) {
e.preventDefault();
goBackBrowser();
});
{# Hide panels or modals on browser backbutton #}
window.onhashchange = function() {
if(window.location.href.indexOf("modal-fullscreen") <= -1) {
{# Close opened modal #}
if(jQueryNuvem(".js-fullscreen-modal").hasClass("modal-show")){
{# Remove body lock only if a single modal is visible on screen #}
if(jQueryNuvem(".js-modal.modal-show").length == 1){
jQueryNuvem("body").removeClass("overflow-none");
}
var $opened_modal = jQueryNuvem(".js-fullscreen-modal.modal-show");
var $opened_modal_overlay = $opened_modal.prev();
$opened_modal.removeClass("modal-show");
setTimeout(() => $opened_modal.hide(), 500);
$opened_modal_overlay.fadeOut(500);
}
}
}
}
jQueryNuvem(document).on("click", ".js-modal-open", function(e) {
e.preventDefault();
var modal_id = jQueryNuvem(this).data('toggle');
var $overlay_id = jQueryNuvem('.js-modal-overlay[data-modal-id="' + modal_id + '"]');
if (jQueryNuvem(modal_id).hasClass("modal-show")) {
let modal = jQueryNuvem(modal_id).removeClass("modal-show");
setTimeout(() => modal.hide(), 500);
} else {
{# Lock body scroll if there is no modal visible on screen #}
if(!jQueryNuvem(".js-modal.modal-show").length){
jQueryNuvem("body").addClass("overflow-none");
}
$overlay_id.fadeIn(400);
jQueryNuvem(modal_id).detach().appendTo("body");
$overlay_id.detach().insertBefore(modal_id);
jQueryNuvem(modal_id).show().addClass("modal-show");
}
});
jQueryNuvem(document).on("click", ".js-modal-close", function(e) {
e.preventDefault();
{# Remove body lock only if a single modal is visible on screen #}
if(jQueryNuvem(".js-modal.modal-show").length == 1){
jQueryNuvem("body").removeClass("overflow-none");
}
var $modal = jQueryNuvem(this).closest(".js-modal");
var modal_id = $modal.attr('id');
var $overlay_id = jQueryNuvem('.js-modal-overlay[data-modal-id="#' + modal_id + '"]');
$modal.removeClass("modal-show");
setTimeout(() => $modal.hide(), 500);
$overlay_id.fadeOut(500);
{# Close full screen modal: Remove url hash #}
if ((window.innerWidth < 768) && (jQueryNuvem(this).hasClass(".js-fullscreen-modal-close"))) {
goBackBrowser();
}
});
jQueryNuvem(document).on("click", ".js-modal-overlay", function(e) {
e.preventDefault();
{# Remove body lock only if a single modal is visible on screen #}
if(jQueryNuvem(".js-modal.modal-show").length == 1){
jQueryNuvem("body").removeClass("overflow-none");
}
var modal_id = jQueryNuvem(this).data('modalId');
let modal = jQueryNuvem(modal_id).removeClass("modal-show");
setTimeout(() => modal.hide(), 500);
jQueryNuvem(this).fadeOut(500);
if (jQueryNuvem(this).hasClass("js-fullscreen-overlay") && (window.innerWidth < 768)) {
cleanURLHash();
}
});Traduções
Nesta etapa vamos adicionar os textos para as traduções no arquivo config/translations.txt
es "Categorías" pt "Categorias" en "Categories" es_mx "Categorías" es "Ver todos los productos" pt "Ver todos os produtos" en "See all products" es_mx "Ver todos los productos" es "Ver toda esta categoría" pt "Ver tudo desta categoria" en "See all this category" es_mx "Ver toda esta categoría"
Parabéns! Você já tem a navegação de categorias para celular no seu layout.