Šablonovací systém
Pro psaní šablon se používá šablonovací systém Twig, který je rozšířený o řadu funkcí, tagů, filtrů a proměnných. Tato rozšíření umožňují používat funkce a přistupovat k informacím o stránce uvnitř šablon.
Základní syntaxe
Twig používá tři typy závorek:
{{ ... }}
– pro výpis hodnoty (echo){% ... %}
– pro řídicí struktury (cykly, podmínky, atd.){# ... #}
– pro komentáře
Proměnné
Proměnné šablon se vypisují na stránku pomocí dvojitých složených závorek.
{{ variable }}
Proměnné mohou také představovat výrazy.
{{ isAjax ? 'Ano' : 'Ne' }}
Proměnné lze spojovat pomocí znaku ~
.
{{ 'Vaše jméno: ' ~ name }}
Výpis proměnných se automaticky escapuje. Pokud potřebujete vypsat HTML bez escapování, použijte filtr |raw
:
{{ htmlObsah|raw }}
Jsou dostupné i globální proměnné pod proměnnou this
:
- this.page - informace o aktuální stránce
- this.layout - informace o layoutu
- this.theme - konfigurace šablony
- this.param - URL parametry
- this.controller - informace o controlleru
- this.environment - prostředí aplikace
- this.session - session data
Tagy
Tagy jsou unikátní funkcí Twig a jsou zabaleny do znaků {% %}
.
{% tag %}
Tagy poskytují plynulejší způsob popisu logiky šablony.
{% if stormCloudComing %}
Zůstaň uvnitř
{% else %}
Jdi ven a hraj si
{% endif %}
Tag {% set %}
lze použít k nastavení proměnných uvnitř šablony.
{% set activePage = 'blog' %}
Dostupné tagy
- {% page %} - vykresluje obsah jiné stránky
- {% partial %} - vkládá parciální šablonu
- {% content %} - vykresluje obsahový blok
- {% component %} - vykresluje komponentu
- {% placeholder %} - definuje místo pro vložení obsahu
- {% scripts %} - vkládá JavaScript soubory
- {% styles %} - vkládá CSS soubory
- {% flash %} - zobrazuje flash zprávy
- {% verbatim %} - zabraňuje zpracování Twig syntaxe
- {% macro %} - definuje opakovaně použitelnou funkci
- {% for %} - smyčka pro iteraci
- {% if %} - podmíněné větvení
Filtry
Filtry fungují jako modifikátory proměnných pro jedinou instanci a aplikují se pomocí pipe symbolu následovaného názvem filtru.
{{ 'string'|filter }}
Filtry mohou přijímat argumenty jako funkce.
{{ price|currency('CZK') }}
Filtry lze aplikovat postupně.
{{ 'October Glory'|upper|replace({'October': 'Morning'}) }}
Dostupné filtry
- |app - vytváří URL odkaz na aplikaci
- |page - vytváří URL odkaz na stránku
- |theme - vytváří URL odkaz na asset v šabloně
- |media - vytváří URL odkaz na soubor v media library
- |resize - změní velikost obrázku
- |default - poskytuje výchozí hodnotu
- |raw - zobrazuje obsah bez HTML escapování
- |md - zpracovává Markdown text
- |_ - lokalizační filtr pro překlad textů
Cykly
Pro iteraci nad polem nebo kolekcí použijte smyčku for
:
{% for produkt in produkty %}
<p>{{ produkt.nazev }} - {{ produkt.cena }} Kč</p>
{% else %}
<p>Žádné produkty k zobrazení.</p>
{% endfor %}
K dispozici je i objekt loop
s informacemi o průběhu cyklu:
{% for i in 1..5 %}
{{ loop.index }} / {{ loop.length }}
{% endfor %}
- loop.index - Aktuální iterace smyčky. (od indexu 1)
- loop.index0 - Aktuální iterace smyčky. (od indexu 0)
- loop.revindex - Počet iterací od konce smyčky (od indexu 1)
- loop.revindex0 - Počet iterací od konce smyčky (od indexu 0)
- loop.first - True, pokud jde o první iteraci
- loop.last - True, pokud jde o poslední iteraci
- loop.length - Počet položek v sekvenci
- loop.parent - Nadřazený kontext
Podmínky
Twig podporuje klasické if
podmínky:
{% if user %}
<p>Vítejte, {{ user.name }}!</p>
{% else %}
<p>Vítejte, hoste!</p>
{% endif %}
Operátory
Twig podporuje běžné operátory:
- Porovnávací:
==
,!=
,<
,>
,>=
,<=
- Logické:
and
,or
,not
- Slučovací:
??
pro výchozí hodnotu
{{ uzivatel.jmeno ?? 'Neznámý' }}
Testy
Twig obsahuje množství testů pro kontrolu typu a stavu:
{% if uzivatel is defined %}
{% if produkty is empty %}
{% if cislo is even %}
Dostupné testy zahrnují:
defined
,empty
,iterable
,even
,odd
,same as
,none
Funkce
Funkce umožňují spuštění logiky a návratový výsledek působí jako proměnná.
{{ function() }}
Funkce mohou přijímat argumenty.
{{ dump(variable) }}
Dostupné funkce
- abort() - přeruší zpracování požadavku s HTTP chybou
- redirect() - přesměruje uživatele na jinou URL
- dump() - zobrazuje debug informace o proměnné
- str() - poskytuje string helper funkce
- form() - poskytuje helper funkce pro formuláře
- html() - poskytuje helper funkce pro generování HTML
Logika přístupu
Nejdůležitější věc, kterou je třeba se naučit o Twig, je způsob, jakým přistupuje k PHP vrstvě. Pro zjednodušení {{ foo.bar }}
provádí následující kontroly na PHP objektu:
- Zkontroluje, zda je
foo
pole abar
platný element. - Pokud ne, a pokud je
foo
objekt, zkontroluje, zda jebar
platná vlastnost. - Pokud ne, a pokud je
foo
objekt, zkontroluje, zda jebar
platná metoda (i když bar je konstruktor - použijte__construct()
místo toho). - Pokud ne, a pokud je
foo
objekt, zkontroluje, zda jegetBar
platná metoda. - Pokud ne, a pokud je
foo
objekt, zkontroluje, zda jeisBar
platná metoda. - Pokud ne, vrátí hodnotu
null
.
Příklady přístupu
{{ user.name }} <!-- Vlastnost nebo metoda getName() -->
{{ user.isActive }} <!-- Metoda isActive() -->
{{ user.getEmail() }} <!-- Explicitní volání metody -->
{{ products[0] }} <!-- Element pole na indexu 0 -->
{{ settings.app_name }} <!-- Hodnota z konfigurace -->
Nepodporované funkce
Existují některé funkce z Twig, které nejsou podporovány. Jsou uvedeny níže vedle ekvivalentní funkce.
Tag | Ekvivalent |
---|---|
{% extend %} | Použijte Layouts nebo {% placeholder %} |
{% include %} | Použijte {% partial %} nebo {% content %} |
V šablonovacím systému je vlastní systém pro správu layoutů a vkládání obsahu:
- Layouts poskytují strukturovaný způsob definování layoutů stránek
- Partials umožňují znovupoužitelné komponenty s parametry
- Content blocks jsou určeny pro editovatelný obsah
Komponenty a částečné šablony (Partials)
Místo {% include %}
se používají Partials.
Partials
Partials slouží pro vkládání opakujících se částí šablon (např. hlavička, patička):
{% partial 'site/header' %}
Partials mohou přijímat parametry:
{% partial 'blog/post' post=record %}
Komponenty
Komponenty se přidávají do stránky nebo layoutu a zobrazují se pomocí:
{% component 'blogPosts' %}
Praktické příklady
Základní stránka
{% put title %}{{ this.page.title }}{% endput %}
{% put head %}
<meta name="description" content="{{ this.page.meta_description }}">
{% if this.page.keywords %}
<meta name="keywords" content="{{ this.page.keywords|join(', ') }}">
{% endif %}
{% endput %}
{% put content %}
<h1>{{ this.page.title }}</h1>
{% if featuredImage %}
<img src="{{ featuredImage|media|resize(800, 400) }}"
alt="{{ this.page.title }}">
{% endif %}
<div class="content">
{{ content|raw }}
</div>
{% if this.param.category %}
<nav class="breadcrumb">
<a href="{{ 'blog'|page }}">{{ 'Blog'|_ }}</a>
<span>/</span>
<span>{{ this.param.category|title }}</span>
</nav>
{% endif %}
{% endput %}
Pokročilý layout
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
{% placeholder title default %}{{ this.theme.site_name }}{% endplaceholder %}
</title>
{% placeholder head %}
<meta name="description" content="{{ this.theme.site_description }}">
{% endplaceholder %}
{% styles %}
<link href="{{ 'assets/css/app.css'|theme }}" rel="stylesheet">
{% endstyles %}
</head>
<body class="{{ this.page.id }}-page">
<header>
{% partial "header" %}
</header>
<main class="main-content">
{% placeholder content %}
<p>{{ 'Žádný obsah nebyl definován.'|_ }}</p>
{% endplaceholder %}
</main>
<footer>
{% content "footer.md" %}
</footer>
{% scripts %}
<script src="{{ 'assets/js/app.js'|theme }}"></script>
{% endscripts %}
{% if this.environment == 'local' %}
<!-- Debug panel pouze v dev prostředí -->
{{ dump(this.page, this.param) }}
{% endif %}
</body>
</html>
Komponenta s podmínkami
{% set showSidebar = this.page.id != 'home' and this.page.id != 'contact' %}
<div class="container {{ showSidebar ? 'with-sidebar' : 'full-width' }}">
<div class="main-content">
{% placeholder content %}
</div>
{% if showSidebar %}
<aside class="sidebar">
{% component "latestPosts" limit=5 %}
{% partial "newsletter-signup" %}
</aside>
{% endif %}
</div>
Best Practices
1. Používejte správné tagy
<!-- ✅ Správně -->
{% partial "header" user=currentUser %}
{% content "about-us.md" %}
{% page "blog-post" slug=article.slug %}
<!-- ❌ Špatně -->
{% include "header.htm" %} <!-- Nepodporováno -->
2. Escapování a bezpečnost
<!-- ✅ Bezpečné pro uživatelský obsah -->
{{ user.comment }}
<!-- ⚠️ Používejte pouze pro důvěryhodný obsah -->
{{ article.content|raw }}
<!-- ✅ Pro HTML z administrace -->
{{ settings.footer_html|raw }}
3. Výkon a optimalizace
<!-- ✅ Cache heavy operations -->
{% set expensiveData = getExpensiveData() %}
{% for item in expensiveData %}
{{ item.name }}
{% endfor %}
<!-- ✅ Podmíněné načítání -->
{% if this.page.id == 'contact' %}
{% component "contactForm" %}
{% endif %}
Obsah
- Šablonovací systém
- Základní syntaxe
- Proměnné
- Tagy
- Dostupné tagy
- Filtry
- Dostupné filtry
- Cykly
- Podmínky
- Operátory
- Testy
- Funkce
- Dostupné funkce
- Logika přístupu
- Příklady přístupu
- Nepodporované funkce
- Komponenty a částečné šablony (Partials)
- Partials
- Komponenty
- Praktické příklady
- Základní stránka
- Pokročilý layout
- Komponenta s podmínkami
- Best Practices
- 1. Používejte správné tagy
- 2. Escapování a bezpečnost
- 3. Výkon a optimalizace