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,25 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'breadcrumb'}
<nav data-depth="{$breadcrumb.count}" class="{$componentName}__wrapper" aria-label="{$componentName}">
<div class="container">
<ol class="{$componentName}">
{block name='breadcrumb'}
{foreach from=$breadcrumb.links item=path name=breadcrumb}
{block name='breadcrumb_item'}
<li class="{$componentName}-item">
{if not $smarty.foreach.breadcrumb.last}
<a href="{$path.url}" class="{$componentName}-link"><span>{$path.title}</span></a>
{else}
<span>{$path.title}</span>
{/if}
</li>
{/block}
{/foreach}
{/block}
</ol>
</div>
</nav>

View File

@@ -0,0 +1,9 @@
{block name='copyright'}
<div class="copyright">
{block name='copyright_link'}
<a href="https://www.prestashop-project.org/" target="_blank" rel="noopener noreferrer nofollow">
{l s='%copyright% %year% - Ecommerce software by %prestashop%' sprintf=['%prestashop%' => 'PrestaShop™', '%year%' => 'Y'|date, '%copyright%' => '©'] d='Shop.Theme.Global'}
</a>
{/block}
</div>
{/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.
*}
{capture name="footer_before"}{hook h='displayFooterBefore'}{/capture}
{if $smarty.capture.footer_before}
{block name='hook_footer_before'}
<div class="footer footer__before">
{$smarty.capture.footer_before nofilter}
</div>
{/block}
{/if}
{block name='footer_main'}
<div class="footer footer__main">
<div class="container">
{capture name="footer_main_top"}{hook h='displayFooter'}{/capture}
{if $smarty.capture.footer_main_top}
{block name='hook_footer_main'}
<div class="footer__main-top row">
{$smarty.capture.footer_main_top nofilter}
</div>
{/block}
{/if}
{capture name="footer_main_bottom"}{hook h='displayFooterAfter'}{/capture}
{if isset($smarty.capture.footer_main_bottom) && $smarty.capture.footer_main_bottom}
{block name='hook_footer_after'}
<div class="footer__main-bottom row">
{$smarty.capture.footer_main_bottom nofilter}
</div>
{/block}
{/if}
{include file='_partials/copyright.tpl'}
</div>
</div>
{/block}

View File

@@ -0,0 +1,25 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $errors|count}
<div class="help-block">
{block name='form_errors'}
<div class="alert alert-danger mt-3 alert-dismissible" role="alert" tabindex="0">
{if $errors|count > 1}
<p class="mb-1">
{l s='There are %d% errors:' sprintf=['%d%' => $errors|count] d='Shop.Notifications.Error'}
</p>
<ol class="mb-0">
{foreach $errors as $error}
<li>{$error|nl2br nofilter}</li>
{/foreach}
</ol>
{else}
{$errors.0|nl2br nofilter}
{/if}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{l s='Close' d='Shop.Theme.Actions'}"></button>
</div>
{/block}
</div>
{/if}

View File

@@ -0,0 +1,219 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $field.type == 'hidden'}
{block name='form_field_item_hidden'}
<input type="hidden" name="{$field.name}" value="{$field.value}">
{/block}
{else}
<div class="mb-3{if !empty($field.errors)} has-error{/if}">
{if ($field.type !== 'checkbox')}
<label class="form-label{if $field.required} required{/if}" for="field-{$field.name}">
{if $field.type !== 'checkbox'}
{$field.label}
{/if}
</label>
{/if}
{if $field.type === 'select'}
{block name='form_field_item_select'}
<select class="form-select" name="{$field.name}" id="field-{$field.name}" {if $field.required}required{/if}>
<option value disabled selected>{l s='-- please choose --' d='Shop.Forms.Labels'}</option>
{foreach from=$field.availableValues item="label" key="value"}
<option value="{$value}" {if $value eq $field.value} selected {/if}>{$label}</option>
{/foreach}
</select>
{/block}
{elseif $field.type === 'countrySelect'}
{block name='form_field_item_country'}
<select
class="form-select js-country"
name="{$field.name}"
id="field-{$field.name}"
{if $field.required}required{/if}
>
<option value disabled selected>{l s='-- please choose --' d='Shop.Forms.Labels'}</option>
{foreach from=$field.availableValues item="label" key="value"}
<option value="{$value}" {if $value eq $field.value} selected {/if}>{$label}</option>
{/foreach}
</select>
{/block}
{elseif $field.type === 'radio-buttons'}
{block name='form_field_item_radio'}
<div aria-labelledby="field-{$field.name}-label">
<p class="visually-hidden" id="field-{$field.name}-label">{$field.label}</p>
{foreach from=$field.availableValues item="label" key="value"}
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="{$field.name}"
id="field-{$field.name}_{$value}"
value="{$value}"
{if $field.required}required{/if}
{if $value eq $field.value} checked {/if}
>
<label class="form-check-label" for="field-{$field.name}_{$value}">
{$label}
</label>
</div>
{/foreach}
</div>
{/block}
{elseif $field.type === 'checkbox'}
{block name='form_field_item_checkbox'}
<div class="form-check">
<input
class="form-check-input"
name="{$field.name}"
type="checkbox"
value="1"
id="field-{$field.name}"
value="1" {if $field.value}checked="checked"{/if}
{if $field.required}required{/if}
>
<label class="form-check-label{if $field.required} required{/if}" for="field-{$field.name}">
{$field.label nofilter}
</label>
</div>
{/block}
{elseif $field.type === 'date'}
{block name='form_field_item_date'}
<input name="{$field.name}" class="form-control" type="date" id="field-{$field.name}" value="{$field.value}"{if isset($field.availableValues.placeholder)} placeholder="{$field.availableValues.placeholder}" aria-label="{$field.availableValues.placeholder}"{/if}>
{if isset($field.availableValues.comment)}
<span class="form-text">
{$field.availableValues.comment}
</span>
{/if}
{/block}
{elseif $field.type === 'birthday'}
{block name='form_field_item_birthday'}
<div class="js-parent-focus">
{html_select_date
field_order=DMY
time={$field.value}
field_array={$field.name}
prefix=false
reverse_years=true
field_separator='<br>'
day_extra='class="form-select"'
month_extra='class="form-select"'
year_extra='class="form-select"'
day_empty={l s='-- day --' d='Shop.Forms.Labels'}
month_empty={l s='-- month --' d='Shop.Forms.Labels'}
year_empty={l s='-- year --' d='Shop.Forms.Labels'}
start_year={'Y'|date}-100 end_year={'Y'|date}
}
</div>
{/block}
{elseif $field.type === 'password'}
{block name='form_field_item_password'}
<div class="input-group password-field">
<input
class="form-control"
name="{$field.name}"
id="field-{$field.name}"
type="password"
{if $field.autocomplete}autocomplete="{$field.autocomplete}"{/if}
value=""
minlength="{$configuration.password_policy.minimum_length|default:8}"
maxlength="{$configuration.password_policy.maximum_length|default:72}"
data-minscore="{$configuration.password_policy.minimum_score|default:3}"
data-bs-placement="top"
data-bs-trigger="manual"
data-ps-ref="password-policy-input"
spellcheck="false"
{if $field.required}required{/if}
>
<button
class="btn btn-primary"
type="button"
data-ps-action="toggle-password"
data-text-show="{l s='Show password' d='Shop.Theme.Actions'}"
data-text-hide="{l s='Hide password' d='Shop.Theme.Actions'}"
aria-label="{l s='Show password' d='Shop.Theme.Actions'}"
aria-controls="field-{$field.name}"
aria-live="polite"
>
<i class="material-icons" aria-hidden="true">&#xE8F4;</i>
</button>
</div>
<div data-ps-target="password-feedback-target"></div>
{/block}
{elseif $field.type === 'textarea'}
{block name='form_field_item_textarea'}
<textarea
id="field-{$field.name}"
class="form-control"
name="{$field.name}"
{if isset($field.availableValues.placeholder)}placeholder="{$field.availableValues.placeholder}"{/if}
{if $field.maxLength}maxlength="{$field.maxLength}"{/if}
{if $field.required}required{/if}
{if isset($field.availableValues.rows)}rows="{$field.availableValues.rows}"{/if}
{if isset($field.availableValues.cols)}cols="{$field.availableValues.cols}"{/if}
>{$field.value|default}</textarea>
{if isset($field.availableValues.comment)}
<span class="form-text">
{$field.availableValues.comment}
</span>
{/if}
{/block}
{else}
{block name='form_field_item_other'}
<input
class="form-control"
name="{$field.name}"
id="field-{$field.name}"
type="{$field.type}"
value="{$field.value}"
{if $field.autocomplete}autocomplete="{$field.autocomplete}"{/if}
{if isset($field.availableValues.placeholder)}placeholder="{$field.availableValues.placeholder}"{/if}
{if $field.maxLength}maxlength="{$field.maxLength}"{/if}
{if !empty($field.minLength)}minlength="{$field.minLength}"{/if}
aria-label="{$field.label}"
{if $field.required}required{/if}
>
{if isset($field.availableValues.comment)}
<span class="form-text">
{$field.availableValues.comment}
</span>
{/if}
{/block}
{/if}
{block name='form_field_errors'}
{include file='_partials/form-errors.tpl' errors=$field.errors}
{/block}
{block name='form_field_comment'}
{if (!$field.required && !in_array($field.type, ['radio-buttons', 'checkbox']))}
<div class="form-text">{l s='Optional' d='Shop.Forms.Labels'}</div>
{/if}
{/block}
</div>
{/if}

View File

@@ -0,0 +1,80 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='head_charset'}
<meta charset="utf-8">
{/block}
{block name='head_ie_compatibility'}
<meta http-equiv="x-ua-compatible" content="ie=edge">
{/block}
{block name='head_seo'}
{block name='head_preload'}
{include file='_partials/preload.tpl'}
{/block}
<title>{block name='head_seo_title'}{$page.meta.title}{/block}</title>
{block name='hook_after_title_tag'}
{hook h='displayAfterTitleTag'}
{/block}
<meta name="description" content="{block name='head_seo_description'}{$page.meta.description}{/block}">
{if $page.meta.robots !== 'index'}
<meta name="robots" content="{$page.meta.robots}">
{/if}
{if $page.canonical}
<link rel="canonical" href="{$page.canonical}">
{/if}
{block name='head_hreflang'}
{foreach from=$urls.alternative_langs item=pageUrl key=code}
<link rel="alternate" href="{$pageUrl}" hreflang="{$code}">
{/foreach}
{/block}
{block name='head_microdata'}
{include file='_partials/microdata/head-jsonld.tpl'}
{/block}
{block name='head_microdata_special'}{/block}
{block name='head_pagination_seo'}
{include file='_partials/pagination-seo.tpl'}
{/block}
{block name='head_open_graph'}
<meta property="og:title" content="{$page.meta.title}">
<meta property="og:description" content="{$page.meta.description}">
<meta property="og:url" content="{$urls.current_url}">
<meta property="og:site_name" content="{$shop.name}">
{if !isset($product) && $page.page_name != 'product'}<meta property="og:type" content="website">{/if}
{/block}
{/block}
{block name='head_viewport'}
<meta name="viewport" content="width=device-width, initial-scale=1">
{/block}
{block name='head_icons'}
<link rel="icon" type="image/vnd.microsoft.icon" href="{$shop.favicon}?{$shop.favicon_update_time}">
<link rel="shortcut icon" type="image/x-icon" href="{$shop.favicon}?{$shop.favicon_update_time}">
{/block}
{block name='stylesheets'}
{include file='_partials/stylesheets.tpl' stylesheets=$stylesheets}
{/block}
{block name='javascript_head'}
{include file='_partials/javascript.tpl' javascript=$javascript.head vars=$js_custom_vars}
{/block}
{block name='hook_header'}
{$HOOK_HEADER nofilter}
{/block}
{block name='hook_extra'}{/block}

View File

@@ -0,0 +1,86 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$headerBanner = 'header-banner'}
{$headerTop = 'header-top'}
{$headerBottom = 'header-bottom'}
{$headerNavFullWidth = 'header-nav-full-width'}
{capture name="header_banner"}{hook h='displayBanner'}{/capture}
{block name='header_banner'}
{if !empty($smarty.capture.header_banner)}
<div class="{$headerBanner}">
{$smarty.capture.header_banner nofilter}
</div>
{/if}
{/block}
{capture name="header_nav_1"}{hook h='displayNav1'}{/capture}
{capture name="header_nav_2"}{hook h='displayNav2'}{/capture}
{block name='header_nav'}
{if !empty($smarty.capture.header_nav_1) || !empty($smarty.capture.header_nav_2)}
<div class="{$headerTop} d-none d-md-block">
<div class="container-md">
<div class="row">
<div class="{$headerTop}__left col-md-4">
{$smarty.capture.header_nav_1 nofilter}
</div>
<div class="{$headerTop}__right col-md-8">
{$smarty.capture.header_nav_2 nofilter}
</div>
</div>
</div>
</div>
{/if}
{/block}
{block name='header_bottom'}
<div class="{$headerBottom}">
<div class="{$headerBottom}__container container-md">
<div class="{$headerBottom}__row row gx-2 gx-md-4 align-items-stretch">
<div class="{$headerBottom}__logo d-flex align-items-center col-auto me-auto me-md-0">
{if $shop.logo_details}
{if $page.page_name == 'index'}<h1 class="{$headerBottom}__h1 mb-0">{/if}
{renderLogo}
{if $page.page_name == 'index'}</h1>{/if}
{/if}
</div>
{hook h='displayTop'}
<div id="_mobile_ps_customersignin" class="d-md-none d-flex col-auto">
{* JUST PLACEHOLDER FOR RESPONSIVE COMPONENT TO LOAD REAL ONE *}
<div class="header-block">
<a href="{$urls.pages.my_account}" class="header-block__action-btn">
<i class="material-icons header-block__icon" aria-hidden="true">&#xE853;</i>
</a>
</div>
{* JUST PLACEHOLDER FOR RESPONSIVE COMPONENT TO LOAD REAL ONE *}
</div>
{if !$configuration.is_catalog}
<div id="_mobile_ps_shoppingcart" class="d-md-none d-flex col-auto">
{* JUST PLACEHOLDER FOR RESPONSIVE COMPONENT TO LOAD REAL ONE *}
<div class="header-block">
<a href="{$urls.pages.cart}" class="header-block__action-btn">
<i class="material-icons header-block__icon" aria-hidden="true">&#xE8CC;</i>
<span class="header-block__badge">{$cart.products_count}</span>
</a>
</div>
{* JUST PLACEHOLDER FOR RESPONSIVE COMPONENT TO LOAD REAL ONE *}
</div>
{/if}
</div>
</div>
</div>
{capture name="nav_full_width"}{hook h='displayNavFullWidth'}{/capture}
{if !empty($smarty.capture.nav_full_width)}
<div class="{$headerNavFullWidth}">
{$smarty.capture.nav_full_width nofilter}
</div>
{/if}
{/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.
*}
{function renderLogo}
<a class="navbar-brand d-block" href="{$urls.pages.index}">
<img
class="logo img-fluid"
src="{$shop.logo_details.src}"
alt="{$shop.name}"
width="{$shop.logo_details.width}"
height="{$shop.logo_details.height}"
>
</a>
{/function}

View File

@@ -0,0 +1,21 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{foreach $javascript.external as $js}
<script type="text/javascript" src="{$js.uri}" {$js.attribute}></script>
{/foreach}
{foreach $javascript.inline as $js}
<script type="text/javascript">
{$js.content nofilter}
</script>
{/foreach}
{if isset($vars) && $vars|@count}
<script type="text/javascript">
{foreach from=$vars key=var_name item=var_value}
var {$var_name} = {$var_value|json_encode nofilter};
{/foreach}
</script>
{/if}

View File

@@ -0,0 +1,69 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name" : "{$shop.name}",
"url" : "{$urls.pages.index}",
{if $shop.logo_details}
"logo": {
"@type": "ImageObject",
"url":"{$shop.logo_details.src}"
}
{/if}
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"isPartOf": {
"@type": "WebSite",
"url": "{$urls.pages.index}",
"name": "{$shop.name}"
},
"name": "{$page.meta.title}",
"url": "{$urls.current_url}"
}
</script>
{if $page.page_name == 'index'}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"url" : "{$urls.pages.index}",
"image": {
"@type": "ImageObject",
"url":"{$shop.logo_details.src}"
},
"potentialAction": {
"@type": "SearchAction",
"target": "{'--search_term_string--'|str_replace:'{search_term_string}':$link->getPageLink('search',true,null,['search_query'=>'--search_term_string--'])}",
"query-input": "required name=search_term_string"
}
}
</script>
{/if}
{if isset($breadcrumb.links[1])}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{foreach from=$breadcrumb.links item=path name=breadcrumb}
{
"@type": "ListItem",
"position": {$smarty.foreach.breadcrumb.iteration},
"name": "{$path.title}",
"item": "{$path.url}"
}{if !$smarty.foreach.breadcrumb.last},{/if}
{/foreach}]
}
</script>
{/if}

View File

@@ -0,0 +1,88 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{assign var=hasAggregateRating value=false}
{if !empty($product.productComments.averageRating) && !empty($product.productComments.nbComments)}
{assign var=hasAggregateRating value=true}
{assign var=ratingValue value=$product.productComments.averageRating}
{assign var=ratingReviewCount value=$product.productComments.nbComments}
{/if}
{if !empty($ratings.avg) && !empty($nbComments)}
{assign var=hasAggregateRating value=true}
{assign var=ratingValue value=$ratings.avg}
{assign var=ratingReviewCount value=$nbComments}
{/if}
{assign var=hasWeight value=false}
{if isset($product.weight) && ($product.weight != 0)}
{assign var=hasWeight value=true}
{/if}
{assign var=hasOffers value=$product.show_price}
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "{$product.name}",
"description": "{$page.meta.description|regex_replace:"/[\r\n]/" : " "}",
"category": "{$product.category_name}",
{if !empty($product.cover)}"image" :"{$product.cover.bySize.home_default.url}",{/if}
"sku": "{if $product.reference}{$product.reference}{else}{$product.id}{/if}",
"mpn": "{if $product.mpn}{$product.mpn}{elseif $product.reference}{$product.reference}{else}{$product.id}{/if}"
{if $product.ean13},"gtin": "{$product.ean13}"{/if}
{if $product.upc},"gtin12": "{$product.upc}"{/if}
{if isset($product_manufacturer) && $product_manufacturer->name},
"brand": {
"@type": "Brand",
"name": "{$product_manufacturer->name|escape:'html':'UTF-8'}"
}
{elseif $shop.name},
"brand": {
"@type": "Organization",
"name": "{$shop.name}"
}
{/if}
{if $hasAggregateRating},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "{$ratingValue|round:1|escape:'html':'UTF-8'}",
"reviewCount": "{$ratingReviewCount|escape:'html':'UTF-8'}"
}
{/if}
{if $hasWeight},
"weight": {
"@context": "https://schema.org",
"@type": "QuantitativeValue",
"value": "{$product.weight}",
"unitCode": "{$product.weight_unit}"
}
{/if}
{if $hasOffers},
"offers": {
"@type": "Offer",
"priceCurrency": "{$currency.iso_code}",
"price": "{$product.price_amount}",
"url": "{$product.url}",
"priceValidUntil": "{($smarty.now + (int) (60*60*24*15))|date_format:"%Y-%m-%d"}",
{if $product.images|count > 0}
"image": {strip}[
{foreach from=$product.images item=p_img name="p_img_list"}
"{$p_img.large.url}"{if not $smarty.foreach.p_img_list.last},{/if}
{/foreach}
]{/strip},
{/if}
{if !empty($product.show_condition) && !empty($product.condition)}"itemCondition": "{$product.condition.schema_url}",{/if}
"availability": "{$product.seo_availability}",
"seller": {
"@type": "Organization",
"name": "{$shop.name}"
}
}
{/if}
}
</script>

View File

@@ -0,0 +1,20 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": [
{foreach from=$listing.products item=item name=productsForJsonLd}
{
"@type": "ListItem",
"position": {$smarty.foreach.productsForJsonLd.iteration},
"name": "{$item.name}",
"url": "{$item.url}"
}{if !$smarty.foreach.productsForJsonLd.last},{/if}
{/foreach}
]
}
</script>

View File

@@ -0,0 +1,78 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if isset($notifications)}
<div id="notifications">
<div class="container">
{if $notifications.error}
{block name='notifications_error'}
<div class="alert alert-danger alert-dismissible" role="alert" tabindex="0">
{if $notifications.error|count > 1}
<ul class="mb-0">
{foreach $notifications.error as $notif}
<li>{$notif nofilter}</li>
{/foreach}
</ul>
{else}
{$notifications.error.0 nofilter}
{/if}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{/block}
{/if}
{if $notifications.warning}
{block name='notifications_warning'}
<div class="alert alert-warning alert-dismissible" role="alert" tabindex="0">
{if $notifications.warning|count > 1}
<ul class="mb-0">
{foreach $notifications.warning as $notif}
<li>{$notif nofilter}</li>
{/foreach}
</ul>
{else}
{$notifications.warning.0 nofilter}
{/if}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{/block}
{/if}
{if $notifications.success}
{block name='notifications_success'}
<div class="alert alert-success alert-dismissible" role="alert" tabindex="0">
{if $notifications.success|count > 1}
<ul class="mb-0">
{foreach $notifications.success as $notif}
<li>{$notif nofilter}</li>
{/foreach}
</ul>
{else}
{$notifications.success.0 nofilter}
{/if}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{/block}
{/if}
{if $notifications.info}
{block name='notifications_info'}
<div class="alert alert-info alert-dismissible" role="alert" tabindex="0">
{if $notifications.info|count > 1}
<ul class="mb-0">
{foreach $notifications.info as $notif}
<li>{$notif nofilter}</li>
{/foreach}
</ul>
{else}
{$notifications.info.0 nofilter}
{/if}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{/block}
{/if}
</div>
</div>
{/if}

View File

@@ -0,0 +1,27 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if isset($listing.pagination) && $listing.pagination.should_be_displayed}
{$page_nb = 1}
{if isset($smarty.get.page)}
{$page_nb = $smarty.get.page|intval|default:1}
{/if}
{$queryPage = '?page='|cat:$page_nb}
{$page.canonical = $page.canonical|replace:$queryPage:''}
{$prev = false}
{$next = false}
{if ($page_nb - 1) == 1}
{$prev = $page.canonical}
{elseif $page_nb> 2}
{$prev = ($page['canonical']|cat:'?page='|cat:($page_nb - 1))}
{/if}
{if $listing.pagination.total_items> $listing.pagination.items_shown_to}
{$next = ($page['canonical']|cat:'?page='|cat:($page_nb + 1))}
{/if}
{if $prev}<link rel="prev" href="{$prev}">{/if}
{if $next}<link rel="next" href="{$next}">{/if}
{/if}

View File

@@ -0,0 +1,72 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'pagination'}
<nav class="{$componentName}__container">
<div class="{$componentName}__number">
{block name='pagination_summary'}
{l s='Showing %from%-%to% of %total% item(s)' d='Shop.Theme.Catalog' sprintf=['%from%' => $pagination.items_shown_from ,'%to%' => $pagination.items_shown_to, '%total%' => $pagination.total_items]}
{/block}
</div>
<div class="{$componentName}__nav">
{block name='pagination_page_list'}
<nav aria-label="{l s='Products pagination' d='Shop.Theme.Catalog'}">
{if $pagination.should_be_displayed}
<ul class="{$componentName}">
{foreach from=$pagination.pages item="page" name="paginationLoop"}
{if $page@iteration === 1}
<li class="page-item">
<button data-ps-data="{$page.url}"
class="page-link previous {['disabled' => !$page.clickable, 'js-pager-link' => $page.clickable]|classnames}"
{if !$page.clickable}aria-disabled="true" disabled{/if}
aria-label="{l s='Go to previous page' d='Shop.Theme.Actions'}"
>
<i class="material-icons rtl-flip" aria-hidden="true">&#xE314;</i>
<span class="d-none d-xl-flex">{l s='Previous' d='Shop.Theme.Actions'}</span>
</button>
</li>
{if $page.type === 'previous'}
{continue}
{/if}
{/if}
{if $page.type === 'spacer'}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&hellip;</span>
</li>
{elseif $page.type != "prev" && $page.type != "next"}
<li class="page-item{if $page.current} active{/if}">
<button data-ps-data="{$page.url}"
class="page-link {['js-pager-link' => $page.clickable]|classnames}"
{if !$page.clickable}aria-disabled="true"{/if}
{if $page.current}aria-current="page"{/if}
aria-label="{l s='Go to page %page%' sprintf=['%page%' => $page.page] d='Shop.Theme.Actions'}"
>
{$page.page}
</button>
</li>
{/if}
{if $smarty.foreach.paginationLoop.last}
<li class="page-item">
<button data-ps-data="{$page.url}"
class="page-link next {['disabled' => !$page.clickable, 'js-pager-link' => $page.clickable]|classnames}"
{if !$page.clickable}aria-disabled="true" disabled{/if}
aria-label="{l s='Go to next page' d='Shop.Theme.Actions'}"
>
<span class="d-none d-xl-flex">{l s='Next' d='Shop.Theme.Actions'}</span>
<i class="material-icons rtl-flip" aria-hidden="true">&#xE315;</i>
</button>
</li>
{/if}
{/foreach}
</ul>
{/if}
</nav>
{/block}
</div>
</nav>

View File

@@ -0,0 +1,8 @@
{$themeDir = _PS_THEME_DIR_}
{$preloadFilePath = "`$themeDir`assets/preload.html"}
{$assetsUrl = $urls.theme_assets}
{if file_exists($preloadFilePath)}
{capture name="preloadBlock"}{include file=$preloadFilePath}{/capture}
{$smarty.capture.preloadBlock|replace:'href="../':"href=\"$assetsUrl" nofilter}
{/if}

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.
*}
{foreach $stylesheets.external as $stylesheet}
<link rel="stylesheet" href="{$stylesheet.uri}" type="text/css" media="{$stylesheet.media}">
{/foreach}
{foreach $stylesheets.inline as $stylesheet}
<style>
{$stylesheet.content}
</style>
{/foreach}

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}

View File

@@ -0,0 +1,50 @@
{extends file='customer/_partials/address-form.tpl'}
{block name='form_field'}
{if $field.name eq "alias" and $customer.is_guest}
{* we don't ask for alias here if customer is not registered *}
{else}
{$smarty.block.parent}
{/if}
{/block}
{block name='address_form_url'}
<form
method="POST"
action="{url entity='order' params=['id_address' => $id_address]}"
data-id-address="{$id_address}"
data-refresh-url="{url entity='order' params=['ajax' => 1, 'action' => 'addressForm', 'id_address' => $id_address]}"
data-ps-action="form-validation"
>
{/block}
{block name='form_fields' append}
<input type="hidden" name="saveAddress" value="{$type}">
{if $type === "delivery"}
<div class="mb-3 form-check">
<input class="form-check-input" name="use_same_address" id="use_same_address" type="checkbox" value="1" {if $use_same_address} checked {/if}>
<label class="form-check-label" for="use_same_address">{l s='Use this address for invoice too' d='Shop.Theme.Checkout'}</label>
</div>
{/if}
{/block}
{block name='form_buttons'}
{if !$form_has_continue_button}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--no-fw-mobile buttons-wrapper--invert-mobile mt-3">
<a class="js-cancel-address btn btn-basic" href="{url entity='order' params=['cancelAddress' => {$type}]}">{l s='Cancel' d='Shop.Theme.Actions'}</a>
<button type="submit" class="btn btn-primary">{l s='Save' d='Shop.Theme.Actions'}</button>
</div>
{else}
<div class="buttons-wrapper {if $customer.addresses|count == 0}buttons-wrapper--end{else}buttons-wrapper--split buttons-wrapper--no-fw-mobile buttons-wrapper--invert-mobile{/if} mt-3">
{if $customer.addresses|count> 0}
<a class="js-cancel-address btn btn-basic" href="{url entity='order' params=['cancelAddress' => {$type}]}">{l s='Cancel' d='Shop.Theme.Actions'}</a>
{/if}
<button type="submit" class="btn btn-primary" name="confirm-addresses" value="1" data-ps-action="form-validation-submit">
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
</div>
{/if}
{/block}

View File

@@ -0,0 +1,66 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'address-card'}
{block name='address_selector_blocks'}
{foreach $addresses as $address}
<article id="{$name|classname}-address-{$address.id}" class="{$componentName} {$componentName}--radio js-address-item{if $address.id == $selected} selected{/if}" data-id-address="{$address.id}">
<label class="{$componentName}__container">
<div class="{$componentName}__header">
<span class="custom-radio">
<input
type="radio"
class="form-check-input"
name="{$name}"
value="{$address.id}"
{if $address.id == $selected}checked{/if}
aria-label="{l s='Select address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
aria-describedby="address-{$address.id}"
>
</span>
<span class="{$componentName}__alias">
{$address.alias}
</span>
</div>
<address class="{$componentName}__content" id="address-{$address.id}">
<span class="visually-hidden">{l s='Address details:' d='Shop.Theme.Actions'}</span>
{$address.formatted nofilter}
</address>
{block name='address_block_item_actions'}
{if $interactive}
<div class="{$componentName}__actions">
<a
class="{$componentName}__edit link-body-emphasis"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $address.id, 'editAddress' => $type, 'token' => $token]}"
aria-label="{l s='Edit address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="{$componentName}__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $address.id, 'deleteAddress' => true, 'token' => $token]}"
aria-label="{l s='Delete address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
{/if}
{/block}
</label>
</article>
{/foreach}
{if $interactive}
<div class="d-none">
<button class="ps-hidden-by-js form-control-submit center-block" type="submit">{l s='Save' d='Shop.Theme.Actions'}</button>
</div>
{/if}
{/block}

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.
*}
{block name='cart_detailed_actions'}
{$disableCheckout = false}
{foreach $cart.products as $product}
{if isset($product.availability) && $product.availability == 'unavailable' }
{$disableCheckout = true}
{/if}
{/foreach}
<div class="cart-summary__actions checkout js-cart-detailed-actions">
{if $cart.minimalPurchaseRequired}
<div class="alert alert-warning" role="alert">
{$cart.minimalPurchaseRequired}
</div>
<div class="d-grid">
<button type="button" class="btn btn-primary btn-lg disabled" disabled>{l s='Proceed to checkout' d='Shop.Theme.Actions'}</button>
</div>
{elseif empty($cart.products) || $disableCheckout === true}
<div class="d-grid">
<button type="button" class="btn btn-primary btn-lg disabled" disabled>{l s='Proceed to checkout' d='Shop.Theme.Actions'}</button>
</div>
{else}
<div class="d-grid">
<a href="{$urls.pages.order}" class="btn btn-primary btn-lg">{l s='Proceed to checkout' d='Shop.Theme.Actions'}</a>
{hook h='displayExpressCheckout'}
</div>
{/if}
</div>
{/block}

View File

@@ -0,0 +1,200 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="product-line">
<div class="product-line__image">
<a class="product-line__title product-line__item" href="{$product.url}"
data-id_customization="{$product.id_customization|intval}">
{if $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-line__img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
loading="lazy"
alt="{$product.name|escape:'quotes'}"
title="{$product.name|escape:'quotes'}"
>
</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-line__img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
</a>
</div>
<div class="product-line__content">
<div class="product-line__content-left">
<a class="product-line__title" href="{$product.url}"
data-id_customization="{$product.id_customization|intval}">
{$product.name}
</a>
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{foreach from=$product.attributes key="attribute" item="value"}
<div class="product-line__item product-line__item--info {$attribute|lower}">
<span class="product-line__item-label">{$attribute}:</span>
<span class="product-line__item-value">{$value}</span>
</div>
{/foreach}
{if !empty($product.availability_message)}
{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}
<div class="product-line__item product-line__item--availability">
<div class="product-line__item-availability-message {$availability_class}">
<i class="product-line__item-availability-icon material-icons rtl-no-flip">&#x{$availability_icon};</i>
{$product.availability_message}
</div>
</div>
{/if}
{if !empty($product.delivery_information)}
<div class="product-line__item product-line__item--small-info">
{$product.delivery_information}
</div>
{/if}
{hook h='displayCartExtraProductInfo' product=$product}
<div class="product-line__item product-line__item--prices">
<span class="product-line__item-price">{$product.price}</span>
{if $product.unit_price_full}
<span class="product-line__item-unit-price">{$product.unit_price_full}</span>
{/if}
{if $product.has_discount}
<span class="product-line__item-regular-price">{$product.regular_price}</span>
{if $product.discount_type === 'percentage'}
<span class="product-line__item-discount product-line__item-discount--percentage badge bg-primary">
-{$product.discount_percentage_absolute}
</span>
{else}
<span class="product-line__item-discount product-line__item-discount--amount badge bg-primary">
-{$product.discount_to_display}
</span>
{/if}
{/if}
{capture name='product_price_block'}{hook h='displayProductPriceBlock' product=$product type="unit_price"}{/capture}
{if $smarty.capture.product_price_block}
<div class="product-line__item-price-block">
{$smarty.capture.product_price_block nofilter}
</div>
{/if}
</div>
</div>
<div class="product-line__content-right">
<div class="product-line__quantity-button quantity-button js-quantity-button">
{if !empty($product.is_gift)}
<span class="product-line__gift">
<i class="product-line__gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</span>
{else}
{include file='components/qty-input.tpl'
attributes=[
"class"=>"js-cart-line-product-quantity form-control mw-100",
"name"=>"product-quantity-spin",
"data-update-url"=>"{$product.update_quantity_url}",
"data-product-id"=>"{$product.id_product}",
"value"=>"{$product.quantity}",
"min"=>"{$product.minimal_quantity}"
]
}
{/if}
</div>
{if empty($product.is_gift)}
<div class="product-line__price">{$product.total}</div>
{/if}
</div>
<div class="product-line__actions">
{if empty($product.is_gift)}
<a class="js-remove-from-cart"
rel="nofollow"
href="{$product.remove_from_cart_url}"
data-link-action="delete-from-cart" data-id-product="{$product.id_product|escape:'javascript'}"
data-id-product-attribute="{$product.id_product_attribute|escape:'javascript'}"
data-id-customization="{$product.id_customization|escape:'javascript'}"
data-product-url="{$product.url|escape:'javascript'}"
data-product-name="{$product.name|escape:'htmlall':'UTF-8'}"
aria-label="{l s='Remove %productName% from cart' sprintf=['%productName%' => $product.name] d='Shop.Theme.Checkout'}"
>
{l s='Remove' d='Shop.Theme.Checkout'}
</a>
{/if}
{block name='hook_cart_extra_product_actions'}
{hook h='displayCartExtraProductActions' product=$product}
{/block}
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='cart_detailed_totals'}
<div class="cart-summary__totals js-cart-detailed-totals">
<div class="cart-summary__subtotals">
{foreach from=$cart.subtotals item="subtotal"}
{if $subtotal && $subtotal.value|count_characters> 0 && $subtotal.type !== 'tax'}
<div class="cart-summary__line" id="cart-subtotal-{$subtotal.type}">
<span class="cart-summary__label{if $subtotal.type === 'products'} js-subtotal{/if}">
{if $subtotal.type === 'products'}
{$cart.summary_string}
{else}
{$subtotal.label}
{/if}
</span>
<span class="cart-summary__value">
{if $subtotal.type === 'discount'}
-{$subtotal.value}
{elseif $subtotal.type === 'shipping'}
{$subtotal.value}
<small class="cart-summary__value-inner">{hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal}</small>
{else}
{$subtotal.value}
{/if}
</span>
</div>
{/if}
{/foreach}
</div>
{block name='cart_summary_totals'}
{include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart}
{/block}
{block name='cart_voucher'}
{include file='checkout/_partials/cart-voucher.tpl'}
{/block}
{block name='cart_actions'}
{include file='checkout/_partials/cart-detailed-actions.tpl' cart=$cart}
{/block}
</div>
{/block}

View File

@@ -0,0 +1,29 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='cart_detailed_product'}
{* .cart-overview needed for JS *}
<div class="cart__overview cart-overview js-cart"
data-refresh-url="{url entity='cart' params=['ajax' => true, 'action' => 'refresh']}"
tabindex="-1"
>
<hr>
{if $cart.products}
<div class="cart__list js-cart-list" role="list" aria-label="{l s='Products in cart' d='Shop.Theme.Checkout'}">
{foreach from=$cart.products item=product}
<div class="cart__item js-cart-item" role="listitem">
{block name='cart_detailed_product_line'}
{include file='checkout/_partials/cart-detailed-product-line.tpl' product=$product}
{/block}
</div>
{/foreach}
</div>
{else}
<p class="cart__empty">{l s='There are no more items in your cart' d='Shop.Theme.Checkout'}</p>
{/if}
<hr>
</div>
{/block}

View File

@@ -0,0 +1,128 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'cart-summary-product'}
{block name='cart_summary_product_line'}
<div class="{$componentName}">
<div class="{$componentName}__image">
<a href="{$product.url}" title="{$product.name}">
{if $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_sm.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_sm.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_sm.url} 2x"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
loading="lazy"
alt="{$product.name}"
title="{$product.name}"
>
</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_sm.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_sm.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_sm.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
</a>
</div>
<div class="{$componentName}__content">
<div class="{$componentName}__content-left">
<a class="{$componentName}__link" href="{$product.url}" target="_blank" rel="noopener noreferrer nofollow">
{$product.name}
</a>
{if !empty($product.attributes)}
<div class="{$componentName}__attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
<div class="{$componentName}__price">
<span class="label">{$product.price}</span>
{if $product.has_discount}
<span class="value">{$product.regular_price}</span>
{/if}
</div>
{if $product.unit_price_full}
<div class="{$componentName}__unit-price">
<span class="value">{$product.unit_price_full}</span>
</div>
{/if}
<div class="{$componentName}__quantity">
<span class="label">{l s='Quantity:' d='Shop.Theme.Checkout'}</span>
<span class="value">x{$product.quantity}</span>
</div>
<div class="{$componentName}__gift">
{if !empty($product.is_gift)}
<i class="{$componentName}__gift-icon material-icons" aria-hidden="true">&#xE8B1;</i> {l s='Gift(s)' d='Shop.Theme.Checkout'}
{/if}
</div>
</div>
<div class="{$componentName}__content-right">
<div class="{$componentName}__prices">
<div class="{$componentName}__total">{$product.total}</div>
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
</div>
</div>
</div>
{/block}

View File

@@ -0,0 +1,32 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__products js-cart-summary-products">
<div class="cart-summary__products-number">{$cart.summary_string}</div>
<hr class="mb-2">
<div class="cart-summary__products-accordion accordion accordion-flush accordion--small">
<div class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-target="#cart-summary-product-list" data-bs-toggle="collapse" aria-expanded="false" aria-label="{l s='Show cart details' d='Shop.Theme.Actions'}">
{l s='Show details' d='Shop.Theme.Actions'}
</button>
</div>
{block name='cart_summary__list'}
<div class="accordion-collapse collapse" id="cart-summary-product-list">
<div class="cart-summary__products-list">
{foreach from=$cart.products item=product}
<div class="cart-summary__product">
{include file='checkout/_partials/cart-summary-product-line.tpl' product=$product}
</div>
{/foreach}
</div>
</div>
{/block}
</div>
<hr class="mt-2">
</div>

View File

@@ -0,0 +1,20 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__subtotals js-cart-summary-subtotals-container">
{foreach from=$cart.subtotals item="subtotal"}
{if $subtotal && $subtotal.value|count_characters> 0 && $subtotal.type !== 'tax'}
<div class="cart-summary__line" id="cart-subtotal-{$subtotal.type}">
<span class="cart-summary__label">
{$subtotal.label}
</span>
<span class="cart-summary__value">
{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}
</span>
</div>
{/if}
{/foreach}
</div>

View File

@@ -0,0 +1,8 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__top js-cart-summary-top">
{hook h='displayCheckoutSummaryTop'}
</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.
*}
<div class="cart-summary__total js-cart-summary-totals">
{block name='cart_summary_total'}
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total.label}&nbsp;{$cart.labels.tax_short}</span>
<span class="cart-summary__value">{$cart.totals.total.value}</span>
</div>
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total_including_tax.label}</span>
<span class="cart-summary__value">{$cart.totals.total_including_tax.value}</span>
</div>
{else}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$cart.labels.tax_short}{/if}</span>
<span class="cart-summary__value">{$cart.totals.total.value}</span>
</div>
{/if}
{/block}
{block name='cart_summary_tax'}
{if $cart.subtotals.tax}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{l s='%label%:' sprintf=['%label%' => $cart.subtotals.tax.label] d='Shop.Theme.Global'}</span>
<span class="cart-summary__value">{$cart.subtotals.tax.value}</span>
</div>
{/if}
{/block}
</div>

View File

@@ -0,0 +1,27 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{* .js-cart needed for JS *}
<section id="js-checkout-summary" class="accordion-collapse collapse show js-cart" data-refresh-url="{$urls.pages.cart}?ajax=1&action=refresh">
{block name='hook_checkout_summary_top'}
{include file='checkout/_partials/cart-summary-top.tpl' cart=$cart}
{/block}
{block name='cart_summary_products'}
{include file='checkout/_partials/cart-summary-products.tpl' cart=$cart}
{/block}
{block name='cart_summary_subtotals'}
{include file='checkout/_partials/cart-summary-subtotals.tpl' cart=$cart}
{/block}
{block name='cart_summary_totals'}
{include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart}
{/block}
{block name='cart_summary_voucher'}
{include file='checkout/_partials/cart-voucher.tpl'}
{/block}
</section>

View File

@@ -0,0 +1,78 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $cart.vouchers.allowed}
{block name='cart_voucher'}
<div class="cart-summary__voucher cart-voucher js-cart-voucher" tabindex="-1" data-ps-ref="voucher-container">
{if $cart.vouchers.added}
{block name='cart_voucher_list'}
<ul class="cart-voucher__list" tabindex="-1" data-ps-ref="voucher-list" aria-label="{l s='Added vouchers' d='Shop.Theme.Checkout'}">
{foreach from=$cart.vouchers.added item=voucher}
<li class="cart-summary__line">
<span class="cart-summary__label cart-summary__label--voucher">
<i class="material-icons" aria-hidden="true">&#xF05B;</i>
{$voucher.name}
</span>
<div class="cart-summary__value cart-summary__value--bold cart-voucher__value">
{$voucher.reduction_formatted}
{if isset($voucher.code) && $voucher.code !== ''}
<a class="cart-voucher__remove" href="{$voucher.delete_url}" data-link-action="remove-voucher" data-ps-ref="voucher-remove-button" aria-label="{l s='Remove voucher: %voucherName%' sprintf=['%voucherName%' => $voucher.name] d='Shop.Theme.Checkout'}">
<i class="material-icons" aria-hidden="true">&#xE872;</i>
</a>
{/if}
</div>
</li>
{/foreach}
</ul>
{/block}
{/if}
<div class="cart-voucher__accordion accordion accordion-flush accordion--small">
<div class="cart-voucher__accordion-item accordion-item">
<button class="cart-voucher__accordion-button accordion-button collapsed" type="button" data-bs-target="#promo-code" data-bs-toggle="collapse" data-ps-ref="voucher-accordion-button" aria-expanded="false">
{l s='Promo code' d='Shop.Theme.Checkout'}
</button>
<div id="promo-code" class="cart-voucher__accordion-collapse accordion-collapse collapse js-voucher-accordion">
<div class="accordion-body">
{block name='cart_voucher_form'}
<form class="cart-voucher__form" action="{$urls.pages.cart}" data-link-action="add-voucher" data-ps-ref="voucher-form" method="post">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="addDiscount" value="1">
<input class="form-control js-voucher-input" type="text" name="discount_name" placeholder="{l s='Paste your voucher here' d='Shop.Theme.Checkout'}" required>
<button type="submit" class="btn btn-primary" aria-label="{l s='Apply voucher' d='Shop.Theme.Actions'}">{l s='Apply' d='Shop.Theme.Actions'}</button>
</form>
{/block}
{block name='cart_voucher_notifications'}
<div class="cart-voucher__error alert alert-danger js-error" role="alert" tabindex="-1" style="display: none;" data-ps-ref="voucher-error">
<i class="cart-voucher__error-icon material-icons" aria-hidden="true">&#xE001;</i>
<span class="js-error-text"></span>
</div>
{/block}
</div>
</div>
</div>
</div>
{if $cart.discounts|count> 0}
<div class="cart-voucher__highlight">
<p class="h5">
{l s='Take advantage of our exclusive offers:' d='Shop.Theme.Actions'}
</p>
<ul class="cart-voucher__offers js-discount">
{foreach from=$cart.discounts item=discount}
<li class="cart-voucher__code">
<button class="cart-voucher__code-value js-voucher-code" aria-label="{l s='Fill %voucherCode% code into the voucher field' sprintf=['%voucherCode%' => $discount.code] d='Shop.Theme.Checkout'}">{$discount.code}</button> - {$discount.name}
</li>
{/foreach}
</ul>
</div>
{/if}
</div>
{/block}
{/if}

View File

@@ -0,0 +1,13 @@
{$componentName = 'checkout-steps'}
<div class="{$componentName}__step-mobile d-none" data-step="{$step}">
<p class="{$componentName}__title">
{$title}
</p>
{if !empty($subtitle)}
<p class="{$componentName}__subtitle">
{$subtitle}
</p>
{/if}
</div>

View File

@@ -0,0 +1,23 @@
{$componentName = 'checkout-steps'}
<li
class="{$componentName}__step js-step-item"
data-step="{$step}"
role="presentation"
>
<span class="{$componentName}__number">
{$number}
</span>
<button
class="{$componentName}__btn btn btn-link"
data-bs-toggle="tab"
data-bs-target="#{$step}"
role="tab"
data-ps-ref="step-button"
{if isset($virtual) && $virtual}
disabled
{/if}
>
{$title}
</button>
</li>

View File

@@ -0,0 +1,41 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends "customer/_partials/customer-form.tpl"}
{block "form_field"}
{if $field.name === 'password' and $guest_allowed}
<div class="mb-3">
<div class="form-check">
<input class="js-password-form__check form-check-input" id="password-form__check" type="checkbox" name="password-form__check">
<label class="form-check-label" for="password-form__check">
<span class="fw-bold">{l s='Create an account' d='Shop.Theme.Checkout'}</span> <small class="fw-normal">{l s='(optional)' d='Shop.Theme.Checkout'}</small>
<br>
<em>{l s='And save time on your next order!' d='Shop.Theme.Checkout'}</em>
</label>
</div>
<div class="js-password-form__input-wrapper d-none mt-3">
{$smarty.block.parent}
</div>
</div>
{else}
{$smarty.block.parent}
{/if}
{/block}
{block "form_buttons"}
<button
class="btn btn-primary"
name="continue"
data-link-action="register-new-customer"
type="submit"
value="1"
data-ps-action="form-validation-submit"
>
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
{/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='customer/_partials/login-form.tpl'}
{block name='form_buttons'}
<button
class="btn btn-primary"
name="continue"
data-link-action="sign-in"
type="submit"
value="1"
data-ps-action="form-validation-submit"
>
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
{/block}

View File

@@ -0,0 +1,22 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="checkout-modal" class="modal fade" tabindex="-1" role="dialog" aria-label="{l s='Terms and conditions' d='Shop.Theme.Checkout'}" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<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">
<div class="text-center">
<div class="spinner-border text-primary-emphasis" role="status">
<span class="visually-hidden">{l s='Loading...' d='Shop.Theme.Global'}</span>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,320 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'order-confirmation'}
<div class="{$componentName}__table {block name='order-confirmation-classes'}{/block}">
<div class="{$componentName}__products">
{foreach from=$products['physical_products'] item=product}
<div class="{$componentName}__carrier-info">
<div class="{$componentName}__carrier-info-content">
<b class="{$componentName}__carrier-info-label">{l s='Delivery option: %carrier_name%' sprintf=['%carrier_name%' => $product.carrier.name] d='Shop.Theme.Global'}</b>
<p class="{$componentName}__carrier-info-delay">{$product.carrier.delay}</p>
</div>
{if empty($hide_multishipment_edit_buttons)}
<button class="{$componentName}__carrier-info-edit-button btn btn-outline-primary btn-sm js-edit-shipping" data-step="checkout-delivery-step" aria-label="{l s='Edit your shipping method' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
{/if}
</div>
{foreach from=$product['products'] item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{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="{$componentName}__product-img 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="{$componentName}__product-img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
{if !empty($product.is_gift)}
<div class="{$componentName}__product-gift">
<i class="{$componentName}__product-gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</div>
{else}
<div class="{$componentName}__product-total">
{$product.total}
</div>
{/if}
</div>
</div>
</div>
{/foreach}
{/foreach}
{if isset($products['virtual_products']) && !empty($products['virtual_products'])}
<div class="{$componentName}__virtual-info {if isset($products['physical_products']) && empty($products['physical_products'])}mt-0{/if}">
<div class="{$componentName}__virtual-info-content">
<b class="{$componentName}__virtual-info-label">{l s='Virtual product(s)' d='Shop.Theme.Global'}</b>
<p class="{$componentName}__virtual-info-value">{l s='No delivery service' d='Shop.Theme.Global'}</p>
</div>
</div>
{foreach from=$products['virtual_products'] item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{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="{$componentName}__product-img 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="{$componentName}__product-img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
<div class="{$componentName}__product-total">
{$product.total}
</div>
</div>
</div>
</div>
{/foreach}
{/if}
</div>
<hr>
<div class="{$componentName}__subtotals">
{foreach $subtotals as $subtotal}
{if $subtotal !== null && $subtotal.type !== 'tax' && $subtotal.label !== null}
<div class="{$componentName}__line">
<div class="{$componentName}__line-label">{$subtotal.label}</div>
<div class="{$componentName}__line-value">{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}</div>
</div>
{/if}
{/foreach}
</div>
<hr>
<div class="{$componentName}__totals">
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{$labels.tax_short}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total_including_tax.label}</div>
<div class="{$componentName}__line-value">{$totals.total_including_tax.value}</div>
</div>
{else}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$labels.tax_short}{/if}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
{/if}
{if $subtotals.tax !== null && $subtotals.tax.label !== null}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{l s='%label%:' sprintf=['%label%' => $subtotals.tax.label] d='Shop.Theme.Global'}</div>
<div class="{$componentName}__line-value">{$subtotals.tax.value}</div>
</div>
{/if}
</div>
</div>

View File

@@ -0,0 +1,177 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'order-confirmation'}
<div class="{$componentName}__table {block name='order-confirmation-classes'}{/block}">
<div class="{$componentName}__products">
{foreach from=$products item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{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="{$componentName}__product-img 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="{$componentName}__product-img 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}"
loading="lazy"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
{if !empty($product.is_gift)}
<div class="{$componentName}__product-gift">
<i class="{$componentName}__product-gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</div>
{else}
<div class="{$componentName}__product-total">
{$product.total}
</div>
{/if}
</div>
</div>
</div>
{/foreach}
</div>
<hr>
<div class="{$componentName}__subtotals">
{foreach $subtotals as $subtotal}
{if $subtotal !== null && $subtotal.type !== 'tax' && $subtotal.label !== null}
<div class="{$componentName}__line">
<div class="{$componentName}__line-label">{$subtotal.label}</div>
<div class="{$componentName}__line-value">{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}</div>
</div>
{/if}
{/foreach}
</div>
<hr>
<div class="{$componentName}__totals">
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{$labels.tax_short}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total_including_tax.label}</div>
<div class="{$componentName}__line-value">{$totals.total_including_tax.value}</div>
</div>
{else}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$labels.tax_short}{/if}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
{/if}
{if $subtotals.tax !== null && $subtotals.tax.label !== null}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{l s='%label%:' sprintf=['%label%' => $subtotals.tax.label] d='Shop.Theme.Global'}</div>
<div class="{$componentName}__line-value">{$subtotals.tax.value}</div>
</div>
{/if}
</div>
</div>

View File

@@ -0,0 +1,5 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/order-confirmation-table-multishipment.tpl'}

View File

@@ -0,0 +1,5 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/order-confirmation-table.tpl'}

View File

@@ -0,0 +1,162 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<hr>
<section id="order-summary-content" class="final-summary">
<p class="h2">{l s='Please check your order before payment' d='Shop.Theme.Checkout'}</p>
<p class="final-summary__header">
{l s='Addresses' d='Shop.Theme.Checkout'}
<button class="btn btn-outline-primary btn-sm js-edit-addresses" data-step="checkout-addresses-step" aria-label="{l s='Edit addresses' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
</p>
<div class="address__list">
<div class="address-card">
<div class="address-card__container">
<div class="address-card__header">
<span class="address-card__alias">
{l s='Your Delivery Address' d='Shop.Theme.Checkout'}
</span>
</div>
<address class="address-card__content">
{$customer.addresses[$cart.id_address_delivery]['formatted'] nofilter}
</address>
<div class="address-card__actions">
<a
class="address-card__edit"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_delivery]['id'], 'editAddress' => 'editAddress', 'token' => $token]}"
aria-label="{l s='Edit your delivery address' d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="address-card__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_delivery]['id'], 'deleteAddress' => 'deleteAddress', 'token' => $token]}"
aria-label="{l s='Delete your delivery address' d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
</div>
</div>
<div class="address-card">
<div class="address-card__container">
<div class="address-card__header">
<span class="address-card__alias">
{l s='Your Invoice Address' d='Shop.Theme.Checkout'}
</span>
</div>
<address class="address-card__content">
{$customer.addresses[$cart.id_address_invoice]['formatted'] nofilter}
</address>
<div class="address-card__actions">
<a
class="address-card__edit"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_invoice]['id'], 'editAddress' => 'editAddress', 'token' => $token]}"
aria-label="{l s='Edit your invoice address' d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="address-card__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_invoice]['id'], 'deleteAddress' => 'deleteAddress', 'token' => $token]}"
aria-label="{l s='Delete your invoice address' d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
</div>
</div>
</div>
{if !$cart.is_virtual && !($is_multishipment_enabled|default:false)}
<p class="final-summary__header">
{l s='Shipping Method' d='Shop.Theme.Checkout'}
<button class="btn btn-outline-primary btn-sm js-edit-shipping" data-step="checkout-delivery-step" aria-label="{l s='Edit your shipping method' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
</p>
<div class="grid-table" role="table" aria-label="{l s='Shipping Method' d='Shop.Theme.Checkout'}">
<div class="grid-table__inner grid-table__inner--3" role="rowgroup">
<div class="grid-table__header" role="row">
<span class="grid-table__cell" role="columnheader">{l s='Delivery Option' d='Shop.Theme.Checkout'}</span>
<span class="grid-table__cell" role="columnheader">{l s='Price' d='Shop.Theme.Checkout'}</span>
<span class="grid-table__cell" role="columnheader">{l s='Delivery Information' d='Shop.Theme.Checkout'}</span>
</div>
<div class="grid-table__row" role="row">
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Delivery Option' d='Shop.Theme.Checkout'}">
<span class="grid-table__cell-group grid-table__cell-group--sm grid-table__cell-group--inline">
{if $selected_delivery_option.logo}
<img src="{$selected_delivery_option.logo}" class="rounded img-fluid" width="32" height="auto" alt="{$selected_delivery_option.name}" loading="lazy">
{/if}
{$selected_delivery_option.name}
</span>
</span>
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Price' d='Shop.Theme.Checkout'}">
{$selected_delivery_option.price}
</span>
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Delivery Information' d='Shop.Theme.Checkout'}">
{$selected_delivery_option.delay}
</span>
</div>
</div>
</div>
{/if}
{block name='order_confirmation_table'}
<p class="final-summary__header">
{l s='%product_count% order items' sprintf=['%product_count%' => $cart.products_count] d='Shop.Theme.Checkout'}
<a class="btn btn-outline-primary btn-sm" href="{url entity=cart params=['action' => 'show']}" aria-label="{l s='Edit your cart' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</a>
</p>
<div class="final-summary__order-table card border-1 mb-4">
<div class="card-body">
{if isset($is_multishipment_enabled) && $is_multishipment_enabled}
{include file='checkout/_partials/order-final-summary-table-multishipment.tpl'
products=$products_carrier_mapping
products_count=$cart.products_count
subtotals=$cart.subtotals
totals=$cart.totals
labels=$cart.labels
add_product_link=true
}
{else}
{include file='checkout/_partials/order-final-summary-table.tpl'
products=$cart.products
products_count=$cart.products_count
subtotals=$cart.subtotals
totals=$cart.totals
labels=$cart.labels
add_product_link=true
}
{/if}
</div>
</div>
{/block}
</section>

View File

@@ -0,0 +1,129 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
<div class="js-address-form">
<form
method="POST"
action="{url entity='order' params=['id_address' => $id_address]}"
data-refresh-url="{url entity='order' params=['ajax' => 1, 'action' => 'addressForm', 'id_address' => $id_address]}"
data-ps-action="form-validation"
>
{if $use_same_address}
<p>
{if $cart.is_virtual}
{l s='The selected address will be used as your personal address (for invoice).' d='Shop.Theme.Checkout'}
{else}
{l s='The selected address will be used both as your personal address (for invoice) and as your delivery address.' d='Shop.Theme.Checkout'}
{/if}
</p>
{else}
<p class="h3">{l s='Shipping Address' d='Shop.Theme.Checkout'}</p>
{/if}
{if $show_delivery_address_form}
<div id="delivery-address">
{render file = 'checkout/_partials/address-form.tpl'
ui = $address_form
use_same_address = $use_same_address
type = "delivery"
form_has_continue_button = $form_has_continue_button
}
</div>
{elseif $customer.addresses|count> 0}
<div id="delivery-addresses" class="address__list js-address-selector">
{include file = 'checkout/_partials/address-selector-block.tpl'
addresses = $customer.addresses
name = "id_address_delivery"
selected = $id_address_delivery
type = "delivery"
interactive = !$show_delivery_address_form and !$show_invoice_address_form
}
</div>
{if isset($delivery_address_error)}
<p class="alert alert-danger js-address-error" name="alert-delivery" id="id-failure-address-{$delivery_address_error.id_address}">{$delivery_address_error.exception}</p>
{else}
<p class="alert alert-danger js-address-error" name="alert-delivery" style="display: none">{l s='Your address is incomplete, please update it.' d='Shop.Notifications.Error'}</p>
{/if}
<div class="buttons-wrapper mb-3">
<a href="{$new_address_delivery_url}" class="btn btn-outline-primary">
<i class="material-icons" aria-hidden="true">&#xE145;</i>
{l s='Add new address' d='Shop.Theme.Actions'}
</a>
</div>
{if $use_same_address && !$cart.is_virtual}
<a data-link-action="different-invoice-address" href="{$use_different_address_url}" class="btn btn-basic">
{l s='Billing address differs from shipping address' d='Shop.Theme.Checkout'}
</a>
{/if}
{/if}
{if !$use_same_address}
<p class="h3 mt-4">{l s='Your Invoice Address' d='Shop.Theme.Checkout'}</p>
{if $show_invoice_address_form}
<div id="invoice-address">
{render file = 'checkout/_partials/address-form.tpl'
ui = $address_form
use_same_address = $use_same_address
type = "invoice"
form_has_continue_button = $form_has_continue_button
}
</div>
{else}
<div id="invoice-addresses" class="address__list js-address-selector">
{include file = 'checkout/_partials/address-selector-block.tpl'
addresses = $customer.addresses
name = "id_address_invoice"
selected = $id_address_invoice
type = "invoice"
interactive = !$show_delivery_address_form and !$show_invoice_address_form
}
</div>
{if isset($invoice_address_error)}
<p class="alert alert-danger js-address-error" name="alert-invoice" id="id-failure-address-{$invoice_address_error.id_address}">{$invoice_address_error.exception}</p>
{else}
<p class="alert alert-danger js-address-error" name="alert-invoice" style="display: none">{l s='Your address is incomplete, please update it.' d='Shop.Notifications.Error'}</p>
{/if}
<a href="{$new_address_invoice_url}" class="btn btn-outline-primary w-100 w-md-auto">
<i class="material-icons" aria-hidden="true">&#xE145;</i>
{l s='Add new address' d='Shop.Theme.Actions'}
</a>
{/if}
{/if}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary js-back" type="button" data-step="checkout-personal-information-step">
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</i>
{l s='Back to Personal Information' d='Shop.Theme.Actions'}
</button>
{if !$form_has_continue_button}
<button type="submit" class="btn btn-primary" name="confirm-addresses" value="1">
{l s='Continue to Shipping' d='Shop.Theme.Actions'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
<input type="hidden" id="not-valid-addresses" class="js-not-valid-addresses" value="{$not_valid_addresses}">
{/if}
</div>
</form>
{capture name="address_selector_bottom"}{hook h='displayAddressSelectorBottom'}{/capture}
{if $smarty.capture.address_selector_bottom}
{block name='address_selector_bottom'}
<div class="address-selector-bottom mt-3">
{$smarty.capture.address_selector_bottom nofilter}
</div>
{/block}
{/if}
</div>
{/block}

View File

@@ -0,0 +1,39 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='step'}
<section
id="{$identifier}"
class="{[
'step' => true,
'tab-pane' => true,
'collapse' => true,
'step--current' => $step_is_current,
'step--reachable' => $step_is_reachable,
'step--complete' => $step_is_complete && !$step_is_current,
'js-current-step' => $step_is_current,
'active' => $step_is_current,
'show' => $step_is_current
]|classnames}" role="tabpanel">
<div class="step__title js-step-title">
{if $step_is_current eq true}
<h1 class="page-title-section">
{else}
<p class="page-title-section">
{/if}
{$title}
{if $step_is_current eq true}
</h1>
{else}
</p>
{/if}
<hr>
</div>
<div class="step__content">
{block name='step_content'}DUMMY STEP CONTENT{/block}
</div>
</section>
{/block}

View File

@@ -0,0 +1,177 @@
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
{hook h='displayPaymentTop'}
{* used by javascript to correctly handle cart updates when we are on payment step (eg vouchers added) *}
<div style="display:none" class="js-cart-payment-step-refresh"></div>
{if !empty($display_transaction_updated_info)}
<p class="payment-options__updated">
{l s='Transaction amount has been correctly updated' d='Shop.Theme.Checkout'}
</p>
{/if}
{if $is_free}
<p class="payment-options__free">{l s='No payment needed for this order' d='Shop.Theme.Checkout'}</p>
{/if}
<div class="payment-options__list{if $is_free} d-block d-sm-none{/if}">
{foreach from=$payment_options item="module_options"}
{foreach from=$module_options item="option"}
<div id="{$option.id}-container" class="payment-option">
{* This is the way an option should be selected when Javascript is enabled *}
<div class="payment-option__form-check form-check">
<input
class="payment-option__input form-check-input ps-shown-by-js {if $option.binary} binary{/if}"
type="radio"
name="payment-option"
data-module-name="{$option.module_name}"
id="{$option.id}"
{if ($selected_payment_option == $option.id || $is_free) || ($payment_options|@count === 1 && $module_options|@count === 1)} checked {/if}
>
<label class="payment-option__label form-check-label" for="{$option.id}">
{if $option.logo}
<img class="img-fluid" src="{$option.logo}" loading="lazy">
{/if}
{$option.call_to_action_text}
</label>
</div>
{* This is the way an option should be selected when Javascript is disabled *}
<form method="GET" class="payment-option__no-js-form ps-hidden-by-js">
{if $option.id === $selected_payment_option}
{l s='Selected' d='Shop.Theme.Checkout'}
{else}
<button class="ps-hidden-by-js" type="submit" name="select_payment_option" value="{$option.id}">
{l s='Choose' d='Shop.Theme.Actions'}
</button>
{/if}
</form>
{if $option.additionalInformation}
<div
id="{$option.id}-additional-information"
class="payment-option__additional-information js-additional-information"
{if $option.id != $selected_payment_option}style="display: none;"{/if}
>
{$option.additionalInformation nofilter}
</div>
{/if}
<div
id="pay-with-{$option.id}-form"
class="js-payment-option-form"
{if $option.id != $selected_payment_option}style="display: none;"{/if}
>
{if $option.form}
{$option.form nofilter}
{else}
<form id="payment-form" method="POST" action="{$option.action nofilter}">
{foreach from=$option.inputs item=input}
<input type="{$input.type}" name="{$input.name}" value="{$input.value}">
{/foreach}
<button style="display:none" id="pay-with-{$option.id}" type="submit"></button>
</form>
{/if}
</div>
</div>
{/foreach}
{foreachelse}
<p class="alert alert-danger">{l s='Unfortunately, there are no payment method available.' d='Shop.Theme.Checkout'}</p>
{/foreach}
</div>
{if $conditions_to_approve|count}
<p class="ps-hidden-by-js">
{* At the moment, we're not showing the checkboxes when JS is disabled
because it makes ensuring they were checked very tricky and overcomplicates
the template. Might change later.
*}
{l s='By confirming the order, you certify that you have read and agree with all of the conditions below:' d='Shop.Theme.Checkout'}
</p>
<form id="conditions-to-approve" class="js-conditions-to-approve mt-3" method="GET">
{foreach from=$conditions_to_approve item="condition" key="condition_name"}
<div class="my-2 form-check">
<input id = "conditions_to_approve[{$condition_name}]"
name = "conditions_to_approve[{$condition_name}]"
required
type = "checkbox"
value = "1"
class = "ps-shown-by-js form-check-input"
>
<label class="js-terms form-check-label" for="conditions_to_approve[{$condition_name}]">
{$condition nofilter}
</label>
</div>
{/foreach}
</form>
{/if}
{hook h='displayCheckoutBeforeConfirmation'}
{if $show_final_summary}
{include file='checkout/_partials/order-final-summary.tpl'}
{/if}
{if $show_final_summary}
<article class="alert alert-danger mb-4 js-alert-payment-conditions" role="alert">
{if isset($tos_cms) && $tos_cms && $conditions_to_approve|count == 1}
{l
s='Please make sure you\'ve chosen a [1]payment method[/1] and accepted the [2]terms and conditions[/2].'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>',
'[2]' => '<a href="#conditions-to-approve" class="alert-link">',
'[/2]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{elseif !empty($conditions_to_approve)}
{l
s='Please make sure you\'ve chosen a [1]payment method[/1] and accepted the required condition(s).'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{else}
{l s='Please make sure you\'ve chosen a [1]payment method[/1].'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{/if}
</article>
{/if}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary js-back" type="button" data-step="checkout-delivery-step">
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</div>
{l s='Back to Shipping' d='Shop.Theme.Actions'}
</button>
<div id="payment-confirmation" class="js-payment-confirmation">
<div class="ps-shown-by-js">
<button type="submit" class="btn btn-primary {if !$selected_payment_option} disabled{/if}">
{l s='Place Order' d='Shop.Theme.Checkout'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
</div>
<div class="ps-hidden-by-js">
{if $selected_payment_option and $all_conditions_approved}
<label for="pay-with-{$selected_payment_option}">{l s='Order with an obligation to pay' d='Shop.Theme.Checkout'}</label>
{/if}
</div>
</div>
</div>
{hook h='displayPaymentByBinaries'}
{/block}

View File

@@ -0,0 +1,100 @@
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{$stepName = 'personnal-information'}
{block name='step_content'}
{hook h='displayPersonalInformationTop' customer=$customer}
{if $customer.is_logged && !$customer.is_guest}
<div class="step__account">
<p>
{* [1][/1] is for a HTML tag. *}
{l s='Connected as [1]%firstname% %lastname%[/1].'
d='Shop.Theme.Customeraccount'
sprintf=[
'[1]' => "<a href='{$urls.pages.identity}' aria-label='{l s='My account (%firstname% %lastname%)' d='Shop.Theme.Customeraccount' sprintf=['%firstname%' => $customer.firstname, '%lastname%' => $customer.lastname]}'>",
'[/1]' => "</a>",
'%firstname%' => $customer.firstname,
'%lastname%' => $customer.lastname
]
}
</p>
<p class="mb-1">
{* [1][/1] is for a HTML tag. *}
{l
s='Not you? [1]Sign out[/1]'
d='Shop.Theme.Customeraccount'
sprintf=[
'[1]' => "<a class='text-danger' href='{$urls.actions.logout}'>",
'[/1]' => "</a>"
]
}
</p>
{if !isset($empty_cart_on_logout) || $empty_cart_on_logout}
<p class="mb-0">
<small class="text-body-tertiary">{l s='If you sign out now, your cart will be emptied.' d='Shop.Theme.Checkout'}</small>
</p>
{/if}
</div>
<form id="checkout-continue-form" method="GET" action="{$urls.pages.order}">
<div class="buttons-wrapper buttons-wrapper--end mt-3">
<button
class="btn btn-primary"
name="controller"
type="submit"
value="order"
>
{l s='Continue to Addresses' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
</div>
</form>
{else}
<ul class="nav nav-underline" id="personal-information-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button
class="nav-link {if !$show_login_form}active{/if}"
data-bs-toggle="tab"
data-bs-target="#checkout-guest-form"
type="button"
role="tab"
aria-controls="checkout-guest-form"
aria-selected="{if !$show_login_form}true{else}false{/if}"
>
{if isset($guest_allowed) && $guest_allowed}
{l s='Order as a guest' d='Shop.Theme.Checkout'}
{else}
{l s='New customer' d='Shop.Theme.Checkout'}
{/if}
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link {if $show_login_form}active{/if}"
data-bs-toggle="tab"
data-bs-target="#checkout-login-form"
type="button"
role="tab"
aria-controls="checkout-login-form"
aria-selected="{if $show_login_form}true{else}false{/if}"
>
{l s='Sign in' d='Shop.Theme.Actions'}
</button>
</li>
</ul>
<div class="tab-content" id="personal-information-tabs-content">
<div class="tab-pane fade{if !$show_login_form} show active{/if}" id="checkout-guest-form" aria-labelledby="checkout-guest-form" role="tabpanel">
{render file='checkout/_partials/customer-form.tpl' ui=$register_form guest_allowed=$guest_allowed}
</div>
<div class="tab-pane fade{if $show_login_form} show active{/if}" id="checkout-login-form" aria-labelledby="checkout-login-form" role="tabpanel">
{render file='checkout/_partials/login-form.tpl' ui=$login_form}
</div>
</div>
{/if}
{/block}

View File

@@ -0,0 +1,113 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
<div id="delivery-options__hook">
{$hookDisplayBeforeCarrier nofilter}
</div>
<div class="delivery-options__container">
{if $delivery_options|count}
<form
id="js-delivery"
data-url-update="{url entity='order' params=['ajax' => 1, 'action' => 'selectDeliveryOption']}"
method="post"
class="delivery-options__form"
>
{block name='delivery_options'}
<div class="delivery-options__list">
{foreach from=$delivery_options item=carrier key=carrier_id name=delivery_options}
<div class="delivery-option__item js-delivery-option">
<label class="delivery-option__label" for="delivery_option_{$carrier.id}">
<div class="delivery-option__left">
<span class="delivery-option__check form-check">
<input type="radio" class="form-check-input" name="delivery_option[{$id_address}]" id="delivery_option_{$carrier.id}" value="{$carrier_id}"{if $delivery_option == $carrier_id} checked{/if}>
</span>
<div class="delivery-option__carrier {if $carrier.logo} delivery-option__carrier--hasLogo{/if}">
{if $carrier.logo}
<img class="delivery-option__carrier-logo" src="{$carrier.logo}" class="img-fluid" alt="{$carrier.name}" loading="lazy" aria-hidden="true">
{/if}
<span class="delivery-option__carrier-name">{$carrier.name}</span>
</div>
</div>
<div class="delivery-option__content">
{$carrier.delay}
</div>
<div class="delivery-option__price">
{$carrier.price}
</div>
</label>
<div class="delivery-option__extra js-carrier-extra" {if $delivery_option == $carrier_id}data-active{/if}>
{capture name='delivery_option_extra_content'}{$carrier.extraContent nofilter}{/capture}
{if !empty($smarty.capture.delivery_option_extra_content)}
<div class="delivery-option__extra-content js-carrier-extra-content">
{$smarty.capture.delivery_option_extra_content nofilter}
</div>
{/if}
</div>
</div>
{/foreach}
</div>
{/block}
<div class="order-options">
<div id="delivery" class="mb-4">
<label for="delivery_message" class="form-label">{l s='Write a comment about this order' d='Shop.Theme.Checkout'}</label>
<textarea class="form-control" rows="2" cols="120" id="delivery_message" placeholder="{l s='Write your comment...' d='Shop.Theme.Checkout'}" name="delivery_message">{$delivery_message}</textarea>
</div>
{if $recyclablePackAllowed}
<div class="form-check" for="input_recyclable">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" id="input_recyclable" name="recyclable" value="1"{if $recyclable} checked{/if}>
{l s='I would like to receive my order in recycled packaging.' d='Shop.Theme.Checkout'}
</label>
</div>
{/if}
{if $gift.allowed}
<div class="form-check mb-4">
<label class="form-check-label" for="input_gift" data-bs-toggle="collapse" data-bs-target="#gift">
<input class="form-check-input js-gift-checkbox" id="input_gift" name="gift" type="checkbox" value="1"{if $gift.isGift} checked="checked"{/if}>
{$gift.label}
</label>
</div>
<div id="gift" class="collapse{if $gift.isGift} show{/if}">
<label for="gift_message" class="form-label">{l s='If you\'d like, you can add a note to the gift:' d='Shop.Theme.Checkout'}</label>
<textarea class="form-control" rows="2" cols="120" id="gift_message" name="gift_message">{$gift.message}</textarea>
</div>
{/if}
</div>
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary w-100 w-md-auto mb-3 mb-md-0 js-back" type="button" data-step="checkout-addresses-step">
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</div>
{l s='Back to Addresses' d='Shop.Theme.Actions'}
</button>
<button type="submit" class="btn btn-primary w-100 w-md-auto" name="confirmDeliveryOption" value="1">
{l s='Continue to Payment' d='Shop.Theme.Actions'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
</div>
</form>
{else}
<p class="alert alert-danger">{l s='Unfortunately, there are no carriers available for your delivery address.' d='Shop.Theme.Checkout'}</p>
{/if}
</div>
<div class="delivery-options__display-after-carrier" id="hook-display-after-carrier">
{$hookDisplayAfterCarrier nofilter}
</div>
<div class="delivery-options__extra-carrier" id="extra_carrier"></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.
*}
{block name='step'}
<section class="step step--unreachable d-none" id="{$identifier}">
<div class="step__title js-step-title">
<p class="step__title-left h3">
{$title}
</p>
</div>
</section>
{/block}

View File

@@ -0,0 +1,24 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/cart.tpl'}
{block name='continue_shopping' append}
<a class="cart__continue-shopping btn btn-outline-primary" href="{$urls.pages.index}">
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</i>
{l s='Continue shopping' d='Shop.Theme.Actions'}
</a>
{/block}
{block name='cart_actions'}
<div class="cart-summary__actions checkout">
<div class="d-grid">
<button type="button" class="btn btn-primary disabled" disabled>{l s='Checkout' d='Shop.Theme.Actions'}</button>
</div>
</div>
{/block}
{block name='continue_shopping'}{/block}
{block name='cart_voucher'}{/block}
{block name='display_reassurance'}{/block}

View File

@@ -0,0 +1,66 @@
{**
* 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'}
<div class="cart-grid row">
<!-- Left Block: cart product informations & shipping -->
<div class="cart-grid__content col-lg-8">
{include file='components/page-title-section.tpl' title={l s='Shopping Cart' d='Shop.Theme.Checkout'}}
{block name="cart_update_alert"}
<div class="js-cart-update-alert" data-ps-data="{l s='has been removed from the cart.' d='Shop.Theme.Actions' js=1}" data-ps-data-close="{l s='Close' d='Shop.Theme.Actions' js=1}" aria-atomic="true"></div>
{/block}
<!-- cart products detailed -->
<div class="cart-grid__products-details js-cart-container">
{block name='cart_overview'}
{include file='checkout/_partials/cart-detailed.tpl' cart=$cart}
{/block}
{block name='continue_shopping'}
<a class="cart__continue-shopping btn btn-outline-primary" href="{$urls.pages.index}">
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</i>
{l s='Continue shopping' d='Shop.Theme.Actions'}
</a>
{/block}
<!-- shipping informations -->
{block name='hook_shopping_cart_footer'}
{hook h='displayShoppingCartFooter'}
{/block}
</div>
</div>
<!-- Right Block: cart subtotal & cart total -->
<div class="cart-grid__aside col-lg-4">
<div class="cart-grid__aside-wrapper">
<h2>{l s='Order summary' d='Shop.Theme.Checkout'}</h2>
{block name='cart_summary'}
<div class="cart-summary js-cart-summary">
{block name='hook_shopping_cart'}
{hook h='displayShoppingCart'}
{/block}
{block name='cart_totals'}
{include file='checkout/_partials/cart-detailed-totals.tpl' cart=$cart}
{/block}
</div>
{/block}
<hr>
{block name='hook_reassurance'}
{hook h='displayReassurance'}
{/block}
</div>
</div>
</div>
<div class="cart-grid__footer row">
{hook h='displayCrossSellingShoppingCart'}
</div>
{/block}

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.
*}
{$componentName = 'checkout-steps'}
{if !isset($notifications)}
{$hasNotifications = $notifications.warning|@count > 0 || $notifications.error|@count > 0 || $notifications.success|@count > 0 || $notifications.info|@count > 0}
{/if}
{block name='checkout_steps'}
<div class="{$componentName} {if isset($notifications) && isset($hasNotifications) && $hasNotifications} {$componentName}--has-notifications{/if}">
<div class="{$componentName}__desktop">
<ul class="{$componentName}__list" role="tablist">
{* Personal Information *}
{include file='checkout/_partials/checkout-navigation-step.tpl' number="{l s='1' d='Shop.Theme.Checkout'}"
step="checkout-personal-information-step" title="{l s='Personal Information' d='Shop.Theme.Checkout'}"}
{* Addresses *}
{include file='checkout/_partials/checkout-navigation-step.tpl' number="{l s='2' d='Shop.Theme.Checkout'}"
step="checkout-addresses-step" title="{l s='Addresses' d='Shop.Theme.Checkout'}"}
{* Shipping method *}
{include file='checkout/_partials/checkout-navigation-step.tpl' number="{l s='3' d='Shop.Theme.Checkout'}"
step="checkout-delivery-step" title="{l s='Shipping method' d='Shop.Theme.Checkout'}" virtual=$cart.is_virtual}
{* Payment *}
{include file='checkout/_partials/checkout-navigation-step.tpl' number="{l s='4' d='Shop.Theme.Checkout'}"
step="checkout-payment-step" title="{l s='Payment' d='Shop.Theme.Checkout'}"}
</ul>
</div>
<div class="{$componentName}__mobile">
<div class="{$componentName}__left">
{include file='components/progress-circle.tpl' classes="text-success" size=74 stroke=4}
</div>
<div class="{$componentName}__right">
{* Personal Information *}
{include file='checkout/_partials/checkout-navigation-step-mobile.tpl' step="checkout-personal-information-step" title="{l s='Personal Information' d='Shop.Theme.Checkout'}"
subtitle="{l s='Next: Addresses' d='Shop.Theme.Checkout'}"}
{* Addresses *}
{include file='checkout/_partials/checkout-navigation-step-mobile.tpl' step="checkout-addresses-step" title="{l s='Addresses' d='Shop.Theme.Checkout'}"
subtitle="{l s='Next: Shipping Method' d='Shop.Theme.Checkout'}"}
{* Shipping Method *}
{include file='checkout/_partials/checkout-navigation-step-mobile.tpl' step="checkout-delivery-step" title="{l s='Shipping Method' d='Shop.Theme.Checkout'}"
subtitle="{l s='Next: Payment' d='Shop.Theme.Checkout'}"}
{* Payment *}
{include file='checkout/_partials/checkout-navigation-step-mobile.tpl' step="checkout-payment-step" title="{l s='Payment' d='Shop.Theme.Checkout'}"}
</div>
</div>
</div>
{/block}

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.
*}
{foreach from=$steps item="step" key="index"}
{render identifier = $step.identifier
position = ($index + 1)
ui = $step.ui
}
{/foreach}

View File

@@ -0,0 +1,57 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{block name='notifications'}
{/block}
{block name='breadcrumb'}
{/block}
{block name='content_columns'}
{include file='checkout/checkout-navigation.tpl'}
{block name='checkout_notifications'}
{include file='_partials/notifications.tpl'}
{/block}
<div class="columns-container container">
<div id="center-column" class="center-column page page--full-width">
<div class="checkout-grid row">
<div class="checkout-grid__content col-lg-8">
<div class="tab-content">
{block name='checkout_process'}
{render file='checkout/checkout-process.tpl' ui=$checkout_process}
{/block}
</div>
</div>
<div class="checkout-grid__aside col-lg-4">
<div class="checkout-grid__aside-wrapper">
<div class="checkout__summary-accordion accordion">
<div class="checkout__summary-accordion-item accordion-item">
<div class="checkout__summary-accordion-header accordion-header">
<button class="accordion-button" type="button" data-bs-target="#js-checkout-summary" data-bs-toggle="collapse" aria-expanded="true">
{l s='Order summary' d='Shop.Theme.Checkout'}
</button>
</div>
{block name='cart_summary'}
<div class="checkout__summary-accordion-wrapper cart-summary js-checkout-summary">
{include file='checkout/_partials/cart-summary.tpl' cart=$cart}
</div>
{/block}
</div>
</div>
{hook h='displayReassurance'}
</div>
</div>
</div>
</div>
</div>
{include file='checkout/_partials/modal-terms.tpl'}
{/block}

View File

@@ -0,0 +1,105 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file=$layout}
{$componentName = 'order-confirmation'}
{block name='content'}
{block name='order_confirmation_header'}
<div class="alert alert-success" role="alert" tabindex="0">
{include file='components/page-title-section.tpl' title={l s='Your order is confirmed' d='Shop.Theme.Checkout'}}
<p class="mb-0">
{l s='An email has been sent to your mail address %email%.' d='Shop.Theme.Checkout' sprintf=['%email%' => $order_customer.email]}
</p>
{if $order.details.invoice_url}
<hr class="border-top border-success"/>
{l
s='You can also [1]download your invoice[/1].'
d='Shop.Theme.Checkout'
sprintf=[
'[1]' => "<a href='{$order.details.invoice_url}' class='alert-link'>",
'[/1]' => "</a>"
]
}
{/if}
</div>
{/block}
{block name='hook_payment_return'}
{capture name='hook_payment_return'}{$HOOK_PAYMENT_RETURN nofilter}{/capture}
{if !empty($smarty.capture.hook_payment_return)}
{$smarty.capture.hook_payment_return nofilter}
{/if}
{/block}
{block name='hook_order_confirmation'}
{capture name='hook_order_confirmation'}{$HOOK_ORDER_CONFIRMATION nofilter}{/capture}
{if !empty($smarty.capture.hook_order_confirmation)}
{$smarty.capture.hook_order_confirmation nofilter}
{/if}
{/block}
{block name='hook_order_confirmation_1'}
{capture name='hook_order_confirmation_1'}{hook h='displayOrderConfirmation1'}{/capture}
{if !empty($smarty.capture.hook_order_confirmation_1)}
{$smarty.capture.hook_order_confirmation_1 nofilter}
{/if}
{/block}
{block name='order_details'}
<div class="{$componentName}__details card border-1 {if !$registered_customer_exists}mb-3{else}mb-4{/if}">
<div class="card-body">
<h2 class="h2">{l s='Order details' d='Shop.Theme.Checkout'}</h2>
<ul class="{$componentName}__details-list">
<li>{l s='Order reference: %reference%' d='Shop.Theme.Checkout' sprintf=['%reference%' => $order.details.reference]}</li>
<li>{l s='Payment method: %method%' d='Shop.Theme.Checkout' sprintf=['%method%' => $order.details.payment]}</li>
{if !$order.details.is_virtual && !($is_multishipment_enabled|default:false)}
<li>{l s='Shipping method: %method%' d='Shop.Theme.Checkout' sprintf=['%method%' => $order.carrier.name]} - {$order.carrier.delay}</li>
{/if}
</ul>
<hr>
{block name='order_confirmation_table'}
{if isset($is_multishipment_enabled) && $is_multishipment_enabled}
{include
file='checkout/_partials/order-confirmation-table-multishipment.tpl'
products=$order.order_shipments
subtotals=$order.subtotals
totals=$order.totals
labels=$order.labels
add_product_link=false
hide_multishipment_edit_buttons=true
}
{else}
{include
file='checkout/_partials/order-confirmation-table.tpl'
products=$order.products
subtotals=$order.subtotals
totals=$order.totals
labels=$order.labels
add_product_link=false
}
{/if}
{/block}
</div>
</div>
{/block}
{if !$registered_customer_exists}
{block name='account_transformation_form'}
<div class="card card-body bg-light mb-4 {$componentName}__account-transformation">
{include file='customer/_partials/account-transformation-form.tpl'}
</div>
{/block}
{/if}
{block name='hook_order_confirmation_2'}
{hook h='displayOrderConfirmation2'}
{/block}
{/block}

View File

@@ -0,0 +1,21 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='sitemap_item'}
<ul class="sitemap__list{if !empty($is_nested)} sitemap__list--nested{/if}">
{foreach $links as $link}
<li class="sitemap__item">
<a class="sitemap__link"
id="{$link.id}" href="{$link.url}" title="{$link.label}">
{$link.label}
</a>
{if !empty($link.children)}
{include file='cms/_partials/sitemap-nested-list.tpl' links=$link.children is_nested=true}
{/if}
</li>
{/foreach}
</ul>
{/block}

View File

@@ -0,0 +1,48 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='page.tpl'}
{block name='page_title'}
{$cms_category.name}
{/block}
{block name='page_content'}
{block name='cms_sub_categories'}
{if $sub_categories}
<p>
{l s='List of sub categories in %name%:' d='Shop.Theme.Global' sprintf=['%name%' => $cms_category.name]}
</p>
<ul>
{foreach from=$sub_categories item=sub_category}
<li>
<a href="{$sub_category.link}">
{$sub_category.name}
</a>
</li>
{/foreach}
</ul>
{/if}
{/block}
{block name='cms_sub_pages'}
{if $cms_pages}
<p>
{l s='List of pages in %category_name%:' d='Shop.Theme.Global' sprintf=['%category_name%' => $cms_category.name]}
</p>
<ul>
{foreach from=$cms_pages item=cms_page}
<li>
<a href="{$cms_page.link}">
{$cms_page.meta_title}
</a>
</li>
{/foreach}
</ul>
{/if}
{/block}
{/block}

View File

@@ -0,0 +1,26 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='page.tpl'}
{block name='page_title'}
{$cms.meta_title}
{/block}
{block name='page_content_container'}
<section id="content" class="page-content page-content--cms rich-text js-page-content-cms">
{block name='cms_content'}
{$cms.content nofilter}
{/block}
{block name='hook_cms_dispute_information'}
{hook h='displayCMSDisputeInformation'}
{/block}
{block name='hook_cms_print_button'}
{hook h='displayCMSPrintButton'}
{/block}
</section>
{/block}

Some files were not shown because too many files have changed in this diff Show More