Neste tutorial, vamos implementar o comportamento para que, nas listagens de produtos, seja exibido um carrossel de imagens em cada item de produto.
HTML
1. A primeira coisa que faremos é substituir a imagem pelo componente privado de imagem para o item de produto product-item-image, que inclui a segunda imagem que precisamos.
Vamos procurar o snipplet item.tpl dentro da pasta snipplets/grid. Pode ser que, no seu layout, este snipplet se chame single_product.tpl.
Dentro deste arquivo, vamos procurar o seguinte código relacionado à imagem e seu contêiner:
<div class="item-image mb-2"> <div style="padding-bottom: {{ item_img_spacing }}%;" class="p-relative" data-store="product-item-image-{{ product.id }}"> <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}"> <img alt="{{ item_img_alt }}" data-expand="-10" src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset="{{ item_img_srcset | product_image_url('small')}} 240w, {{ item_img_srcset | product_image_url('medium')}} 320w, {{ item_img_srcset | product_image_url('large')}} 480w" class="js-item-image lazyload img-absolute img-absolute-centered fade-in" width="{{ item_img_width }}" height="{{ item_img_height }}" /> <div class="placeholder-fade"></div> </a> </div> </div>
E o substituímos pelo componente privado (se você já tiver a funcionalidade Segunda imagem em rollagem, precisamos ter cuidado para não remover os parâmetros do componente privado usados para isso.):
{# Item image slider #} {% set show_image_slider = (template == 'category' or template == 'search') and settings.product_item_slider and not reduced_item and not slide_item and not has_filters and product.other_images %} {% if show_image_slider %} {% set slider_controls_container_class = 'item-slider-controls-container d-none d-md-block' %} {% set slider_control_class = 'icon-inline icon-w-8 icon-2x svg-icon-text' %} {% set control_prev = include ('snipplets/svg/chevron-left.tpl', {svg_custom_class: slider_control_class}) %} {% set control_next = include ('snipplets/svg/chevron-right.tpl', {svg_custom_class: slider_control_class}) %} {% endif %} {% set image_classes = 'js-item-image lazyload img-absolute img-absolute-centered fade-in' %} {% set data_expand = show_image_slider ? '50' : '-10' %} {{ component( 'product-item-image', { image_lazy: true, image_lazy_js: true, image_thumbs: ['small', 'medium', 'large', 'huge', 'original'], image_data_expand: data_expand, slider: show_image_slider, placeholder: true, svg_sprites: false, product_item_image_classes: { image_container: 'item-image mb-2', image_padding_container: 'p-relative', image: image_classes, slider_container: 'swiper-container position-absolute h-100 w-100', slider_wrapper: 'swiper-wrapper', slider_slide: 'swiper-slide item-image-slide', slider_control_pagination: 'swiper-pagination item-slider-pagination font-small d-md-none', slider_control: 'fa-lg svg-icon-primary', slider_control_prev_container: 'swiper-button-prev ' ~ slider_controls_container_class, slider_control_next_container: 'swiper-button-next ' ~ slider_controls_container_class, more_images_message: 'item-more-images-message font-small', placeholder: 'placeholder-fade', }, custom_control_prev: control_prev, custom_control_next: control_next, }) }}
O componente privado product-item-image inclui o contêiner da imagem e as imagens necessárias (tanto a principal quanto a secundária). Por sua vez, ele também utiliza outro componente privado específico para a imagem. Recomendamos revisar a documentação de cada componente para entender quais parâmetros eles aceitam:
2. Uma vez incluído o componente product-item-image, precisamos adicionar dentro deste componente todos os elementos que estão flutuando sobre a imagem, como, por exemplo, as etiquetas.
Vamos procurar este conteúdo e vamos englobá-lo em um {% set floating_elements %}
da seguinte maneira:
{% set floating_elements %} {% if not reduced_item %} {% if settings.product_color_variants %} {% include 'snipplets/labels.tpl' with {color: true} %} {% include 'snipplets/grid/item-colors.tpl' %} {% else %} {% include 'snipplets/labels.tpl' %} {% endif %} {% endif %} {% endset %}
Uma vez definido "floating_elements", vamos usá-lo no parâmetro "custom_content" do product-item-image da seguinte forma:
{{ component( 'product-item-image', { image_lazy: true, image_lazy_js: true, image_thumbs: ['small', 'medium', 'large', 'huge', 'original'], image_data_expand: data_expand, slider: show_image_slider, placeholder: true, svg_sprites: false, custom_content: floating_elements, product_item_image_classes: { image_container: 'item-image mb-2', image_padding_container: 'p-relative', image: image_classes, slider_container: 'swiper-container position-absolute h-100 w-100', slider_wrapper: 'swiper-wrapper', slider_slide: 'swiper-slide item-image-slide', slider_control_pagination: 'swiper-pagination item-slider-pagination font-small d-md-none', slider_control: 'fa-lg svg-icon-primary', slider_control_prev_container: 'swiper-button-prev ' ~ slider_controls_container_class, slider_control_next_container: 'swiper-button-next ' ~ slider_controls_container_class, more_images_message: 'item-more-images-message font-small', placeholder: 'placeholder-fade', }, custom_control_prev: control_prev, custom_control_next: control_next, }) }}
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.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.
{# /* // Grid item */ #} .item-image-slide img{ max-width: 100%; object-fit: contain; object-position: top; } .item-more-images-message { position: absolute; top: 10px; right: 15px; z-index: 1; opacity: 0; text-transform: uppercase; transform: initial; transition: all 0.2s ease; } @media (min-width: 768px) { .item-slider-controls-container { opacity: 0; transition: opacity .2s ease; } .item-slider-controls-container.swiper-button-disabled { opacity: 0; cursor: auto; } .item-image:hover .item-slider-controls-container:not(.swiper-button-disabled) { opacity: 1; } }
JS
1. Precisamos rodar o JS necessário para gerar os sliders à medida que cada item de produto é visualizado na tela. Para isso, precisamos adicionar o seguinte código:
{% set has_item_slider = settings.product_item_slider %} {% if template == 'category' or template == 'search' %} {# /* // Product item slider */ #} {% if has_item_slider %} LS.productItemSlider({ pagination_type: 'fraction', onInit: function(){ console.log('init'); }, onSlideChange: function(){ console.log('slideChange'); } }); {% endif %} {% endif %}
No exemplo, podemos ver todos os parâmetros que podem ser usados:
- pagination_type: Por padrão, usa "bullets", mas se for necessário usar o formato de fração (Ex: 1/6), pode-se usar o valor "fraction". Caso contrário, não é necessário especificá-lo.
- onInit: Serve para adicionar JS depois que cada slider é inicializado.
- onSlideChange: Serve para adicionar JS depois que cada slider muda de slide.
2. Caso tenha a funcionalidade de scroll infinito, é necessário adicionar o seguinte código:
{# /* // Infinite scroll */ #} {% if pages.current == 1 and not pages.is_last %} LS.hybridScroll({ productGridSelector: '.js-product-table', spinnerSelector: '#js-infinite-scroll-spinner', loadMoreButtonSelector: '.js-load-more', hideWhileScrollingSelector: ".js-hide-footer-while-scrolling", productsBeforeLoadMoreButton: 50, productsPerPage: 12, {% if has_item_slider %} afterLoaded: function(){ LS.productItemSlider({ pagination_type: 'fraction', }); }, {% endif %} }); {% endif %}
Como neste tutorial usamos a técnica de lazy load com o plugin Lazysizes, precisamos adicioná-lo. Para ver como fazer isso, você pode ler este pequeno artigo.
Por outro lado também usamos um slider com o Swiper, precisamos adicionar o plugin. Para ver como fazer isso, você pode ler este pequeno artigo.
Configurações
No arquivo config/settings.txt, adicionaremos um checkbox que ativa a funcionalidade na seção "Lista de produtos".
title title = Fotos del producto checkbox name = product_item_slider description = Mostrar las fotos en un carrusel para cada producto subtitle subtitle = <span class='js-description-html legend d-block p-top-half'>El carrusel aplica sólo a listados de categorías y resultados de búsqueda</span>
Traduções
Nesta etapa, adicionamos os textos para as traduções no arquivo config/translations.txt.
es "Fotos del producto" pt "Fotos do produto" en "Product photos" es_mx "Fotos del producto" es "Mostrar las fotos en un carrusel para cada producto" pt "Exibir fotos em um carrossel para cada produto" en "Show photos in a carousel for each product" es_mx "Mostrar las fotos en un carrusel para cada producto" es "<span class='js-description-html legend d-block p-top-half'>El carrusel aplica sólo a listados de categorías y resultados de búsqueda</span>" pt "<span class='js-description-html legend d-block p-top-half'>O carrossel se aplica somente a listagens de categorias e resultados de pesquisa</span>" es_mx "<span class='js-description-html legend d-block p-top-half'>El carrusel aplica sólo a listados de categorías y resultados de búsqueda</span>"
Ativação
Por último, você pode ativar funcionalidade no Administrador Nuvem, na seção ‘Personalizar seu layout atual’ dentro de ‘Lista de produtos’:
Lembre-se, para que o produto funcione, ele deve ter pelo menos 2 imagens.