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:
{# _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 setsthis.templateto the correct page file (e.g.,zbozi.tplfor product detail)this.templateNamereturns the current template name without extension (e.g.,zbozi,vypis)sekce_kosik(literally "cart section") detects checkout pages viaiUrl('Objednavka/Kosik')-- the internal cart URLkosis the cart object,sekceis the current checkout step nameURIis the current request URI
Minimal config.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 behaviorwebfonts-- Google Fonts loaded automaticallyplugins-- JS/CSS libraries injected before your code;jqueryandfoundationare the minimum for interactive templatescartSteps-- defines the checkout flow;handlesare step identifiers,queryis the URL query parameter for that step (dodani= delivery,adresa= address)features-- feature flags;syntax2019enables modern template syntax support
For the full config.json reference, see Configuration.
Minimal css/base.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:
_settings.scss(if present) -- injected before plugin styles- Plugin styles (Foundation, etc.)
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 page | Template file | Czech name | Key variables |
|---|---|---|---|
| Homepage | index.tpl | Uvodní stránka | repository, this.contentGrid() |
| Product detail | zbozi.tpl | Zboží | product |
| Category listing | vypis.tpl | Výpis | kategorie, this.nazev |
| Search results | vyhledavani.tpl | Vyhledávání | search query in URL |
| Cart | kosik.tpl | Košík | kos, cart, sekce |
| Order confirmation | potvrzeni.tpl | Potvrzení | order |
| Order management | objednavka.tpl | Objednávka | order |
| Registration | registrace.tpl | Registrace | form fields |
| Static page | stranka.tpl | Stránka | textPage |
| Article | clanek.tpl | Článek | article |
| Store detail | prodejna.tpl | Prodejna | store |
| Contact | kontakty.tpl | Kontakty | contact info |
Czech identifier glossary:
zbozi= goods/product,vypis= listing,kosik= cart/basketpotvrzeni= confirmation,objednavka= order,registrace= registrationstranka= page,clanek= article,prodejna= store,kontakty= contactsthis.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.tplHeader 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 pathkos= 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:
<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 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 themcode="item"-- how you access this row in Twig:this.contentGrid('header-usp').itemtype="image"-- image upload field;type="html_simple"-- basic rich text editorwidth-- 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:
{# 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').itemreturns an array because ofmultiple="true"i:imgis 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
- Template file structure -- directory layout and naming conventions
- Configuration -- config.json options in detail
- Syntax -- Twital custom tags (
i:img,i:list-container,if:class, etc.) - Object Types --
product,category,cart, and other object references - Examples -- complete code recipes from production templates