Skip to content

Getting Started

This guide covers the minimum file set needed for a working Simplia template, explains how pages are rendered, and walks through adding a content section. Based on the buran production template.

Minimal template

A working template requires four files:

template/
├── _base.tpl        {# layout wrapper - wraps every page #}
├── config.json      {# template configuration #}
├── index.tpl        {# homepage content #}
└── css/
    └── base.scss    {# main stylesheet (required entry point for SCSS) #}

Minimal _base.tpl

The layout wrapper includes a header, renders the current page template, and includes a footer. This is simplified from the buran _base.tpl -- feature-toggle conditionals have been stripped to show the core structure:

twig
{# _base.tpl - the outermost layout wrapper for every page #}

{# Detect checkout pages: sekce_kosik = "cart section" #}
{% set sekce_kosik = false %}
{% if iUrl('Objednavka/Kosik') in URI %}
    {% set sekce_kosik = true %}
{% endif %}

{# Choose header: checkout pages get a simplified header #}
{% if sekce_kosik and kos and sekce %}
    {% include '_header-checkout.tpl' %}
{% else %}
    {% include '_header.tpl' %}
{% endif %}

{# Main content area - this.template resolves to the current page's .tpl file #}
<main id="main" role="main" data-template="{{ this.templateName }}">
    {% include this.template %}
</main>

{# Footer: checkout pages get a simplified footer #}
{% if sekce_kosik and kos %}
    {% include '_footer-checkout.tpl' %}
{% else %}
    {% include '_footer.tpl' %}
{% endif %}

Key points:

  • {% include this.template %} is the core mechanism -- the system sets this.template to the correct page file (e.g., zbozi.tpl for product detail)
  • this.templateName returns the current template name without extension (e.g., zbozi, vypis)
  • sekce_kosik (literally "cart section") detects checkout pages via iUrl('Objednavka/Kosik') -- the internal cart URL
  • kos is the cart object, sekce is the current checkout step name
  • URI is the current request URI

Minimal config.json

json
{
    "responsive": true,
    "webfonts": [
        "Manrope:500,600,700"
    ],
    "plugins": {
        "jquery": "3.4",
        "foundation": "6.4"
    },
    "cartSteps": [
        {
            "handles": ["content"]
        },
        {
            "handles": ["delivery"],
            "query": "dodani"
        },
        {
            "handles": ["address"],
            "query": "adresa"
        }
    ],
    "features": [
        "syntax2019"
    ]
}
  • responsive -- enables viewport meta tag and responsive behavior
  • webfonts -- Google Fonts loaded automatically
  • plugins -- JS/CSS libraries injected before your code; jquery and foundation are the minimum for interactive templates
  • cartSteps -- defines the checkout flow; handles are step identifiers, query is the URL query parameter for that step (dodani = delivery, adresa = address)
  • features -- feature flags; syntax2019 enables modern template syntax support

For the full config.json reference, see Configuration.

Minimal css/base.scss

scss
/* base.scss - required SCSS entry point */
/* All other .scss files should be @import-ed from here */

/* Optional: _settings.scss is injected before plugin styles,
   allowing you to override Foundation variables, colors, etc. */

body {
    font-family: 'Manrope', sans-serif;
}

The build system compiles SCSS in this order:

  1. _settings.scss (if present) -- injected before plugin styles
  2. Plugin styles (Foundation, etc.)
  3. base.scss -- your main stylesheet

Page-to-file mapping

Each shop page type maps to a specific template file. The system automatically selects the file based on the current URL and sets this.template.

Shop pageTemplate fileCzech nameKey variables
Homepageindex.tplUvodní stránkarepository, this.contentGrid()
Product detailzbozi.tplZbožíproduct
Category listingvypis.tplVýpiskategorie, this.nazev
Search resultsvyhledavani.tplVyhledávánísearch query in URL
Cartkosik.tplKošíkkos, cart, sekce
Order confirmationpotvrzeni.tplPotvrzeníorder
Order managementobjednavka.tplObjednávkaorder
Registrationregistrace.tplRegistraceform fields
Static pagestranka.tplStránkatextPage
Articleclanek.tplČlánekarticle
Store detailprodejna.tplProdejnastore
Contactkontakty.tplKontaktycontact info

Czech identifier glossary:

  • zbozi = goods/product, vypis = listing, kosik = cart/basket
  • potvrzeni = confirmation, objednavka = order, registrace = registration
  • stranka = page, clanek = article, prodejna = store, kontakty = contacts
  • this.nazev = current page title (nazev = name)

See Object Types for the full reference on product, category, order, and other objects.

Page rendering flow

When a visitor opens a URL, the rendering proceeds through four stages:

1. URL resolution
   URL is resolved to a page type (e.g., /product/some-name -> product detail)
   The system binds variables: this.template = 'zbozi.tpl', product = <product object>

2. _base.tpl loads
   The layout wrapper begins rendering

3. Conditional header
   {% if sekce_kosik %} -> _header-checkout.tpl (simplified: logo + step indicators)
   {% else %}           -> _header.tpl (full: logo, navigation, search, cart icon)

4. {% include this.template %} renders the page-specific file
   e.g., zbozi.tpl renders inside <main> using the bound variables

5. Conditional footer
   {% if sekce_kosik %} -> _footer-checkout.tpl (simplified)
   {% else %}           -> _footer.tpl (full footer with links, contact, social)

Concrete example: product detail

Visitor opens: /product/blue-sneakers

1. URL resolution -> page type: product detail
2. Variable binding:
   - this.template = 'zbozi.tpl'
   - this.templateName = 'zbozi'
   - product = {name: "Blue Sneakers", price: ..., image: ...}
3. _base.tpl renders:
   a. sekce_kosik = false (not a cart URL) -> includes _header.tpl
   b. {% include this.template %} -> renders zbozi.tpl
      zbozi.tpl can access {{ product.name }}, {{ product.price }}, etc.
   c. sekce_kosik = false -> includes _footer.tpl

Header selection logic

_base.tpl chooses between two headers:

  • _header.tpl -- full header with logo, navigation menu, search bar, cart icon, user account links
  • _header-checkout.tpl -- simplified header for checkout pages (logo + checkout step indicators only)

The condition is {% if sekce_kosik and kos and sekce %} where:

  • sekce_kosik = true when the URL contains the cart path
  • kos = the cart object (truthy when a cart exists)
  • sekce = current checkout step name ('udaje', 'dodani'); null/empty on the initial cart step (equivalent to 'kosik')

Content area

The <main> tag wraps the page content. The data-template attribute is set to this.templateName for CSS/JS targeting:

html
<main id="main" role="main" data-template="zbozi">
    <!-- zbozi.tpl content rendered here -->
</main>

This allows page-specific styling: main[data-template="zbozi"] { ... }

Adding a content section

Content grid allows shop admins to configure content blocks through the admin panel without template code changes. Here is a step-by-step example adding a USP (Unique Selling Proposition) bar with repeatable image + text items.

Step 1: Create the XML schema

Create content-grid/header-usp.xml:

xml
<?xml version="1.0" encoding="utf-8"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="https://tpldoc.simplia.cz/xsd/content-grid.xsd">
    <config>
        <name>Header - USP</name>
        <translations>true</translations>      <!-- separate content per language -->
        <mode>part</mode>                       <!-- "part" = one section, not a full page layout -->
        <supported-context type="global"/>      <!-- available on all pages, not tied to a product/article -->
    </config>

    <grid>
        <!-- multiple="true" means admins can add/remove/reorder items -->
        <row code="item" label="USP" multiple="true">
            <content type="image" label="Icon" code="image" width="30" />
            <content type="html_simple" label="Text" code="text" width="70" />
        </row>
    </grid>
</schema>

Key attributes:

  • multiple="true" on <row> -- admins can add zero or more items, and reorder them
  • code="item" -- how you access this row in Twig: this.contentGrid('header-usp').item
  • type="image" -- image upload field; type="html_simple" -- basic rich text editor
  • width -- percentage width in the admin panel layout (visual only, not output)

Step 2: Reference in template

Use this.contentGrid('section-name') where the name matches the XML filename without extension:

twig
{# In _header.tpl or wherever you want the USP bar #}
{% if this.contentGrid('header-usp') %}
    <div class="usp-bar grid-x">
        {% for item in this.contentGrid('header-usp').item %}
            <div class="usp-item cell auto">
                {# Render the uploaded icon image #}
                <i:img src="item.image" format="30x30" loading="lazy" vector transparent />
                {# Render the rich text content #}
                <span>{{ item.text }}</span>
            </div>
        {% endfor %}
    </div>
{% endif %}

Pattern notes:

  • Always wrap in {% if this.contentGrid('...') %} -- returns null if no content has been configured
  • this.contentGrid('header-usp').item returns an array because of multiple="true"
  • i:img is the platform image tag with responsive format support (see Syntax)

Step 3: Admin configuration

Once the XML file is deployed and the template references it, the content grid section automatically appears in the admin panel under template settings. Shop administrators fill in the content through a visual editor -- no further code is needed.

For the full content grid reference including all content types (string, html, image, color, url, category, product, product_list, select, article, text_page), see Content Grid.

Next steps