Template Examples
Simplified code recipes extracted from the buran production template. Feature-toggle conditionals have been stripped to show core structural patterns. For the complete file listing, see Template file structure.
Product listing item
The _listing.tpl file defines how each product card looks in category pages, search results, and product sliders. The i:list-item tag wraps each item and is rendered automatically by i:list-container (see Product listing).
{# _listing.tpl - default product card #}
<i:list-item type="product" class="swiper-slide cell cell--product">
<div class="white-item white-item--column">
{# Product image with link #}
<div class="white-item__image">
<a href="{{ product.url }}">
<i:img src="product.image" format="359x479" fill />
</a>
{# Labels: discount, new, custom labels #}
<div class="listing__labels labels">
{% if product.item.price.discountPercent %}
<strong class="label label__discount">
-{{ product.item.price.discountPercent }}%
</strong>
{% endif %}
{% if product.flagNew %}
<strong class="label label__new">{% trans 'template.label.new' %}</strong>
{% endif %}
{% for label in product.labels %}
<strong class="label" if:style="label.colorCode ? 'background: ' ~ label.colorCode">
{{ label.name }}
</strong>
{% endfor %}
</div>
</div>
{# Product name #}
<h2 class="listing-item__header">
<a href="{{ product.url }}">{{ product.name }}</a>
</h2>
{# Price: before-discount + current price #}
<div class="white-item__bottom-left">
{% if product.item.price.discount %}
<span class="u-decoration-through">{{ product.item.price.beforeDiscount.formatted }}</span>
{% endif %}
<strong class="{{ product.item.price.discount ? 'u-color-red' }}">
{{ product.item.price.current.formatted }}
</strong>
</div>
{# Availability text and estimated delivery date #}
<div class="white-item__bottom-right">
<strong class="availability availability--{{ product.item.availability.hours }}">
{# prvniVelke = capitalize first letter #}
{{ product.item.availability.text|prvniVelke }}
</strong>
{% if product.item.availability.hours < 999 and product.item.availability.deliveryOption.dateDelivered %}
<span>
{% trans 'template.at-your-place' %}
<strong>{{ product.item.availability.deliveryOption.dateDelivered|date('j. n.') }}</strong>
</span>
{% endif %}
</div>
{# Add-to-cart button #}
<div class="listing__submit-form">
<form action="/Koupit" class="js_koupit" method="post">
<button type="submit" class="button--order">
+ {% trans 'template.add-to-cart' %}
</button>
<input name="zbozi" value="{{ product.id }}" type="hidden" />
</form>
</div>
{# Wishlist heart icon (prani = wishes) #}
<a href="#" class="listing__fav fav-link {{ customer ? (customer.productOnWishlist(product) ? 'js_wish_del is-active' : 'js_wish_add') : 'js_prihlaseni' }}"
data-zbozi="{{ product.id }}" role="button">
<svg class="icon fav-empty"><use xlink:href="{{ images('symbol-defs.svg#bi-Heart') }}"></use></svg>
<svg class="icon fav-full u-color-red"><use xlink:href="{{ images('symbol-defs.svg#bi-Heart') }}"></use></svg>
</a>
</div>
</i:list-item>Key objects: product.url, product.image, product.name, product.item.price, product.item.availability, product.labels. See Object Types.
Category page
The vypis.tpl (category listing) uses i:list-container to render a filterable, sortable product grid. The container automatically loads _listing.tpl for each product. The i:list-dynamic wrapper marks sections that the system re-renders via AJAX when the user applies filters or navigates pages.
{# vypis.tpl - category listing (vypis = listing/display) #}
<div class="grid-container">
{# Category title (this.nazev = page heading set by the system) #}
<h1>{{ this.nazev }}</h1>
{# Category description - i:list-dynamic re-renders this block when filters change #}
{% if category.text('long') %}
<i:list-dynamic variables="category" type="text">
{{ category.text('long') }}
{# Link to bottom description if both long and short text exist #}
{% if category.text %}
<p><a href="#long-description" class="to-anchor">
{% trans 'template.category.description.more' %}
</a></p>
{% endif %}
</i:list-dynamic>
{% endif %}
{# Subcategory navigation with swiper - also dynamic (updates on filter) #}
<i:list-dynamic variables="category" type="subcategories" class="swiper-container subcategories">
{% if category.subcategories %}
<div class="swiper-wrapper">
{% for cat in category.subcategories %}
<a href="{{ cat.url }}" class="swiper-slide subcategory">
{# cat.image('ico') = icon-sized category image #}
<i:img src="cat.image('ico')" format="80x80" fill loading="lazy" />
<span>{{ cat.name }}</span>
</a>
{% endfor %}
</div>
{% endif %}
</i:list-dynamic>
</div>
<div class="grid-container">
{# Product list container - automatically renders _listing.tpl for each product #}
<i:list-container type="product" class="main-listing">
{# Filter placeholder - renders the filter form from _filter.tpl #}
<i:filter-placeholder name="default" config="default" always-collapsed />
{# Sort dropdown (razeni = sorting) #}
<div data-role="pagination" data-name="sort"></div>
{# Product count display #}
<div data-role="pagination" data-name="numbers"></div>
{# Grid/list view toggle #}
<div data-role="pagination" data-name="grid"></div>
{# Active filter values with remove buttons #}
<i:filter-placeholder-values name="default" config="default" />
{# Empty state message (shown when no products match filters) #}
<div data-role="empty"></div>
{# Product grid - items from _listing.tpl are injected here #}
<div data-role="list" class="listing"></div>
{# Pagination controls - multiple strategies: scroll, pages, load-more #}
<div class="pagination">
<div data-role="pagination" data-name="scroll"></div>
<div data-role="pagination" data-name="pages"></div>
<div data-role="pagination" data-name="add"></div>
<div data-role="pagination" data-name="numbers"></div>
</div>
</i:list-container>
{# Bottom category description (SEO text) #}
{% if category.text %}
<div id="long-description">
<i:list-dynamic variables="category" type="text">
{{ category.text }}
</i:list-dynamic>
</div>
{% endif %}
</div>See Product listing for i:list-container reference and Filters for i:filter-placeholder. The i:list-dynamic component is documented in Syntax.
Homepage
The index.tpl renders the homepage with banner sliders, product sections, brands, and content-grid-driven content blocks. The homepage is heavily data-driven: most sections are controlled through content grids and banner repositories configured in the admin panel.
{# index.tpl - homepage (uvodni stranka) #}
{# Main banner slider (configured via admin banner sections) #}
{% if this.templateAttributes.banners_homepage %}
{% set banner_section_id = this.templateAttributes.banners_homepage.id %}
<div class="main-banner" role="banner">
<i:banners source="repository.banner.findBy({'sectionId': banner_section_id, 'limit': 6})"
class="main-banner__swiper" click="banner" plugin="swiper">
{# Responsive image sources - system picks best size per device #}
<source format="1920x800" src="desktop" alt="" />
<source format="767x900" src="tablet" alt="" />
<source format="375x440" src="mobile" alt="" />
{# Banner content slots - filled from banner.name, banner.text, banner.ctaText #}
<span data-role="title"></span>
<strong data-role="description"></strong>
<button data-role="cta" class="button--white"></button>
</i:banners>
</div>
{% endif %}
{# Content-grid section: rich text/image block (positioned above or below banner) #}
{% if this.contentGrid('homepage-about-top') %}
{% set item = this.contentGrid('homepage-about-top').item %}
<div if:style="item.color ? 'background-color: ' ~ item.color">
{% if item.image %}
{# Multiple format sizes for responsive srcset generation #}
<i:img src="item.image" format="2000x2000,1600x1600,800x800" sizes="100vw" loading="lazy" />
{% endif %}
{{ item.text }}
</div>
{% endif %}
{# Content-grid section: banner with product slider combo #}
{% if this.contentGrid('homepage-banner-products') %}
{% for item in this.contentGrid('homepage-banner-products').item %}
<div class="banner-products" if:style="item.left.color ? '--banner-bg-color: ' ~ item.left.color">
{# Left side: promotional image #}
<div class="banner-products__image">
<i:img src="item.left.image" format="600x600" loading="lazy" />
</div>
{# Right side: text + CTA button #}
<div class="banner-products__text">
<span>{{ item.right.text }}</span>
<strong>{{ item.right.headline }}</strong>
<a href="{{ item.right.button.url }}" class="button">
{{ item.right.button.label }}
</a>
</div>
{# Product slider using a content-grid-defined product collection #}
{# hide-empty = don't render this block if collection is empty #}
<i:list-container type="product" name="simple"
collection="{{ item.right.products }}" hide-empty>
<div data-role="list" class="swiper-wrapper"></div>
</i:list-container>
</div>
{% endfor %}
{% endif %}
{# Text block above brands (optional content grid section) #}
{% if this.contentGrid('homepage-text-above-brands') %}
{% set item = this.contentGrid('homepage-text-above-brands').item %}
<div if:style="item.color ? 'background-color: ' ~ item.color">
{{ item.text }}
</div>
{% endif %}
{# Important brands slider from repository #}
{% set important_brands = repository.brand.findBy({'important': true, 'limit': 10}) %}
{% if important_brands|length > 0 %}
<h2>{% trans 'template.favourite-brands.headline' %}</h2>
<p><a href="{{ iUrl('Vyrobce/Vypis') }}">{% trans 'template.favourite-brands.text' %}</a></p>
<div class="swiper-container swiper-per-10">
<div class="swiper-wrapper">
{% for brand in important_brands %}
<div class="swiper-slide">
<a href="{{ brand.url }}">
{# vector + transparent = render SVG logos without background #}
<i:img src="brand.image" format="69x60" loading="lazy" vector transparent="" fill />
</a>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{# Blog articles section #}
{% if repository.article.findBy({'limit': 4}) is not empty %}
<div class="swiper-container swiper-per-4">
<div class="swiper-wrapper">
{% for article in repository.article.findBy({'limit': 4}) %}
<div class="swiper-slide">
<a href="{{ article.url }}">
{# article.image('preview') = preview-sized article image #}
<i:img src="article.image('preview')" format="359x251" fill loading="lazy" />
</a>
<span>{{ article.topic.name|upper }}</span>
<h3><a href="{{ article.url }}">{{ article.name }}</a></h3>
{# orez = truncate text to N characters #}
<p>{{ article.text('annotation')|orez(100) }}</p>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{# Footer about section driven by content grid #}
{% if this.contentGrid('homepage-about') %}
{% include 'partials/_footer-about.tpl' %}
{% endif %}Key patterns:
repository.banner.findBy(),repository.brand.findBy(),repository.article.findBy()-- query data from Repositoriesthis.contentGrid('name')-- load admin-configured content (see Content Grid)this.templateAttributes.banners_homepage.id-- banner section ID from Configurationi:banners-- banner slider component with responsive<source>tags (see Syntax)i:list-containerwithcollectionattribute -- render a specific product set as a slideriUrl('Vyrobce/Vypis')-- generate internal URL for a route (see Global variables)
Product detail buy form
From zbozi.tpl and zbozi_vars.tpl -- the variant selection and add-to-cart area on product detail pages. The buy form is only rendered when product.active is true; inactive products show alternative recommendations instead.
{# zbozi.tpl - product detail buy form (Koupit = Buy) #}
{% if product.active %}
<form class="product__rest js_koupit" action="/Koupit" method="post">
{# Variant choice component - renders color/size selectors #}
{# See variant-selection docs for full reference #}
{% include 'zbozi_vars.tpl' %}
{# Availability info block - reloads when variant changes #}
{# js_reload_var + i:dynamic="product" = AJAX-reloaded on variant select #}
<div class="js_reload_var" i:dynamic="product">
<strong class="availability availability--{{ product.item.availability.hours }}">
{# prvniVelke = capitalize first letter #}
{{ product.item.availability.text|prvniVelke }}
</strong>
{% if product.item.availability.deliveryOption.dateDelivered %}
<div>
{% trans 'template.estimated-delivery-date' %}
<strong>{{ product.item.availability.deliveryOption.dateDelivered|date('j. n.') }}</strong>
</div>
{% endif %}
</div>
{# Hidden product ID (zbozi = goods/product) #}
<input type="hidden" value="{{ product.id }}" name="zbozi">
{# Quantity input (ks = kusy = pieces) #}
<div class="product__amount">
<span class="plus-minus">
<a href="" class="plus-minus__plus">+</a>
<a href="" class="plus-minus__minus">-</a>
<label>
{% trans 'checkout.catalog-table.item.quantity' %}
<input type="tel" name="ks" class="ks" value="1" size="1" min="0" />
</label>
</span>
</div>
{# Buy button with inline price display #}
<div class="product__buy">
<button type="submit" class="button button--order button--expanded">
{% trans 'product.button.buy' %}
<span class="product__buy-price">
{{ product.item.price.current.formatted }}
</span>
</button>
</div>
</form>
{% endif %}The zbozi_vars.tpl uses the i:variant-choice component. It supports three step modes: icons (color swatches), selects (dropdown), and a default radio-button list. The buran template also adds size table links when available:
{# zbozi_vars.tpl - variant choice steps #}
<i:variant-choice product="product" reload-targets=".js_reload_var">
{% for step in product.variantChoiceSteps %}
<div data-role="step">
{% if step.mode == 'icons' %}
{# Color swatches (barva = color) #}
<label>{{ step.headline }}: <span>{{ step.selectedChoice.name }}</span></label>
<ul class="variant-choice__list variant-choice__list--color">
{% for choice in step.choices %}
<li>
<input name="{{ step.inputName }}" type="radio"
value="{{ choice.inputValue }}" if:checked="choice.selected"
required data-msg-required="{{ step.messageEmpty }}" />
<label title="{{ choice.name }}">
{% if choice.icon %}
<i:img src="choice.icon" fill format="40x40" vector loading="lazy" />
{% elseif choice.description %}
{# description contains hex color code #}
<span style="background-color: {{ choice.description }}"></span>
{% endif %}
</label>
</li>
{% endfor %}
</ul>
{% elseif step.mode == 'selects' %}
{# Dropdown select (roletka = dropdown) #}
{# Size table link if available on product or brand #}
{% if step.infoDescription %}
<a class="variant-choice__link open-dialog"
data-dialogtitle="{{ step.infoDescription }}">
{{ step.infoDescription }}
</a>
{% endif %}
<label>{{ step.headline }}</label>
<select name="{{ step.inputName }}" required
data-msg-required="{{ step.messageEmpty }}">
<option value="">{{ step.placeholder }}</option>
{% for choice in step.choices %}
<option value="{{ choice.inputValue }}" if:selected="choice.selected">
{{ choice.name }}
</option>
{% endfor %}
</select>
{% else %}
{# Default: radio button list with availability per choice #}
<label>{{ step.headline }}: <span>{{ step.selectedChoice.name }}</span></label>
<ul class="variant-choice__list">
{% for choice in step.choices %}
<li>
<input type="radio" name="{{ step.inputName }}"
value="{{ choice.inputValue }}" if:checked="choice.selected"
required data-msg-required="{{ step.messageEmpty }}" />
<label>
<strong>{{ choice.name }}</strong>
{% if choice.availability %}
<br><small class="availability availability--{{ choice.availability.hours }}">
{{ choice.availability.text }}
</small>
{% endif %}
</label>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
</i:variant-choice>Key attributes:
i:variant-choicewithreload-targets-- automatically reloads price/availability when a variant is selectedi:dynamic="product"-- marks elements for AJAX reload when variant changesproduct.variantChoiceSteps-- array of selection steps (color, size, etc.)step.mode-- determines rendering style:icons,selects, or default radio liststep.infoDescription/step.infoIcon-- optional help link (e.g., size table)choice.availability-- per-choice stock info (only in default radio mode)- See Variant Selection for the full reference
Cart items
From kosik_obsah.tpl -- iterating over products in the cart. The cart page uses cart.catalogItems to loop through items. The entire cart form is wrapped in i:dynamic="cart, objednavka" so the system can reload it via AJAX when quantities change.
{# kosik_obsah.tpl - cart product list (kosik = cart, obsah = content) #}
<form action="{{ this.urlSave }}" method="post">
<div class="checkout-left js_reload_order" i:dynamic="cart, objednavka">
{# Optional checkout info banner from content grid #}
{% if this.contentGrid('checkout-content-info') %}
{% set block = this.contentGrid('checkout-content-info').checkouttext %}
<div class="callout callout--info"
style="color: {{ block.color }}; background: {{ block.bgcolor }}">
{{ block.text }}
</div>
{% endif %}
<h1>
{% trans 'checkout.headline' %}
<span>({{ cart.catalogItemTotalAmount }} {% trans 'template.qty' %})</span>
</h1>
{# Loop through cart items (orderItem = polozka objednavky) #}
{% for orderItem in cart.catalogItems %}
<div class="cartie cartie--item {{ orderItem.gift ? 'cartie--gift' }}">
{# Product image - use variant image if available #}
<a href="{{ orderItem.product.url }}" class="cartie__image">
{% if orderItem.variant.image %}
<i:img src="orderItem.variant.image" format="130x92" fill />
{% else %}
<i:img src="orderItem.image" format="130x92" fill />
{% endif %}
</a>
<div class="cartie__rest">
{# Product name and child items (e.g., bundle components) #}
<div class="cartie__name">
<a href="{{ orderItem.product.url }}">
<strong>{{ orderItem.item.name }}</strong>
</a>
{% for item in orderItem.children %}
{% if orderItem.name not in item.name %}
{{ item.name }} {{ item.variantName }}
{% if item.priceTotal.current.value != 0 %}
({{ item.priceTotal.current.formatted }})
{% endif %}<br>
{% endif %}
{% endfor %}
</div>
{# Availability and variant info (not shown for gift items) #}
{% if not orderItem.gift %}
<div class="cartie__info">
{% trans 'template.availability' %}:
<strong class="availability availability--{{ orderItem.item.availability.hours }}">
{{ orderItem.item.availability.text }}
</strong><br>
{% if orderItem.variantName %}
{% trans 'template.variant' %}: <strong>{{ orderItem.variantName }}</strong><br>
{% endif %}
{% trans 'template.price' %}:
{% if orderItem.item.price.discount %}
<span class="u-decoration-through">{{ orderItem.item.price.beforeDiscount.formatted }}</span>
{% endif %}
<strong>{{ orderItem.item.price.current.formatted }}</strong>
</div>
{% endif %}
{# Line total (darek zdarma = free gift) #}
<div class="cartie__price">
{% if orderItem.gift %}
<strong class="u-color-red">{% trans 'global.free' %}</strong>
{% else %}
<strong>{{ orderItem.priceTotal.current.formatted }}</strong>
{% endif %}
</div>
{# Quantity input with plus/minus buttons (ks = kusy = pieces) #}
<div class="cartie__quantity">
{% if orderItem.gift %}
1 {% trans 'template.qty' %}
{% else %}
<span class="plus-minus plus-minus--to-null">
<a href="" class="plus-minus__plus">+</a>
<a href="" class="plus-minus__minus">-</a>
<label>
{% trans 'checkout.catalog-table.item.quantity' %}
<input type="tel" name="ks[{{ orderItem.id }}]"
value="{{ orderItem.amount }}" size="1" min="0" />
</label>
</span>
{% endif %}
</div>
{# Remove item link (del = smazat/delete) #}
{% if not orderItem.gift %}
<a href="?del={{ orderItem.id }}" class="cartie__del">
{% trans 'cart-popup.item.delete' %}
</a>
{% endif %}
{# Upsell add-ons (e.g., extended warranty, gift wrapping) #}
{% if orderItem.availableUpsells is not empty and not orderItem.gift %}
<div class="cartie__extra">
<strong>{% trans 'cart-dialog.upsells.headline' %}</strong>
{% for upsell in orderItem.availableUpsells %}
<p>
<input type="checkbox" name="upsell[{{ orderItem.id }}]"
value="{{ orderItem.id }}-{{ upsell.id }}"
if:checked="upsell.inCart" />
<label>
{{ upsell.name }}
<span>{{ upsell.price.current.formatted }}</span>
</label>
</p>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endfor %}
{# Discount items (e.g., coupon codes; sleva = discount) #}
{% for orderDiscountCart in cart.discountItems %}
<div class="cartie">
<div class="cartie__name">{{ orderDiscountCart.name }}</div>
<div class="cartie__price">
{% if orderDiscountCart.percent > 0 %}
<strong>-{{ orderDiscountCart.percent }}%</strong>
{% elseif orderDiscountCart.price.current.value > 0 %}
<strong>{{ orderDiscountCart.price.current.formatted }}</strong>
{% endif %}
</div>
{# delSleva = delete discount #}
<a href="?delSleva={{ orderDiscountCart.id }}" class="cartie__del">
{% trans 'cart-popup.item.delete' %}
</a>
</div>
{% endfor %}
</div>
{# Order summary sidebar (souhrn = summary) #}
{% include 'kosik_souhrn.tpl' with {'checkout': 'products'} %}
{# toSekce = target section for next checkout step (dodani = delivery) #}
<input type="hidden" name="toSekce" value="dodani">
<input type="submit" name="submit" class="hide" value="{% trans 'checkout.button.recount' %}" />
</form>Key objects:
cart.catalogItems-- ordered products (see Cart)cart.discountItems-- applied discount coupons (sleva = discount)cart.catalogItemTotalAmount-- total number of itemsorderItem.item.price,orderItem.priceTotal-- unit price vs line totalorderItem.availableUpsells-- add-on products (warranty, services) for this itemorderItem.children-- child items for bundles/packsorderItem.gift-- boolean, true if item is a free giftthis.urlSave-- form action URL for cart updatesthis.contentGrid('checkout-content-info')-- optional info banner (see Content Grid)i:dynamic="cart, objednavka"-- marks the section for AJAX reload when cart changes
Footer with content grid
From _footer.tpl -- rendering configurable footer columns using the footer-column-links content grid. The footer is composed of multiple included sub-templates and content-grid-driven sections.
{# _footer.tpl - footer link columns from content grid #}
<div class="footer">
{# Newsletter subscription form (optional, toggled via templateAttributes) #}
{% include 'partials/_newsletter.tpl' %}
{# USP bar: free shipping, returns, etc. (from content-grid/footer-usp.xml) #}
{% if this.contentGrid('footer-usp').item %}
{% include '_footer-usp.tpl' %}
{% endif %}
<div class="u-bg-light-gray">
<div class="grid-container">
<div class="grid-x xlarge-up-5">
{# Link columns from content-grid/footer-column-links.xml #}
{# Each item has .headline and .link[] array #}
{# Production template limits to first 3 columns: loop.index <= 3 #}
{% for item in this.contentGrid('footer-column-links').item %}
<div class="cell footer-box">
<h4 class="footer-box__headline">
{{ item.headline }}
{# Chevron icon for mobile accordion toggle #}
<svg class="footer-box__headline-angle icon">
<use xlink:href="{{ images('symbol-defs.svg#bi-chevron-down') }}"></use>
</svg>
</h4>
<div class="footer-box__info">
<ul>
{% for link in item.link %}
<li><a href="{{ link.url }}">{{ link.label }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
{# Contact column with phone and email #}
<div class="cell footer-box">
<h4>{% trans 'footer.contact.headline' %}</h4>
<div class="footer-box__info">
{% if shop.phone %}
<a href="tel:{{ shop.phone }}" class="button button--white-bg-gray-border">
<svg class="icon"><use xlink:href="{{ images('symbol-defs.svg#bi-Phone') }}"></use></svg>
<span>
{% trans 'footer.contact.phone-contact' %}<br>
<strong>{{ shop.phone }}</strong>
</span>
</a>
{% endif %}
{% if shop.email %}
<a href="mailto:{{ shop.email }}" class="button button--white-bg-gray-border">
<svg class="icon"><use xlink:href="{{ images('symbol-defs.svg#bi-Envelope') }}"></use></svg>
<span>
{% trans 'footer.contact.email-contact' %}<br>
<strong>{{ shop.email }}</strong>
</span>
</a>
{% endif %}
</div>
</div>
{# Social media links (sledujte nas = follow us) #}
<div class="cell footer-box">
<h4>{% trans 'footer.social.headline' %}</h4>
<div class="footer-box__info">
<span>{% trans 'footer.social.find-us' %}</span><br>
{% if shop.socialProfiles['facebook'] %}
<a href="{{ shop.socialProfiles['facebook'].url }}" rel="nofollow" target="_blank" aria-label="Facebook">
<svg class="icon"><use xlink:href="{{ images('symbol-defs.svg#bi-Facebook') }}"></use></svg>
</a>
{% endif %}
{% if shop.socialProfiles['instagram'] %}
<a href="{{ shop.socialProfiles['instagram'].url }}" rel="nofollow" target="_blank" aria-label="Instagram">
<svg class="icon"><use xlink:href="{{ images('symbol-defs.svg#bi-Instagram') }}"></use></svg>
</a>
{% endif %}
{% if shop.socialProfiles['pinterest'] %}
<a href="{{ shop.socialProfiles['pinterest'].url }}" rel="nofollow" target="_blank" aria-label="Pinterest">
<svg class="icon"><use xlink:href="{{ images('symbol-defs.svg#bi-Pinterest') }}"></use></svg>
</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{# Copyright bar (podpis = signature) #}
{% include '_footer-sign.tpl' %}
</div>Key patterns:
this.contentGrid('footer-column-links').item-- returns an array of column objects, each with.headlineand.link[](see Content Grid)this.contentGrid('footer-usp').item-- USP items (free delivery, returns guarantee, etc.)shop.phone,shop.email-- global shop contact info (see Global variables)shop.socialProfiles['facebook'].url-- social media URLs configured in admin; supportsfacebook,instagram,pinterest,twitterimages('symbol-defs.svg#bi-*')-- SVG sprite icon references; thesymbol-defs.svgfile inimages/contains all icons- Footer boxes collapse into accordions on mobile (toggled by the chevron icon)
Working Hours
workingHours is an object of type WorkingHours, either the global this.templateAttributes.globalWorkingHours or on an object of type Store.
Current Status
{% if workingHours.open %}
Otevřeno
{% else %}
Zavřeno
{% endif %}Display of the current open/closed status with the next transition time.
{% if workingHours.open %}
Máme otevřeno, zavíráme {{ workingHours.nextClose|date('d. m. Y H:i') }}
{% else %}
Máme zavřeno, otevíráme {{ workingHours.nextOpen|date('d. m. Y H:i') }}
{% endif %}Compact Display
Days with the same opening hours are merged, e.g. Po-St (Mon-Wed), Ct (Thu), Pa-Ne (Fri-Sun). timeFormat: 'compact' hides minutes when they are 0 (e.g. 9-10:30, 9:30-11).
Note: This display does not include exceptions (or holidays) — they must be listed separately: Listing Exceptions and Holidays
{% for day, time in workingHours.week({longDays: false, timeDelimiter: '-', timeFormat: 'compact'}) %}
{{ day }}: {% if time %}
{{ time|join(', ') }}
{% else %}
Zavřeno
{% endif %}
{% endfor %}Full Week Day-by-Day Display
Lists the entire week day by day (Monday, Tuesday, ...).
Note: This display does not include exceptions (or holidays) — they must be listed separately: Listing Exceptions and Holidays
{% for day, time in workingHours.weekFull({longDays: true, timeDelimiter: '-', timeFormat: 'compact'}) %}
{{ day }}: {% if time %}
{{ time|join(', ') }}
{% else %}
Zavřeno
{% endif %}
{% endfor %}Upcoming Days Display
Day-by-day listing including dates (reflects exceptions and holidays).
{% for dayBlock in workingHours.forNextDays %}
{# Or dayNameShort for abbreviated day names: #}
{{ dayBlock.dayName }} {{ dayBlock.date|date('d. m. Y') }}:
{% if dayBlock.timeBlocks %}
{{ dayBlock.timeBlocks|join(', ') }}
{% else %}
Zavřeno
{% endif %}
{% endfor %}Listing Exceptions and Holidays
Lists exceptions to regular opening hours, including holidays.
{% for date, timeBlocks in workingHours.specialCases({dateFormat: 'd. m. Y'}) %}
{{ date }}:
{% if timeBlocks %}
{{ timeBlocks|join(', ') }}
{% else %}
Zavřeno
{% endif %}
{% endfor %}Locale note: The day abbreviations in code output (Po, Ut, St, Ct, Pa, So, Ne) and Czech strings like "Otevřeno" (open), "Zavřeno" (closed), "Máme otevřeno, zavíráme" (we are open, closing at), and "Máme zavřeno, otevíráme" (we are closed, opening at) come from the system locale / template layer and are intentionally left in Czech in the code examples.