Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<section id="js-active-search-filters" class="{if $activeFilters|count}active_filters{else}hide{/if}">
{block name='active_filters_title'}
<h1 class="h6 {if $activeFilters|count}active-filter-title{else}d-block d-sm-none{/if}">{l s='Active filters' d='Shop.Theme.Global'}</h1>
{/block}
{if $activeFilters|count}
<ul>
{foreach from=$activeFilters item="filter"}
{block name='active_filters_item'}
<li class="filter-block">
{l s='%1$s:' d='Shop.Theme.Catalog' sprintf=[$filter.facetLabel]}
{$filter.label}
<a class="js-search-link" href="{$filter.nextEncodedFacetsURL}"><i class="material-icons close">&#xE5CD;</i></a>
</li>
{/block}
{/foreach}
</ul>
{/if}
</section>

View File

@@ -0,0 +1,15 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="js-product-list-footer">
{if $listing.pagination.items_shown_from == 1}
<div class="category__footer">
{if !empty($category.additional_description) && $listing.pagination.items_shown_from == 1}
<div class="category__additional-description rich-text">
{$category.additional_description nofilter}
</div>
{/if}
</div>
{/if}
</div>

View File

@@ -0,0 +1,42 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="js-product-list-header">
{if $listing.pagination.items_shown_from == 1}
<div class="category__header">
{include file='components/page-title-section.tpl' title=$category.name}
{if $category.description}
<div class="category__description rich-text">{$category.description nofilter}</div>
{/if}
{if !empty($category.cover.bySize.category_cover.url)}
<div class="category__cover">
<picture>
{if isset($category.cover.bySize.category_cover.sources.avif)}
<source srcset="{$category.cover.bySize.category_cover.sources.avif}" type="image/avif">
{/if}
{if isset($category.cover.bySize.category_cover.sources.webp)}
<source srcset="{$category.cover.bySize.category_cover.sources.webp}" type="image/webp">
{/if}
<img
class="category__cover-image img-fluid"
src="{$category.cover.bySize.category_cover.url}"
width="{$category.cover.bySize.category_cover.width}"
height="{$category.cover.bySize.category_cover.height}"
alt="{if !empty($category.cover.legend)}{$category.cover.legend}{else}{$category.name}{/if}"
fetchpriority="high"
>
</picture>
</div>
{/if}
{if isset($subcategories) && $subcategories|@count > 0}
{include file='catalog/_partials/subcategories.tpl' subcategories=$subcategories}
{/if}
</div>
{/if}
</div>

View File

@@ -0,0 +1,79 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'product-customization-modal'}
<div id="product-customizations-modal-{$customization.id_customization}" class="modal fade product-customization-modal" tabindex="-1" role="dialog" aria-hidden="true" aria-labelledby="customizations-modal-{$customization.id_customization}-title">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<p class="h2 modal-title" id="customizations-modal-{$customization.id_customization}-title">{l s='Product customization' d='Shop.Theme.Checkout'}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
{foreach from=$customization.fields item="field"}
<div class="{$componentName}__line">
<p class="{$componentName}__label">{$field.label}</p>
{if $field.type == 'text'}
<div class="{$componentName}__text">
{if $field.id_module|intval}
{$field.text nofilter}
{else}
{$field.text}
{/if}
</div>
{elseif $field.type == 'image'}
{assign var=image_modal_id value="{$componentName}_image--{mt_rand()}"}
<a href="#{$image_modal_id}" data-bs-toggle="modal" data-bs-dismiss="modal" >
<img class="{$componentName}__img" src="{$field.image.small.url}">
</a>
{append var='image_modals'
value=[
"id"=>$image_modal_id,
"title"=>$field.label,
"image_url"=>$field.image.large.url
]
}
{/if}
</div>
{/foreach}
</div>
</div>
</div>
</div>
{if isset($image_modals) && count($image_modals)}
<div class="{$componentName}__popup">
{foreach from=$image_modals item="image_modal"}
<div class="modal fade" id="{$image_modal['id']}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<p class="h2 modal-title">{$image_modal['title']}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
<img class="{$componentName}__img-popup img-fluid" src="{$image_modal['image_url']}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
data-bs-target="#product-customizations-modal-{$customization.id_customization}"
data-bs-toggle="modal"
data-bs-dismiss="modal"
>
{l s='Back' d='Shop.Theme.Global'}
</button>
</div>
</div>
</div>
</div>
{/foreach}
</div>
{/if}

View File

@@ -0,0 +1,155 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $facets|count}
<div id="search-filters" class="js-search-filters">
{block name='facets_title'}
<p class="text-uppercase h6 d-none d-sm-block d-md-block">{l s='Filter By' d='Shop.Theme.Actions'}</p>
{/block}
{block name='facets_clearall_button'}
{if $activeFilters|count}
<div id="_desktop_search_filters_clear_all" class="d-none d-sm-block d-md-block clear-all-wrapper">
<button data-search-url="{$clear_all_link}" class="btn btn-tertiary js-search-filters-clear-all">
<i class="material-icons" aria-hidden="true">&#xE14C;</i>
{l s='Clear all' d='Shop.Theme.Actions'}
</button>
</div>
{/if}
{/block}
{foreach from=$facets item="facet"}
{if !$facet.displayed}
{continue}
{/if}
<section class="facet">
<p class="h6 facet-title d-none d-sm-block d-md-block">{$facet.label}</p>
{assign var=_expand_id value=10|mt_rand:100000}
{assign var=_collapse value=true}
{foreach from=$facet.filters item="filter"}
{if $filter.active}{assign var=_collapse value=false}{/if}
{/foreach}
<div class="title d-none d-sm-block d-md-none" data-target="#facet_{$_expand_id}" data-bs-toggle="collapse"{if !$_collapse} aria-expanded="true"{/if}>
<p class="h6 facet-title">{$facet.label}</p>
<span>
<span class="navbar-toggler collapse-icons">
<i class="material-icons add">&#xE313;</i>
<i class="material-icons remove">&#xE316;</i>
</span>
</span>
</div>
{if $facet.widgetType !== 'dropdown'}
{block name='facet_item_other'}
<ul id="facet_{$_expand_id}" class="collapse{if !$_collapse} in{/if}">
{foreach from=$facet.filters key=filter_key item="filter"}
{if !$filter.displayed}
{continue}
{/if}
<li>
<label class="facet-label{if $filter.active} active {/if}" for="facet_input_{$_expand_id}_{$filter_key}">
{if $facet.multipleSelectionAllowed}
<span class="custom-checkbox">
<input
id="facet_input_{$_expand_id}_{$filter_key}"
data-search-url="{$filter.nextEncodedFacetsURL}"
type="checkbox"
{if $filter.active }checked{/if}
>
{if isset($filter.properties.texture)}
<span class="color texture" style="background-image:url({$filter.properties.texture})"></span>
{elseif isset($filter.properties.color)}
<span class="color" style="background-color:{$filter.properties.color}"></span>
{else}
<span {if !$js_enabled} class="ps-shown-by-js" {/if}><i class="material-icons rtl-no-flip checkbox-checked">&#xE5CA;</i></span>
{/if}
</span>
{else}
<span class="custom-radio">
<input
id="facet_input_{$_expand_id}_{$filter_key}"
data-search-url="{$filter.nextEncodedFacetsURL}"
type="radio"
name="filter {$facet.label}"
{if $filter.active }checked{/if}
>
<span {if !$js_enabled} class="ps-shown-by-js" {/if}></span>
</span>
{/if}
<a
href="{$filter.nextEncodedFacetsURL}"
class="_gray-darker search-link js-search-link"
rel="nofollow"
>
{$filter.label}
{if $filter.magnitude}
<span class="magnitude">({$filter.magnitude})</span>
{/if}
</a>
</label>
</li>
{/foreach}
</ul>
{/block}
{else}
{block name='facet_item_dropdown'}
<ul id="facet_{$_expand_id}" class="collapse{if !$_collapse} in{/if}">
<li>
<div class="facet-dropdown dropdown">
<a class="select-title" rel="nofollow" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{$active_found = false}
<span>
{foreach from=$facet.filters item="filter"}
{if $filter.active}
{$filter.label}
{if $filter.magnitude}
({$filter.magnitude})
{/if}
{$active_found = true}
{/if}
{/foreach}
{if !$active_found}
{l s='(no filter)' d='Shop.Theme.Global'}
{/if}
</span>
<i class="material-icons" aria-hidden="true">&#xE5C5;</i>
</a>
<div class="dropdown-menu dropdown-menu-start">
{foreach from=$facet.filters item="filter"}
{if !$filter.active}
<a
rel="nofollow"
href="{$filter.nextEncodedFacetsURL}"
class="dropdown-item select-list"
>
{$filter.label}
{if $filter.magnitude}
({$filter.magnitude})
{/if}
</a>
{/if}
{/foreach}
</div>
</div>
</li>
</ul>
{/block}
{/if}
</section>
{/foreach}
</div>
{/if}

View File

@@ -0,0 +1,38 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='brand_miniature_item'}
<li class="brand">
<div class="brand__image">
<picture>
{if !empty($brand.image.bySize.small_default.sources.avif)}<source srcset="{$brand.image.bySize.small_default.sources.avif}" type="image/avif">{/if}
{if !empty($brand.image.bySize.small_default.sources.webp)}<source srcset="{$brand.image.bySize.small_default.sources.webp}" type="image/webp">{/if}
<img
class="brand__img img-fluid"
src="{$brand.image.bySize.small_default.url}"
alt="{if !empty($brand.image.legend)}{$brand.image.legend}{else}{$brand.name}{/if}"
width="{$brand.image.bySize.small_default.width}"
height="{$brand.image.bySize.small_default.height}"
loading="lazy"
>
</picture>
</div>
<div class="brand__infos">
<a class="brand__title stretched-link" href="{$brand.url}">
{$brand.name}
</a>
</div>
<p class="brand__products">
{if $brand.nb_products > 1}
{l s='%number% products' sprintf=['%number%' => $brand.nb_products] d='Shop.Theme.Catalog'}
{elseif $brand.nb_products == 1}
{l s='%number% product' sprintf=['%number%' => $brand.nb_products] d='Shop.Theme.Catalog'}
{else}
{l s='No products' d='Shop.Theme.Catalog'}
{/if}
</p>
</li>
{/block}

View File

@@ -0,0 +1,23 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='category_miniature_item'}
<section class="category-miniature">
<a href="{$category.url}">
<img
src="{$category.image.medium.url}"
alt="{if !empty($category.image.legend)}{$category.image.legend}{else}{$category.name}{/if}"
loading="lazy"
width="250"
height="250"
>
</a>
<h1 class="h4">
<a href="{$category.url}">{$category.name}</a>
</h1>
<div class="category-description">{$category.description nofilter}</div>
</section>
{/block}

View File

@@ -0,0 +1,87 @@
{block name='product_miniature_image'}
<div class="{$componentName}__image-container thumbnail-container">
<a href="{$product.url}" class="{$componentName}__image-link outline outline--rounded">
{if $product.cover}
<picture>
{if isset($product.cover.bySize.default_md.sources.avif)}
<source
srcset="
{$product.cover.bySize.default_sm.sources.avif} 216w,
{$product.cover.bySize.default_md.sources.avif} 261w,
{$product.cover.bySize.default_lg.sources.avif} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
type="image/avif"
>
{/if}
{if isset($product.cover.bySize.default_md.sources.webp)}
<source
srcset="
{$product.cover.bySize.default_sm.sources.webp} 216w,
{$product.cover.bySize.default_md.sources.webp} 261w,
{$product.cover.bySize.default_lg.sources.webp} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
type="image/webp"
>
{/if}
<img
class="{$componentName}__image"
srcset="
{$product.cover.bySize.default_sm.url} 216w,
{$product.cover.bySize.default_md.url} 261w,
{$product.cover.bySize.default_lg.url} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
src="{$product.cover.bySize.default_md.url}"
width="{$product.cover.bySize.default_md.width}"
height="{$product.cover.bySize.default_md.height}"
loading="lazy"
alt="{$product.cover.legend}"
title="{$product.cover.legend}"
data-full-size-image-url="{$product.cover.bySize.home_default.url}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_md.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_sm.sources.avif} 216w,
{$urls.no_picture_image.bySize.default_md.sources.avif} 261w,
{$urls.no_picture_image.bySize.default_lg.sources.avif} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_md.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_sm.sources.webp} 216w,
{$urls.no_picture_image.bySize.default_md.sources.webp} 261w,
{$urls.no_picture_image.bySize.default_lg.sources.webp} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
type="image/webp"
>
{/if}
<img
class="{$componentName}__image"
srcset="
{$urls.no_picture_image.bySize.default_sm.url} 216w,
{$urls.no_picture_image.bySize.default_md.url} 261w,
{$urls.no_picture_image.bySize.default_lg.url} 336w"
sizes="(min-width: 992px) 25vw, (min-width: 360px) 50vw, 100vw"
width="{$urls.no_picture_image.bySize.default_md.width}"
height="{$urls.no_picture_image.bySize.default_md.height}"
src="{$urls.no_picture_image.bySize.default_md.url}"
loading="lazy"
alt="{l s='No image available' d='Shop.Theme.Catalog'}"
title="{l s='No image available' d='Shop.Theme.Catalog'}"
data-full-size-image-url="{$urls.no_picture_image.bySize.home_default.url}"
>
</picture>
{/if}
</a>
</div>
{/block}

View File

@@ -0,0 +1,98 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='pack_miniature_item'}
<article class="product-pack__item">
<a href="{$product.url}"
class="product-pack__link"
aria-labelledby="pack-product-{$product.id_product}"
>
<span class="product-pack__image-wrapper">
{if !empty($product.default_image)}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="product-pack__image img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
src="{$product.default_image.bySize.default_xs.url}"
loading="lazy"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
alt="{$product.default_image.legend}"
title="{$product.default_image.legend}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="product-pack__image img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
src="{$urls.no_picture_image.bySize.default_xs.url}"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
</span>
<span class="product-pack__name">
{$product.name}
</span>
{if $showPackProductsPrice}
<span class="product-pack__price">
{$product.price}
</span>
{/if}
<span class="product-pack__quantity">
x{$product.pack_quantity}
</span>
<span id="pack-product-{$product.id_product}" class="visually-hidden">
{l s='View product %product_name%, part of the pack.' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Catalog'} {l s='Quantity inside the pack: %quantity%.' sprintf=['%quantity%' => $product.pack_quantity] d='Shop.Theme.Catalog'} {if $showPackProductsPrice}{l s='Price: %price%.' sprintf=['%price%' => $product.price] d='Shop.Theme.Catalog'}{/if}
</span>
</a>
</article>
{/block}

View File

@@ -0,0 +1,17 @@
{block name='quick_view'}
<button class="{$componentName}__quickview-button btn btn-tertiary btn-square-icon outline js-quickview"
data-ps-action="open-quickview"
data-ps-ref="quickview-button"
aria-label="{l s='Quick view %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE417;</i>
{l s='Quick view' d='Shop.Theme.Actions'}
</button>
{/block}
{block name='quick_view_touch'}
<button class="{$componentName}__quickview-touch btn btn-tertiary btn-square-icon js-quickview"
data-ps-action="open-quickview"
aria-label="{l s='Quick view %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}">
<i class="material-icons">&#xE417;</i>
</button>
{/block}

View File

@@ -0,0 +1,114 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'product-miniature'}
{block name='product_miniature_item'}
<article
class="{$componentName} js-{$componentName}"
data-id-product="{$product.id_product}"
data-id-product-attribute="{$product.id_product_attribute}"
>
<div class="{$componentName}__inner">
{block name='product_miniature_top'}
<div class="{$componentName}__top">
{include file='catalog/_partials/product-flags.tpl'}
{include file='catalog/_partials/miniatures/product-image.tpl'}
{include file='catalog/_partials/miniatures/product-quickview.tpl'}
</div>
{/block}
{block name='product_miniature_bottom'}
<div class="{$componentName}__bottom">
<div class="{$componentName}__infos">
{block name='product_name'}
<a class="{$componentName}__title" href="{$product.url}" aria-label="{l s='View product %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Catalog'}">{$product.name}</a>
{/block}
{block name='product_variants'}
{if $product.main_variants}
<div class="{$componentName}__variants">
{include file='catalog/_partials/variant-links.tpl' variants=$product.main_variants}
</div>
{/if}
{/block}
{if $product.show_price}
<div class="{$componentName}__prices">
{block name='product_price'}
{hook h='displayProductPriceBlock' product=$product type="before_price"}
<div class="{$componentName}__price" aria-label="{l s='Price' d='Shop.Theme.Catalog'}">
{capture name='custom_price'}{hook h='displayProductPriceBlock' product=$product type='custom_price' hook_origin='products_list'}{/capture}
{if '' !== $smarty.capture.custom_price}
{$smarty.capture.custom_price nofilter}
{else}
{$product.price}
{/if}
</div>
{hook h='displayProductPriceBlock' product=$product type='unit_price'}
{hook h='displayProductPriceBlock' product=$product type='weight'}
{/block}
{block name='product_discount_price'}
{if $product.show_price}
<div class="{$componentName}__discount-price">
{if $product.has_discount}
{hook h='displayProductPriceBlock' product=$product type="old_price"}
<span class="{$componentName}__regular-price" aria-label="{l s='Regular price' d='Shop.Theme.Catalog'}">{$product.regular_price}</span>
{/if}
</div>
{/if}
{/block}
</div>
{/if}
{block name='product_reviews'}
{hook h='displayProductListReviews' product=$product}
{/block}
</div>
<div class="{$componentName}__actions">
{if $product.add_to_cart_url}
<form class="{$componentName}__form" action="{$urls.pages.cart}" method="post">
<input type="hidden" value="{$product.id_product}" name="id_product">
<input type="hidden" name="token" value="{$static_token}">
<div class="quantity-button js-quantity-button">
{include file='components/qty-input.tpl'
attributes=[
"id" => "quantity_wanted_{$product.id_product}",
"value" => "{$product.quantity_wanted}",
"min" => "{$product.quantity_required}"
]
}
</div>
<button
data-button-action="add-to-cart"
class="product-miniature__add btn btn-primary btn-square-icon"
aria-label="{l s='Add to cart %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}"
title="{l s='Add to cart %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}"
data-ps-ref="add-to-cart"
>
<i class="material-icons" aria-hidden="true">&#xe854;</i>
<span class="product-miniature__add-text">{l s='Add to cart' d='Shop.Theme.Actions'}</span>
</button>
</form>
{else}
<a href="{$product.url}" class="product-miniature__details btn btn-outline-primary" aria-label="{l s='View product %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Catalog'}">
{l s='See details' d='Shop.Theme.Actions'}
</a>
{/if}
</div>
</div>
{/block}
</div>
</article>
{/block}

View File

@@ -0,0 +1,38 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='supplier_miniature_item'}
<li class="supplier">
<div class="supplier__image">
<picture>
{if !empty($supplier.image.bySize.small_default.sources.avif)}<source srcset="{$supplier.image.bySize.small_default.sources.avif}" type="image/avif">{/if}
{if !empty($supplier.image.bySize.small_default.sources.webp)}<source srcset="{$supplier.image.bySize.small_default.sources.webp}" type="image/webp">{/if}
<img
class="supplier__img img-fluid"
src="{$supplier.image.bySize.small_default.url}"
alt="{if !empty($supplier.image.legend)}{$supplier.image.legend}{else}{$supplier.name}{/if}"
width="{$supplier.image.bySize.small_default.width}"
height="{$supplier.image.bySize.small_default.height}"
loading="lazy"
>
</picture>
</div>
<div class="supplier__infos">
<a class="supplier__title stretched-link" href="{$supplier.url}">
{$supplier.name}
</a>
</div>
<p class="supplier__products">
{if $supplier.nb_products > 1}
{l s='%number% products' sprintf=['%number%' => $supplier.nb_products] d='Shop.Theme.Catalog'}
{elseif $supplier.nb_products == 1}
{l s='%number% product' sprintf=['%number%' => $supplier.nb_products] d='Shop.Theme.Catalog'}
{else}
{l s='No products' d='Shop.Theme.Catalog'}
{/if}
</p>
</li>
{/block}

View File

@@ -0,0 +1,16 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file="components/module-products.tpl"}
{block name='module_products_variables'}
{assign var="products" value=$accessories}
{assign var="need_container" value=false}
{/block}
{block name='module_products_name'}product__accessories{/block}
{block name='module_products_title'}
{include file='components/section-title.tpl' title={l s='You might also like' d='Shop.Theme.Catalog'}}
{/block}

View File

@@ -0,0 +1,17 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $page.admin_notifications}
<div class="alert alert-warning" role="alert">
<div class="container">
{foreach $page.admin_notifications as $notif}
<div>
<i class="material-icons" aria-hidden="true">&#xE001;</i>
<p class="alert-text">{$notif.message}</p>
</div>
{/foreach}
</div>
</div>
{/if}

View File

@@ -0,0 +1,111 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if !$configuration.is_catalog}
<div class="product__add-to-cart-container product-add-to-cart js-product-add-to-cart">
{block name='product_availability'}
<div
id="product-availability"
class="product__availability js-product-availability"
{if empty($product.availability_message) && empty($product.delivery_information)}
hidden
{/if}
>
{if !empty($product.availability_message)}
{** First, we prepare the icons and colors we want to use *}
{if $product.availability == 'in_stock'}
{assign 'availability_icon' 'E5CA'}
{assign 'availability_class' 'text-success'}
{elseif $product.availability == 'available'}
{assign 'availability_icon' 'E002'}
{assign 'availability_class' 'text-warning'}
{elseif $product.availability == 'last_remaining_items'}
{assign 'availability_icon' 'E002'}
{assign 'availability_class' 'text-warning'}
{else}
{assign 'availability_icon' 'E14B'}
{assign 'availability_class' 'text-danger'}
{/if}
{** And render the availability message with icon *}
<div class="product__availability-status {$availability_class}" aria-live="off" data-ps-ref="product-availability">
<i class="product__availability-icon material-icons rtl-no-flip">&#x{$availability_icon};</i>
<div class="product__availability-messages">
<span class="visually-hidden">{l s='Product availability:' d='Shop.Theme.Global'}</span>
<span>{$product.availability_message}</span>
{if !empty($product.availability_submessage)}
<small class="d-block">{$product.availability_submessage}</small>
{/if}
</div>
</div>
{/if}
{block name='product_delivery_times'}
{if !empty($product.delivery_information)}
<div class="product__delivery-infos">{$product.delivery_information}</div>
{/if}
{/block}
</div>
{/block}
{block name='product_quantity'}
{* .product-quantity needed for JS *}
<div class="product__actions-qty-add product-quantity">
<div class="product-actions__quantity product__quantity quantity-button js-quantity-button">
{include file='components/qty-input.tpl'
attributes=[
"id" => "quantity_wanted",
"class" => "form-control js-quantity-wanted",
"value" => "{$product.quantity_wanted}",
"min" => "{$product.quantity_required}"
]
}
</div>
<div class="product__add-to-cart add">
<button
class="product__add-to-cart-button btn btn-primary"
data-button-action="add-to-cart"
type="submit"
{if !$product.add_to_cart_url}
aria-disabled="true"
disabled
{/if}
data-ps-ref="add-to-cart"
aria-label="{l s='Add to cart %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}"
title="{l s='Add to cart %product_name%' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Actions'}"
>
<i class="material-icons" aria-hidden="true">&#xE547;</i>
{l s='Add to cart' d='Shop.Theme.Actions'}
</button>
</div>
{capture name='product_actions'}{hook h='displayProductActions' product=$product}{/capture}
{if $smarty.capture.product_actions}
{$smarty.capture.product_actions nofilter}
{/if}
</div>
{/block}
{block name='product_minimal_quantity'}
<div
class="product__minimal-quantity product-minimal-quantity js-product-minimal-quantity"
{if $product.minimal_quantity <= 1}
hidden
{/if}
>
{if $product.minimal_quantity > 1}
<i class="material-icons" aria-hidden="true">&#xE88F;</i>
{l
s='The minimum purchase order quantity for the product is %quantity%.'
d='Shop.Theme.Checkout'
sprintf=['%quantity%' => $product.minimal_quantity]
}
{/if}
</div>
{/block}
</div>
{/if}

View File

@@ -0,0 +1,7 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="product__additional-info js-product-additional-info">
{hook h='displayProductAdditionalInfo' product=$product}
</div>

View File

@@ -0,0 +1,178 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="product__images js-images-container">
{if $product.images|@count > 0}
<div
id="product-images-{$product.id}"
class="product__carousel carousel slide js-product-carousel"
>
{include file='catalog/_partials/product-flags.tpl'}
<div class="carousel-inner">
{block name='product_cover'}
{foreach from=$product.images item=image key=key name=productImages}
<div class="carousel-item{if $image.id_image == $product.default_image.id_image} active{/if}">
<picture>
{if isset($image.bySize.default_xl.sources.avif)}
<source
srcset="
{$image.bySize.default_xl.sources.avif} 400w,
{$image.bySize.product_main.sources.avif} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
type="image/avif"
>
{/if}
{if isset($image.bySize.default_xl.sources.webp)}
<source
srcset="
{$image.bySize.default_xl.sources.webp} 400w,
{$image.bySize.product_main.sources.webp} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
type="image/webp"
>
{/if}
<img
class="img-fluid w-100"
srcset="
{$image.bySize.default_xl.url} 400w,
{$image.bySize.product_main.url} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
src="{$image.bySize.product_main.url}"
width="{$image.bySize.product_main.width}"
height="{$image.bySize.product_main.height}"
{if $smarty.foreach.productImages.first}
fetchpriority="high"
{else}
loading="lazy"
{/if}
alt="{$image.legend}"
title="{$image.legend}"
data-full-size-image-url="{$image.bySize.home_default.url}"
>
</picture>
</div>
{/foreach}
{/block}
</div>
{if $product.images|@count > 1}
<button class="carousel-control-prev outline outline--rounded" type="button" data-bs-target="#product-images-{$product.id}" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">{l s='Previous image' d='Shop.Theme.Global'}</span>
</button>
<button class="carousel-control-next outline outline--rounded" type="button" data-bs-target="#product-images-{$product.id}" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">{l s='Next image' d='Shop.Theme.Global'}</span>
</button>
{/if}
{block name='product_images_modal_button'}
<button class="product__zoom btn btn-tertiary outline outline--rounded btn-square-icon" data-bs-toggle="modal" data-bs-target="#product-modal" aria-label="{l s='Open zoomed product image gallery' d='Shop.Theme.Global'}" title="{l s='Open zoomed product image gallery' d='Shop.Theme.Global'}">
<i class="material-icons">&#xE8B6;</i>
</button>
{/block}
</div>
{block name='product_images'}
<div class="product__thumbnails">
<ul class="product__thumbnails-list">
{foreach from=$product.images item=image key=key name=productThumbnails}
<button
class="product__thumbnail focus-ring js-thumb-container{if $image.id_image == $product.default_image.id_image} active{/if}"
data-bs-target="#product-images-{$product.id}"
data-bs-slide-to="{$key}"
{if $image.id_image == $product.default_image.id_image}
aria-current="true"
{/if}
aria-label="{l s='Slide to product image %number%' d='Shop.Theme.Catalog' sprintf=['%number%' => $key + 1]}"
>
<picture>
{if isset($image.bySize.default_xs.sources.avif)}
<source
srcset="
{$image.bySize.default_xs.sources.avif},
{$image.bySize.default_xl.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($image.bySize.default_xs.sources.webp)}
<source
srcset="
{$image.bySize.default_xs.sources.webp},
{$image.bySize.default_xl.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="product__thumbnail-image outline outline--rounded img-fluid js-thumb{if $image.id_image == $product.default_image.id_image} js-thumb-selected{/if}"
srcset="
{$image.bySize.default_xs.url},
{$image.bySize.default_xl.url} 2x"
width="{$image.bySize.default_xs.width}"
height="{$image.bySize.default_xs.height}"
loading="lazy"
alt="{$image.legend}"
title="{$image.legend}"
>
</picture>
</button>
{/foreach}
</ul>
</div>
{/block}
{hook h='displayAfterProductThumbs' product=$product}
{else}
<div class="product__no-image">
{include file='catalog/_partials/product-flags.tpl'}
<picture>
{if isset($urls.no_picture_image.bySize.default_xl.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xl.sources.avif} 400w,
{$urls.no_picture_image.bySize.product_main.sources.avif} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xl.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xl.sources.webp} 400w,
{$urls.no_picture_image.bySize.product_main.sources.webp} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
type="image/webp"
>
{/if}
<img
class="img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xl.url} 400w,
{$urls.no_picture_image.bySize.product_main.url} 720w"
sizes="(min-width: 992px) 50vw, (min-width: 360px) 33vw, 100vw"
width="{$urls.no_picture_image.bySize.product_main.width}"
height="{$urls.no_picture_image.bySize.product_main.height}"
src="{$urls.no_picture_image.bySize.default_xl.url}"
loading="lazy"
alt="{l s='No image available' d='Shop.Theme.Catalog'}"
title="{l s='No image available' d='Shop.Theme.Catalog'}"
>
</picture>
</div>
{/if}
{block name='product_images_modal'}
{include file='catalog/_partials/product-images-modal.tpl'}
{/block}
</div>

View File

@@ -0,0 +1,97 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'product-customization-modal'}
<div class="{$componentName}__content">
{assign var=customization_modal_id value="{$componentName}--{$product.id_customization|intval}"}
<div class="modal fade" id="{$customization_modal_id}" tabindex="-1" aria-hidden="true" aria-labelledby="customizations-modal-{$product.id_customization}-title">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<p class="h2 modal-title" id="customizations-modal-{$product.id_customization}-title">{l s='Product customization' d='Shop.Theme.Checkout'}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
{assign var=image_modals value=[]}
{foreach from=$product.customizations item="customization"}
{foreach from=$customization.fields item="field"}
<div class="{$componentName}__line">
<p class="{$componentName}__label">{$field.label}</p>
{if $field.type == 'text'}
<div class="{$componentName}__text">
{if $field.id_module|intval}
{$field.text nofilter}
{else}
{$field.text}
{/if}
</div>
{elseif $field.type == 'image'}
{assign var=image_modal_id value="{$componentName}_image--{mt_rand()}"}
<a href="#{$image_modal_id}" data-bs-toggle="modal" data-bs-dismiss="modal" >
<img class="{$componentName}__img" src="{$field.image.small.url}">
</a>
{append var='image_modals'
value=[
"id"=>$image_modal_id,
"title"=>$field.label,
"image_url"=>$field.image.large.url,
"back_id"=>$customization_modal_id
]
}
{/if}
</div>
{/foreach}
{/foreach}
</div>
</div>
</div>
</div>
{if isset($image_modals) && count($image_modals)}
<div class="{$componentName}__popup">
{foreach from=$image_modals item="image_modal"}
<div class="modal fade" id="{$image_modal['id']}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<p class="h2 modal-title">{$image_modal['title']}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
<img class="{$componentName}__img-popup img-fluid" src="{$image_modal['image_url']}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
data-bs-target="#{$image_modal['back_id']}"
data-bs-toggle="modal"
data-bs-dismiss="modal"
>
{l s='Back' d='Shop.Theme.Global'}
</button>
</div>
</div>
</div>
</div>
{/foreach}
</div>
{/if}
<button type="button" class="btn btn-sm btn-outline-primary"
data-bs-toggle="modal"
data-bs-target="#{$customization_modal_id}"
aria-label="{l s='View my customization' d='Shop.Theme.Checkout'}"
>
{l s='Customized' d='Shop.Theme.Checkout'}
</button>
</div>

View File

@@ -0,0 +1,59 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if !$configuration.is_catalog}
<section class="product__customization product-customization js-product-customization">
<p class="product-customization__title h4">{l s='Product customization' d='Shop.Theme.Catalog'}</p>
{block name='product_customization_form'}
<form method="post" action="{$product.url}" enctype="multipart/form-data" class="mb-0">
{foreach from=$customizations.fields item="field"}
<div class="product-customization__item">
<label class="product-customization__label form-label {if $field.required}required{/if}" for="field-{$field.id_customization_field}">{$field.label}</label>
<div class="product-customization__field">
{if $field.type === 'text'}
<textarea placeholder="{l s='Your message here' d='Shop.Forms.Help'}" class="form-control product-message" maxlength="250" {if $field.required} required {/if} name="{$field.input_name}" id="field-{$field.id_customization_field}"></textarea>
{if $field.text !== ''}
<div class="product-customization__message">
<b>{l s='Your customization:' d='Shop.Theme.Catalog'}</b> {$field.text}
</div>
{/if}
{elseif $field.type === 'image'}
<input class="form-control file-input js-file-input" {if $field.required} required {/if} type="file" name="{$field.input_name}" id="field-{$field.id_customization_field}">
{if $field.is_customized}
<div class="product-customization__image-wrapper">
<img src="{$field.image.small.url}" class="product-customization__image img-fluid" loading="lazy">
<a class="product-customization__image-remove link-danger" href="{$field.remove_image_url}" rel="nofollow" role="button">
{l s='Remove image' d='Shop.Theme.Actions'}
</a>
</div>
{/if}
{/if}
</div>
<div class="product-customization__field-footer">
{if $field.type === 'text'}
<small class="form-text">{l s='250 char. max' d='Shop.Forms.Help'}</small>
{elseif $field.type === 'image'}
<small class="form-text">{l s='.png .jpg .gif' d='Shop.Forms.Help'}</small>
{/if}
{if !$field.required}
<small class="form-text">{l s='Optional' d='Shop.Forms.Help'}</small>
{/if}
</div>
</div>
{/foreach}
<div class="product-customization__action">
<button class="btn btn-primary" type="submit" name="submitCustomizedData">{l s='Save customization' d='Shop.Theme.Actions'}</button>
</div>
</form>
{/block}
{/if}
</section>

View File

@@ -0,0 +1,149 @@
<div
class="js-product-details"
data-product="{$product.embedded_attributes|json_encode}"
>
<div class="accordion-item" id="product_details">
<h2 class="accordion-header" id="product_details_heading">
<button class="accordion-button {if $product.description}collapsed{/if}" type="button" data-bs-toggle="collapse" data-bs-target="#product_details_collapse" aria-expanded="{if !$product.description}true{else}false{/if}"
aria-controls="product_details_collapse">
{l s='Product Details' d='Shop.Theme.Catalog'}
</button>
</h2>
<div id="product_details_collapse" class="accordion-collapse collapse {if !$product.description}show{/if}" aria-labelledby="product_details_heading">
<div class="accordion-body">
<ul class="details__list">
{block name='product_manufacturer'}
{if isset($product_manufacturer->id)}
<li class="details__item details__item--manufacturer">
<div class="details__left">
<span class="details__title">{l s='Brand' d='Shop.Theme.Catalog'}</span>
</div>
<div class="details__right">
{if isset($product_manufacturer.image.bySize.small_default.url)}
<a href="{$product_manufacturer->url}">
<img src="{$product_manufacturer.image.bySize.small_default.url}"
class="img-fluid details__manufacturer-logo"
alt="{$product_manufacturer->name}"
loading="lazy"
width="{$product_manufacturer.image.bySize.small_default.width}"
height="{$product_manufacturer.image.bySize.small_default.height}"
aria-label="{l s='Brand: %brand_name%' sprintf=['%brand_name%' => $product_manufacturer->name] d='Shop.Theme.Catalog'}"
>
</a>
{else}
<a href="{$product_manufacturer->url}">{$product_manufacturer->name}</a>
{/if}
</div>
</li>
{/if}
{/block}
{block name='product_reference'}
{if !empty($product.reference_to_display)}
<li class="details__item details__item--reference">
<div class="details__left">
<span class="details__title">{l s='Reference' d='Shop.Theme.Catalog'}</span>
</div>
<div class="details__right">
<span>{$product.reference_to_display}</span>
</div>
</li>
{/if}
{/block}
{block name='product_quantities'}
{if $product.show_quantities}
<li class="details__item details__item--quantities">
<div class="details__left">
<span class="details__title">{l s='In stock' d='Shop.Theme.Catalog'}</span>
</div>
<div class="details__right">
<span data-stock="{$product.quantity}" data-allow-oosp="{$product.allow_oosp}">{$product.quantity} {$product.quantity_label}</span>
</div>
</li>
{/if}
{/block}
{block name='product_availability_date'}
{if $product.availability_date}
<li class="details__item details__item--availability-date">
<div class="details__left">
<span class="details__title">{l s='Availability date' d='Shop.Theme.Catalog'}</span>
</div>
<div class="details__right">
<span>{$product.availability_date}</span>
</div>
</li>
{/if}
{/block}
{* if product have specific references, a table will be added to product details section *}
{block name='product_condition'}
{if $product.condition}
<li class="details__item details__item--condition">
<div class="details__left">
<span class="details__title">{l s='Condition' d='Shop.Theme.Catalog'}</span>
</div>
<div class="details__right">
<span>{$product.condition.label}</span>
</div>
</li>
{/if}
{/block}
{block name='product_specific_references'}
{if !empty($product.specific_references)}
{foreach from=$product.specific_references item=reference key=key}
<li class="details__item details__item--{$key|classname}">
<div class="details__left">
<span class="details__title">{$key}</span>
</div>
<div class="details__right">
<span>{$reference}</span>
</div>
</li>
{/foreach}
{/if}
{/block}
</ul>
</div>
</div>
</div>
{block name='product_features'}
{if $product.grouped_features}
<div class="accordion-item" id="product_features">
<h2 class="accordion-header" id="product_features_heading">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#product_features_collapse" aria-expanded="false" aria-controls="product_features_collapse">
{l s='Data sheet' d='Shop.Theme.Catalog'}
</button>
</h2>
<div id="product_features_collapse" class="accordion-collapse collapse" aria-labelledby="product_features_heading">
<div class="accordion-body">
<ul class="details__list">
{foreach from=$product.grouped_features item=feature}
<li class="details__item details__item--feature">
<div class="details__left">
<span class="details__title">{$feature.name}</span>
</div>
<div class="details__right">
<span>{$feature.value|escape:'htmlall'|nl2br nofilter}</span>
</div>
</li>
{/foreach}
</ul>
</div>
</div>
</div>
{/if}
{/block}
</div>

View File

@@ -0,0 +1,33 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<section class="product__discounts js-product-discounts"
{if !$product.show_price || !$product.quantity_discounts|count}
hidden
{/if}
>
{if $product.quantity_discounts}
{block name='product_discount_table'}
<table class="discounts-table">
<thead>
<tr>
<th>{l s='Quantity' d='Shop.Theme.Catalog'}</th>
<th>{$configuration.quantity_discount.label}</th>
<th>{l s='You Save' d='Shop.Theme.Catalog'}</th>
</tr>
</thead>
<tbody>
{foreach from=$product.quantity_discounts item='quantity_discount' name='quantity_discounts'}
<tr data-discount-type="{$quantity_discount.reduction_type}" data-discount="{$quantity_discount.real_value}" data-discount-quantity="{$quantity_discount.quantity}">
<td>{$quantity_discount.quantity}</td>
<td>{$quantity_discount.discount}</td>
<td>{$quantity_discount.save}</td>
</tr>
{/foreach}
</tbody>
</table>
{/block}
{/if}
</section>

View File

@@ -0,0 +1,13 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if !empty($product.flags)}
{block name='product_flags'}
<ul class="product-flags js-product-flags">
{foreach from=$product.flags item=flag}
<li class="badge {$flag.type}">{$flag.label}</li>
{/foreach}
</ul>
{/block}
{/if}

View File

@@ -0,0 +1,79 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="product-images-modal modal fade js-product-images-modal" id="product-modal" tabindex="-1" aria-labelledby="product-modal-images-title" data-ps-ref="product-images-modal">
<div class="modal-dialog modal-xl modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<p class="h2 modal-title visually-hidden" id="product-modal-images-title">{$product.name} {l s='images' d='Shop.Theme.Catalog'}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="product-images-modal__body modal-body">
<div
id="product-images-modal-{$product.id}"
class="product-images-modal__carousel carousel slide js-product-images-modal-carousel"
data-ps-ref="product-images-modal-carousel"
>
<div class="carousel-inner">
{foreach from=$product.images item=image key=key name=productImages}
<div class="carousel-item{if $image.id_image == $product.default_image.id_image} active{/if}">
<picture>
{if isset($image.bySize.default_md.sources.avif)}
<source
srcset="
{$image.bySize.default_md.sources.avif} 320w,
{$image.bySize.product_main.sources.avif} 720w,
{$image.bySize.product_main_2x.sources.avif} 1440w"
sizes="(min-width: 1200px) 1440px, (min-width: 768px) 720px, 100vw"
type="image/avif"
>
{/if}
{if isset($image.bySize.default_md.sources.webp)}
<source
srcset="
{$image.bySize.default_md.sources.webp} 320w,
{$image.bySize.product_main.sources.webp} 720w,
{$image.bySize.product_main_2x.sources.webp} 1440w"
sizes="(min-width: 1200px) 1440px, (min-width: 768px) 720px, 100vw"
type="image/webp"
>
{/if}
<img
class="img-fluid"
srcset="
{$image.bySize.default_md.url} 320w,
{$image.bySize.product_main.url} 720w,
{$image.bySize.product_main_2x.url} 1440w"
sizes="(min-width: 1200px) 1440px, (min-width: 768px) 720px, 100vw"
src="{$image.bySize.product_main.url}"
width="{$image.bySize.product_main_2x.width}"
height="{$image.bySize.product_main_2x.height}"
loading="{if $smarty.foreach.productImages.first}eager{else}lazy{/if}"
alt="{$image.legend}"
title="{$image.legend}"
data-full-size-image-url="{$image.bySize.home_default.url}"
>
</picture>
</div>
{/foreach}
</div>
{if $product.images|@count > 1}
<button class="carousel-control-prev outline outline--rounded" type="button" data-bs-target="#product-images-modal-{$product.id}" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">{l s='Previous image' d='Shop.Theme.Global'}</span>
</button>
<button class="carousel-control-next outline outline--rounded" type="button" data-bs-target="#product-images-modal-{$product.id}" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">{l s='Next image' d='Shop.Theme.Global'}</span>
</button>
{/if}
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->

View File

@@ -0,0 +1,17 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $packItems}
<section class="product__pack">
<p class="h4">{l s='This pack contains' d='Shop.Theme.Catalog'}</p>
<div class="product-pack__list">
{foreach from=$packItems item="product_pack"}
{block name='product_miniature'}
{include file='catalog/_partials/miniatures/product-pack.tpl' product=$product_pack showPackProductsPrice=$product.show_price}
{/block}
{/foreach}
</div>
</section>
{/if}

View File

@@ -0,0 +1,95 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $product.show_price}
<div class="product__prices js-product-prices">
{block name='product_price'}
<div class="product__prices-block">
{if $product.has_discount}
<div class="product__discount-price product__prices-inline product__prices-inline--small-gap">
{hook h='displayProductPriceBlock' product=$product type="old_price"}
<span class="product__regular-price">
<span class="visually-hidden">{l s='Regular price: ' d='Shop.Theme.Catalog'}</span>
{$product.regular_price}
</span>
{if $product.discount_type === 'percentage'}
<span class="product__discount-percentage text-primary-emphasis">
({l s='Save %percentage%' d='Shop.Theme.Catalog' sprintf=['%percentage%' => $product.discount_percentage_absolute]})
</span>
{else}
<span class="product__discount-amount text-primary-emphasis">
({l s='Save %amount%' d='Shop.Theme.Catalog' sprintf=['%amount%' => $product.discount_to_display]})
</span>
{/if}
</div>
{/if}
<div class="product__prices-inline product__prices-inline--small-gap">
<div class="product__price">
{capture name='custom_price'}{hook h='displayProductPriceBlock' product=$product type='custom_price' hook_origin='product_sheet'}{/capture}
{if !empty($smarty.capture.custom_price)}
{$smarty.capture.custom_price nofilter}
{else}
<span class="visually-hidden">{l s='Price: ' d='Shop.Theme.Catalog'}</span>
{$product.price}
{/if}
</div>
{block name='product_unit_price'}
{if $displayUnitPrice}
<span class="product__unit-price">
{l s='(%unit_price%)' sprintf=['%unit_price%' => $product.unit_price_full] d='Shop.Theme.Catalog'}
</span>
{/if}
{/block}
</div>
{block name='product_pack_price'}
{if $displayPackPrice}
<span class="product__pack-price">
{l s='Instead of %price%' d='Shop.Theme.Catalog' sprintf=['%price%' => $noPackPrice]}
</span>
{/if}
{/block}
<div class="product__tax-infos">
<span class="product__tax-label">
{if !$configuration.taxes_enabled}
{l s='No tax' d='Shop.Theme.Catalog'}
{elseif $configuration.display_taxes_label}
{$product.labels.tax_long}
{/if}
{hook h='displayProductPriceBlock' product=$product type="price"}
{hook h='displayProductPriceBlock' product=$product type="after_price"}
</span>
{* Separator *}
{if $configuration.display_taxes_label && $product.ecotax.amount > 0}<span class="product__price-separator"> - </span>{/if}
{block name='product_ecotax'}
{if $product.ecotax.amount> 0}
<span class="product__ecotax-price">
{l s='Including %amount% for ecotax' d='Shop.Theme.Catalog' sprintf=['%amount%' => $product.ecotax.value]}
{if $product.has_discount}
{l s='(not impacted by the discount)' d='Shop.Theme.Catalog'}
{/if}
</span>
{/if}
{/block}
</div>
{block name='product_without_taxes'}
{if $priceDisplay == 2}
<span class="product__taxless-price">{l s='%price% tax excl.' d='Shop.Theme.Catalog' sprintf=['%price%' => $product.price_tax_exc]}</span>
{/if}
{/block}
</div>
{/block}
{hook h='displayProductPriceBlock' product=$product type="weight" hook_origin='product_sheet'}
</div>
{/if}

View File

@@ -0,0 +1,97 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if isset($groups) && $groups}
<div class="product__variants js-product-variants">
{foreach from=$groups key=id_attribute_group item=group}
{if !empty($group.attributes)}
{assign var=groupId value="group_{$id_attribute_group}_{$product.id}"}
{assign var=inputId value="input_{$id_attribute_group}_{$product.id}"}
{assign var=legendId value="legend_{$id_attribute_group}_{$product.id}"}
<fieldset class="product-variant">
<div class="product-variant__label">
<legend class="form-label product-variant__legend" id="{$legendId}">{$group.name}</legend>
<span class="selected-value product-variant__selected" aria-hidden="true">
{l s=': ' d='Shop.Theme.Catalog'}
{foreach from=$group.attributes key=id_attribute item=group_attribute}
{if $group_attribute.selected}{$group_attribute.name}{/if}
{/foreach}
</span>
</div>
{if $group.group_type == 'select'}
<select
class="form-select"
id="{$inputId}"
aria-labelledby="{$legendId}"
data-product-attribute="{$id_attribute_group}"
name="group[{$id_attribute_group}]">
{foreach from=$group.attributes key=id_attribute item=group_attribute}
<option value="{$id_attribute}" {if $group_attribute.selected} selected="selected"{/if}>{$group_attribute.name}</option>
{/foreach}
</select>
{elseif $group.group_type == 'color'}
<div id="{$groupId}" class="product-variant__colors" role="radiogroup" aria-labelledby="{$legendId}">
{foreach from=$group.attributes key=id_attribute item=group_attribute}
{assign var=inputId value="input_{$id_attribute_group}_{$id_attribute}_{$product.id}"}
{assign var=labelId value="label_{$id_attribute_group}_{$id_attribute}_{$product.id}"}
<div class="product-variant__color input-color">
<input
class="input-color__input"
type="radio"
id="{$inputId}"
data-product-attribute="{$id_attribute_group}"
name="group[{$id_attribute_group}]"
value="{$id_attribute}"
aria-labelledby="{$labelId}"
{if $group_attribute.selected} checked="checked" aria-checked="true"{/if}
>
<label
class="input-color__label{if $group_attribute.texture} input-color__label--texture{/if}{if $group_attribute.selected} input-color__label--active{/if}"
for="{$inputId}"
>
<span id="{$labelId}"
{if $group_attribute.texture}
class="color texture {if $group_attribute.selected}active{/if}" style="background-image: url({$group_attribute.texture})"
{elseif $group_attribute.html_color_code}
class="color {if $group_attribute.selected}active{/if}" style="background-color: {$group_attribute.html_color_code}"
{/if}
>
<span class="visually-hidden">{$group.group_name} - {$group_attribute.name}</span>
</span>
</label>
</div>
{/foreach}
</div>
{elseif $group.group_type == 'radio'}
<div id="{$groupId}" class="product-variant__radios" role="radiogroup" aria-labelledby="{$legendId}">
{foreach from=$group.attributes key=id_attribute item=group_attribute}
{assign var=inputId value="input_{$id_attribute_group}_{$id_attribute}_{$product.id}"}
{assign var=labelId value="label_{$id_attribute_group}_{$id_attribute}_{$product.id}"}
<div class="product-variant__radio form-check">
<input
class="form-check-input"
type="radio"
id="{$inputId}"
data-product-attribute="{$id_attribute_group}"
name="group[{$id_attribute_group}]"
value="{$id_attribute}"
aria-labelledby="{$labelId}"
{if $group_attribute.selected} checked="checked" aria-checked="true"{/if}
>
<label for="{$inputId}">
<span class="form-check-label" id="{$labelId}"><span class="visually-hidden">{$group.group_name} - </span>{$group_attribute.name}</span>
</label>
</div>
{/foreach}
</div>
{/if}
</fieldset>
{/if}
{/foreach}
</div>
{/if}

View File

@@ -0,0 +1,10 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="products">
{foreach from=$products item='product' key='position'}
{include file='catalog/_partials/miniatures/product.tpl' product=$product position=$position}
{/foreach}
</div>

View File

@@ -0,0 +1,6 @@
{*
* Classic theme doesn't use this subtemplate, feel free to do whatever you need here.
* This template is generated at each ajax calls.
* See ProductListingFrontController::getAjaxProductSearchVariables()
*}
<div id="js-product-list-bottom"></div>

View File

@@ -0,0 +1,28 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="js-product-list-top">
<div class="products__selection">
<div class="products__count">
{if $listing.pagination.total_items> 1}
<span>{l s='There are %product_count% products.' d='Shop.Theme.Catalog' sprintf=['%product_count%' => $listing.pagination.total_items]}</span>
{elseif $listing.pagination.total_items> 0}
<span>{l s='There is 1 product.' d='Shop.Theme.Catalog'}</span>
{/if}
</div>
<div class="products__sort">
{block name='sort_by'}
{include file='catalog/_partials/sort-orders.tpl' sort_orders=$listing.sort_orders}
{/block}
{if !empty($listing.rendered_facets) && !isset($page.body_classes['layout-full-width'])}
<button id="search_filter_toggler" class="products__filter-button btn btn-outline-primary js-search-toggler" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-faceted">
<i class="material-icons" aria-hidden="true">&#xE152;</i>
{l s='Filter' d='Shop.Theme.Actions'}
</button>
{/if}
</div>
</div>
</div>

View File

@@ -0,0 +1,13 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="js-product-list">
{include file='catalog/_partials/productlist.tpl' products=$listing.products}
{block name='pagination'}
<div class="products__pagination">
{include file='_partials/pagination.tpl' pagination=$listing.pagination}
</div>
{/block}
</div>

View File

@@ -0,0 +1,91 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="quickview-modal-{$product.id}-{$product.id_product_attribute}" class="modal fade quickview in" tabindex="-1" role="dialog" aria-hidden="true" data-id-product="{$product.id}" data-ps-ref="quickview-modal" aria-labelledby="quickview-modal-{$product.id}-title">
<div class="quickview__dialog modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="quickview__content modal-content">
<div class="quickview__header modal-header">
<p class="h2 modal-title visually-hidden" id="quickview-modal-{$product.id}-title">{$product.name} {l s='quick view' d='Shop.Theme.Catalog'}</p>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
{* For screen readers *}
<p class="visually-hidden" aria-live="polite" role="status" data-ps-target="quickview-modal-status" data-ps-data="{l s='%product_name% quick view.' sprintf=['%product_name%' => $product.name] d='Shop.Theme.Checkout'}"></p>
</div>
<div class="quickview__body modal-body page-product page-product--quickview">
<div class="product__left">
{block name='product_cover_thumbnails'}
{include file='catalog/_partials/product-cover-thumbnails.tpl'}
{/block}
</div>
<div class="product__right">
<p class="product__name h2 {if !empty($product_manufacturer->name) && !empty($product_brand_url)}mb-1{/if}">
{$product.name}
</p>
{block name='product_manufacturer'}
{if !empty($product_manufacturer->name) && !empty($product_brand_url)}
<div class="product__manufacturer">
<a href="{$product_brand_url}" aria-label="{l s='Product brand: %brand_name%' sprintf=['%brand_name%' => $product_manufacturer->name] d='Shop.Theme.Catalog'}">
{$product_manufacturer->name}
</a>
</div>
{/if}
{/block}
{block name='product_prices'}
{include file='catalog/_partials/product-prices.tpl'}
{/block}
{block name='product_description_short'}
{if $product.description_short}
<div class="product__description-short">{$product.description_short nofilter}</div>
{/if}
{/block}
{block name='product_customization'}
{if $product.is_customizable && count($product.customizations.fields)}
{include file='catalog/_partials/product-customization.tpl' customizations=$product.customizations}
{/if}
{/block}
{block name='product_buy'}
<div class="product__actions js-product-actions">
<form action="{$urls.pages.cart}" method="post" id="add-to-cart-or-refresh">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="id_product" value="{$product.id}" id="product_page_product_id">
<input type="hidden" name="id_customization" value="{$product.id_customization}"
id="product_customization_id" class="js-product-customization-id">
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block}
{block name='product_add_to_cart'}
{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}
{* Input to refresh product HTML removed, block kept for compatibility with themes *}
{block name='product_refresh'}{/block}
</form>
</div>
{/block}
</div>
</div>
<div class="quickview__footer modal-footer">
{capture name="social_share"}{widget name="ps_sharebuttons"}{/capture}
{if !empty($smarty.capture.social_share)}
{$smarty.capture.social_share nofilter}
{/if}
<a class="quickview__details-link" href="{$product.url|escape:'htmlall':'UTF-8'}">
<span>{l s='All details' d='Shop.Theme.Catalog'}</span>
<i class="material-icons" aria-hidden="true">chevron_right</i>
</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="products__sort-label">
<span class="align-middle">{l s='Sort by:' d='Shop.Theme.Global'}</span>
</div>
<div class="products__sort-dropdown">
<button
class="products__sort-dropdown-button btn btn-outline-tertiary dropdown-toggle"
id="sort_dropdown_button"
rel="nofollow"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
aria-label="{l s='Change sort order' d='Shop.Theme.Global'}">
{if $listing.sort_selected}{$listing.sort_selected}{else}{l s='Choose' d='Shop.Theme.Actions'}{/if}
</button>
<div class="dropdown-menu" role="menu" aria-labelledby="sort_dropdown_button">
{foreach from=$listing.sort_orders item=sort_order}
<a
rel="nofollow"
href="{$sort_order.url}"
aria-label="{l s='Sort products by: %sort_order%' sprintf=['%sort_order%' => $sort_order.label] d='Shop.Theme.Global'}"
role="menuitem"
{if $sort_order.current}aria-current="true"{/if}
class="dropdown-item {['current' => $sort_order.current, 'js-search-link' => true]|classnames}"
>
{$sort_order.label}
</a>
{/foreach}
</div>
</div>

View File

@@ -0,0 +1,61 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'subcategory'}
{if !empty($subcategories)}
{**
* Determine if at least one subcategory has a thumbnail image.
* If so, set 'displaySubcategoryImages' to true so the list will render with images.
*}
{assign var=displaySubcategoryImages value=false}
{foreach $subcategories as $category}
{if isset($category.thumbnail) && !empty($category.thumbnail)}
{assign var=displaySubcategoryImages value=true}
{break}
{/if}
{/foreach}
<div class="{$componentName}">
<div class="{$componentName}__list{if $displaySubcategoryImages} {$componentName}__list--with-images{/if}">
{foreach from=$subcategories item=subcategory}
<a class="{$componentName}__link{if $displaySubcategoryImages} {$componentName}__link--with-image{/if}" href="{$subcategory.url}" title="{$subcategory.name|escape:'html':'UTF-8'}">
{if $displaySubcategoryImages}
{if isset($subcategory.thumbnail.bySize.category_default.url) && !empty($subcategory.thumbnail.bySize.category_default.url)}
<picture>
{if isset($subcategory.thumbnail.bySize.category_default.sources.avif)}
<source srcset="{$subcategory.thumbnail.bySize.category_default.sources.avif}" type="image/avif">
{/if}
{if isset($subcategory.thumbnail.bySize.category_default.sources.webp)}
<source srcset="{$subcategory.thumbnail.bySize.category_default.sources.webp}" type="image/webp">
{/if}
<img
class="{$componentName}__thumbnail img-fluid"
src="{$subcategory.thumbnail.bySize.category_default.url}"
width="{$subcategory.thumbnail.bySize.category_default.width}"
height="{$subcategory.thumbnail.bySize.category_default.height}"
alt="{$subcategory.name|escape:'html':'UTF-8'}"
loading="lazy"
>
</picture>
{else}
<img
class="{$componentName}__thumbnail img-fluid"
src="{$urls.no_picture_image.bySize.small_default.url}"
width="{$urls.no_picture_image.bySize.small_default.width}"
height="{$urls.no_picture_image.bySize.small_default.height}"
alt="{$subcategory.name|escape:'html':'UTF-8'}"
loading="lazy"
>
{/if}
{/if}
<span class="{$componentName}__name">{$subcategory.name|escape:'html':'UTF-8'}</span>
</a>
{/foreach}
</div>
</div>
{/if}

View File

@@ -0,0 +1,14 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{foreach from=$variants item=variant}
<a href="{$variant.url}"
class="{$variant.type}"
title="{$variant.name}"
aria-label="{$variant.name} - {$product.name}"
{if $variant.texture}style="background-image: url({$variant.texture})"{/if}
{if $variant.html_color_code}style="background-color: {$variant.html_color_code}"{/if}
></a>
{/foreach}

View File

@@ -0,0 +1,19 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{block name='content'}
{block name='brand_header'}
{include file='components/page-title-section.tpl' title={l s='Brands' d='Shop.Theme.Catalog'}}
{/block}
{block name='brand_miniature'}
<ul class="brand__list">
{foreach from=$brands item=brand}
{include file='catalog/_partials/miniatures/brand.tpl' brand=$brand}
{/foreach}
</ul>
{/block}
{/block}

View File

@@ -0,0 +1,5 @@
{*
* This file allows you to customize your best-sales page.
* You can safely remove it if you want it to appear exactly like all other product listing pages
*}
{extends file='catalog/listing/product-list.tpl'}

View File

@@ -0,0 +1,13 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='catalog/listing/product-list.tpl'}
{block name='product_list_header'}
{include file='catalog/_partials/category-header.tpl' listing=$listing category=$category}
{/block}
{block name='product_list_footer'}
{include file='catalog/_partials/category-footer.tpl' listing=$listing category=$category}
{/block}

View File

@@ -0,0 +1,17 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='catalog/listing/product-list.tpl'}
{block name='product_list_header'}
{include file='components/page-title-section.tpl' title={l s='List of products by brand %brand_name%' sprintf=['%brand_name%' => $manufacturer.name] d='Shop.Theme.Catalog'}}
{if $manufacturer.short_description}
<div class="rich-text">{$manufacturer.short_description nofilter}</div>
{/if}
{if $manufacturer.description}
<div class="rich-text">{$manufacturer.description nofilter}</div>
{/if}
{/block}

View File

@@ -0,0 +1,5 @@
{*
* This file allows you to customize your new-product page.
* You can safely remove it if you want it to appear exactly like all other product listing pages
*}
{extends file='catalog/listing/product-list.tpl'}

View File

@@ -0,0 +1,5 @@
{*
* This file allows you to customize your price-drop page.
* You can safely remove it if you want it to appear exactly like all other product listing pages
*}
{extends file='catalog/listing/product-list.tpl'}

View File

@@ -0,0 +1,56 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{block name='head_microdata_special'}
{include file='_partials/microdata/product-list-jsonld.tpl' listing=$listing}
{/block}
{block name='content'}
{block name='product_list_header'}
<div id="js-product-list-header">
{include file='components/page-title-section.tpl' title=$listing.label}
</div>
{/block}
{hook h='displayHeaderCategory'}
<section id="products">
{if $listing.products|count}
{block name='product_list_top'}
{include file='catalog/_partials/products-top.tpl' listing=$listing}
{/block}
{block name='product_list_active_filters'}
{$listing.rendered_active_filters nofilter}
{/block}
{block name='product_list'}
{include file='catalog/_partials/products.tpl' listing=$listing}
{/block}
{block name='product_list_bottom'}
{include file='catalog/_partials/products-bottom.tpl' listing=$listing}
{/block}
{else}
<div id="js-product-list-top"></div>
<div id="js-product-list">
{capture assign="errorContent"}
<p class="h3">{l s='No products available at the moment' d='Shop.Theme.Catalog'}</p>
<p>{l s='Stay tuned! More products will be shown here as they are added.' d='Shop.Theme.Catalog'}</p>
{/capture}
{include file='errors/not-found.tpl' errorContent=$errorContent}
<div>
<div id="js-product-list-bottom"></div>
{/if}
</section>
{block name='product_list_footer'}{/block}
{hook h='displayFooterCategory'}
{/block}

View File

@@ -0,0 +1,29 @@
{*
* This file allows you to customize your search page.
* You can safely remove it if you want it to appear exactly like all other product listing pages
*}
{extends file='catalog/listing/product-list.tpl'}
{block name='product_list'}
{include file='catalog/_partials/products.tpl' listing=$listing}
{/block}
{block name='error_content'}
<p>{l s='Search again what you are looking for.' d='Shop.Theme.Catalog'}</p>
{/block}
{block name='product_list_header'}
{if empty($search_string)}
{assign var='title' value={l s='Nothing to search for' d='Shop.Theme.Catalog'}}
{else}
{if $listing.products|count}
{assign var='title' value={l s='Search results for "%search_term%"' sprintf=['%search_term%' => $search_string] d='Shop.Theme.Catalog'}}
{else}
{assign var='title' value={l s='No search results for "%search_term%"' sprintf=['%search_term%' => $search_string] d='Shop.Theme.Catalog'}}
{/if}
{/if}
<div id="js-product-list-header">
{include file='components/page-title-section.tpl' title=$title}
</div>
{/block}

View File

@@ -0,0 +1,13 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='catalog/listing/product-list.tpl'}
{block name='product_list_header'}
{include file='components/page-title-section.tpl' title={l s='List of products by supplier %supplier_name%' sprintf=['%supplier_name%' => $supplier.name] d='Shop.Theme.Catalog'}}
{if $supplier.description}
<div class="rich-text">{$supplier.description nofilter}</div>
{/if}
{/block}

View File

@@ -0,0 +1,221 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{block name='head' append}
<meta property="og:type" content="product">
<meta content="{$product.url}">
{if $product.cover}
<meta property="og:image" content="{$product.cover.large.url}">
{/if}
{if $product.show_price}
<meta property="product:pretax_price:amount" content="{$product.price_tax_exc}">
<meta property="product:pretax_price:currency" content="{$currency.iso_code}">
<meta property="product:price:amount" content="{$product.price_amount}">
<meta property="product:price:currency" content="{$currency.iso_code}">
{/if}
{if isset($product.weight) && ($product.weight != 0)}
<meta property="product:weight:value" content="{$product.weight}">
<meta property="product:weight:units" content="{$product.weight_unit}">
{/if}
{/block}
{block name='head_microdata_special'}
{include file='_partials/microdata/product-jsonld.tpl'}
{/block}
{block name='content'}
{* FIRST PART - PHOTO, NAME, PRICES, ADD TO CART*}
<div class="product__container product-container js-product-container" data-ps-ref="product-container">
<div class="product__left">
{block name='product_cover_thumbnails'}
{include file='catalog/_partials/product-cover-thumbnails.tpl'}
{/block}
</div>
<div class="product__right" data-ps-ref="product-right" tabindex="-1">
{block name='product_header'}
<h1 class="product__name h2 {if !empty($product_manufacturer->name) && !empty($product_brand_url)}mb-1{/if}">
{block name='page_title'}{$product.name}{/block}
</h1>
{/block}
{block name='product_manufacturer'}
{if !empty($product_manufacturer->name) && !empty($product_manufacturer->url)}
<div class="product__manufacturer">
<a href="{$product_manufacturer->url}" aria-label="{l s='Product brand: %brand_name%' sprintf=['%brand_name%' => $product_manufacturer->name] d='Shop.Theme.Catalog'}">
{$product_manufacturer->name}
</a>
</div>
{/if}
{/block}
{block name='product_prices'}
{include file='catalog/_partials/product-prices.tpl'}
{/block}
{block name='product_description_short'}
<div class="product__description-short rich-text">{$product.description_short nofilter}</div>
{/block}
{block name='product_customization'}
{if $product.is_customizable && count($product.customizations.fields)}
{include file='catalog/_partials/product-customization.tpl' customizations=$product.customizations}
{/if}
{/block}
<div class="product__actions js-product-actions">
{block name='product_buy'}
<form action="{$urls.pages.cart}" method="post" id="add-to-cart-or-refresh">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="id_product" value="{$product.id}" id="product_page_product_id">
<input type="hidden" name="id_customization" value="{$product.id_customization}" id="product_customization_id" class="js-product-customization-id">
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block}
{block name='product_pack'}
{include file='catalog/_partials/product-pack.tpl'}
{/block}
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block}
{block name='product_add_to_cart'}
{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}
{block name='product_additional_info'}
{include file='catalog/_partials/product-additional-info.tpl'}
{/block}
{block name='product_out_of_stock'}
{hook h='actionProductOutOfStock' product=$product}
{/block}
{* Input to refresh product HTML removed, block kept for compatibility with themes *}
{block name='product_refresh'}{/block}
</form>
{/block}
</div>
</div>
</div>
{* END OF FIRST PART *}
{* SECOND PART - REASSURANCE, TABS *}
<div class="product__bottom">
<div class="product__bottom-left">
{block name='product_tabs'}
<div class="product__accordion accordion accordion-flush" id="product_accordion">
{block name='product_description'}
{if $product.description}
<div class="accordion-item" id="product_description">
<h2 class="accordion-header" id="product_description_heading">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#product_description_collapse" aria-expanded="true" aria-controls="product_description_collapse">
{l s='Description' d='Shop.Theme.Catalog'}
</button>
</h2>
<div id="product_description_collapse" class="accordion-collapse collapse show" aria-labelledby="product_description_heading">
<div class="accordion-body">
<div class="product__description rich-text">
{$product.description nofilter}
</div>
</div>
</div>
</div>
{/if}
{/block}
{block name='product_details'}
{include file='catalog/_partials/product-details.tpl'}
{/block}
{block name='product_attachments'}
{if $product.attachments}
<div class="info accordion-item" id="product_attachments">
<h2 class="accordion-header" id="product_attachments_heading">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#product_attachments_collapse" aria-expanded="false" aria-controls="product_attachments_collapse">
{l s='Download' d='Shop.Theme.Actions'}
</button>
</h2>
<div id="product_attachments_collapse" class="accordion-collapse collapse" aria-labelledby="product_attachments_heading">
<div class="accordion-body">
<div class="product__attachments">
{foreach from=$product.attachments item=attachment}
<div class="attachment">
<p class="attachment__name">
{$attachment.name}
</p>
{if $attachment.description}
<p class="attachment__description">
{$attachment.description}
</p>
{/if}
<a class="attachment__link stretched-link"
href="{url entity='attachment' params=['id_attachment' => $attachment.id_attachment]}"
aria-label="{l s='Download %attachment_name%' sprintf=['%attachment_name%' => $attachment.name] d='Shop.Theme.Actions'}"
>
<i class="material-icons">&#xE2C4;</i> {l s='Download' d='Shop.Theme.Actions'} ({$attachment.file_size_formatted})
</a>
</div>
{/foreach}
</div>
</div>
</div>
</div>
{/if}
{/block}
{* New collapses for module hooked content *}
{foreach from=$product.extraContent item=extra key=extraKey}
<div class="accordion-item" id="extra_{$extraKey}" {foreach $extra.attr as $key => $val} {$key}="{$val}"{/foreach}>
<h2 class="accordion-header" id="product_extra_{$extraKey}_heading">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#product_extra_{$extraKey}_collapse" aria-expanded="false" aria-controls="product_extra_{$extraKey}_collapse">
{$extra.title}
</button>
</h2>
<div id="product_extra_{$extraKey}_collapse" class="accordion-collapse collapse" data-bs-parent="#product_accordion" aria-labelledby="product_extra_{$extraKey}_heading">
<div class="accordion-body">
{$extra.content nofilter}
</div>
</div>
</div>
{/foreach}
</div>
{/block}
</div>
<div class="product__bottom-right">
{block name='hook_display_reassurance'}
{hook h='displayReassurance'}
{/block}
</div>
</div>
{* END OF SECOND PART *}
{block name='product_accessories'}
{if $accessories}
{include file='catalog/_partials/product-accessories.tpl'}
{/if}
{/block}
{block name='product_footer'}
{hook h='displayFooterProduct' product=$product category=$category}
{/block}
{block name='page_footer_container'}
{block name='page_footer'}
{/block}
{/block}
{/block}

View File

@@ -0,0 +1,19 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{block name='content'}
{block name='supplier_header'}
{include file='components/page-title-section.tpl' title={l s='Suppliers' d='Shop.Theme.Catalog'}}
{/block}
{block name='supplier_miniature'}
<ul class="supplier__list">
{foreach from=$suppliers item=supplier}
{include file='catalog/_partials/miniatures/supplier.tpl' supplier=$supplier}
{/foreach}
</ul>
{/block}
{/block}