Skip to content

Syntax

Templates use Twig syntax (https://twig.symfony.com/), extended with platform-specific functions. This documentation covers only these extensions. We recommend familiarizing yourself with the base Twig syntax first: https://twig.symfony.com/doc/2.x/templates.html

Template validity

All templates are processed by a DOM parser, so they must be valid HTML. Crossing tags is not allowed, and all tags opened in one file should be closed in the same file. Template processing follows the HTML5 specification, so self-closing tags like IMG, INPUT, BR, HR, etc. do not need to be explicitly closed.

A consequence of template parsing can be unexpected behavior — for example, when using DIV inside P:

twig
{# as written in the template #}
<p> Hello!
    <div>Hi!</div>
</p>

Actual output:

xml
<p> Hello!</p>
<div>Hi!</div>

According to the HTML5 specification, a DIV cannot be inside a paragraph, so the paragraph is closed as soon as the parser encounters the DIV.

The following constructs cannot be used in templates:

twig
<input {%if x%}checked{%endif%}> {# invalid tag #}
<img src="{{iUrl("Objednavka/Kosik")}}"> {# incorrect quotes — use apostrophes in Twig instead #}

Template structure

Some constructs may pass validation but are not recommended. For example, the following is technically valid but can cause problems:

twig
{# incorrect pattern #}
{%if user %}
    <div class="user">
{%endif%}
{%include this.template %}
{%if user %}
    </div>
{%endif%}

Recommended approach:

twig
{# correct pattern #}
{%if user %}
    <div class="user">
        {%include this.template %}
    </div>
{%else%}
    {%include this.template %}
{%endif%}

When you need different structures based on conditions, it is most practical to define the entire structure in one place. For example, keep only conditions in one file and split the template code into macros/files. The resulting code is significantly more readable and avoids problems during template processing.

Conditional attributes

Using the if: prefix, you can conditionally render an attribute. The attribute value is Twig code (without {{}}) that can contain either just a condition (for use with checked, selected, etc.) or a condition and a value.

twig
<input if:checked="1==1"> {# output: <input checked> #}
<input if:checked="1==2"> {# output: <input> #}

<div if:class="1==1 ? 'main'"> {# output: <div class="main"> #}
<div if:class="1==2 ? 'main'"> {# output: <div> #}

Twital and the i: prefix

Simplia templates use Twital — a Twig extension that allows writing Twig logic directly as XML attributes and custom elements. This keeps templates as valid HTML/XML and makes them easily parseable.

The key concept is the i: prefix — custom XML elements that are replaced with the resulting HTML at compile time. i:* elements are Simplia system components (images, lists, forms, social buttons, etc.).

twig
{# Twital component — product image #}
<i:img src="product.image" width="300" height="300" />

{# Twital component — product listing #}
<i:list-container repository="product.recommended" limit="4">
    <div>{{ product.name }}</div>
</i:list-container>

{# Twital conditional attribute (if: prefix) #}
<button if:disabled="not product.available">Buy</button>

The complete list of available i:* components can be found in the component reference.

Common Patterns

Setting and Reusing Variables

Use {% set %} to define variables at the top of a template and reference them later:

twig
{% set headerMode = '' %}
{% if page.type == 'checkout' %}
    {% set headerMode = 'header--minimal' %}
{% endif %}

<header class="header{{ headerMode ? ' ' ~ headerMode }}">

Dynamic Content Reload

Mark elements with i:dynamic so they refresh automatically when related data changes. The attribute accepts a comma-separated list of data scopes:

twig
{# Reload this element when product data changes #}
<div i:dynamic="product">
    {{ product.price.current.formatted }}
</div>

{# Reload when cart or order data changes #}
<div i:dynamic="cart, objednavka">
    {{ cart.catalogItemTotalAmount }} items
</div>

Translation Patterns

Three ways to output translated strings:

twig
{# Block trans tag #}
{% trans 'checkout.headline' %}

{# Inline trans filter #}
{{ 'checkout.headline'|trans }}

{# Trans filter with parameters #}
{{ 'cart.items.count'|trans({count: cart.catalogItemTotalAmount}) }}

SVG Sprite Access

Icons are stored in an SVG sprite file and referenced with <use>:

twig
<svg class="icon">
    <use xlink:href="{{ images('symbol-defs.svg#bi-Arrow-right') }}"></use>
</svg>

The images() function resolves the path to the template's images directory. Icon names use the bi- prefix (e.g., bi-Close, bi-Chevron-down, bi-Voucher).

Conditional CSS Classes

Combine static and dynamic classes using Twig's ternary operator and string concatenation (~):

twig
{# Append class conditionally #}
<header class="header{{ headerMode ? ' ' ~ headerMode }}">

{# Choose between two classes #}
<strong class="{{ orderItem.price.discount ? 'u-color-red' : 'u-color-black' }}">

{# Use if: prefix for fully conditional attributes #}
<div if:class="product.available ? 'in-stock' : 'out-of-stock'">

Conditional Inline Styles

The if:style prefix works the same way as if:class for inline styles:

twig
{# Dynamic background color from data #}
<span class="label" if:style="label.colorCode ? 'background: ' ~ label.colorCode">
    {{ label.name }}
</span>

{# Conditionally hide an element #}
<div if:style="hidden ? 'display: none'">

Content Grid Blocks

Use this.contentGrid() to fetch configurable content blocks from the admin panel (see Content Grid):

twig
{% if this.contentGrid('checkout-content-info') %}
    {% set block = this.contentGrid('checkout-content-info').checkouttext %}
    <div style="color: {{ block.color }}; background: {{ block.bgcolor }}">
        {{ block.text }}
    </div>
{% endif %}

Template Attributes

Access shop-level configuration flags and values via this.templateAttributes:

twig
{# Check a feature toggle #}
{% if this.templateAttributes.global_enable_free_delivery == 'enabled' %}
    {% include 'partials/_free-delivery.tpl' %}
{% endif %}

{# Use a custom label text with fallback #}
{% if this.templateAttributes.label_new %}
    {{ this.templateAttributes.label_new }}
{% else %}
    {% trans 'template.label.new' %}
{% endif %}

Slave Config Flags

Feature toggles from the shop configuration are available via this.slaveConfig:

twig
{% if this.slaveConfig.enableGifts %}
    {% include 'kosik_darky.tpl' %}
{% endif %}

{% if this.slaveConfig.enableLoyaltyProgram %}
    {# Loyalty program UI #}
{% endif %}

Plural Translations

For strings that need pluralization, use the {% trans %}...{% plural %}...{% endtrans %} block syntax:

twig
{{ customer.userPointsAvailable }}
{% trans %}user.credits-count{% plural customer.userPointsAvailable %}user.credits-count-plural{% endtrans %}