RainTPL - Template Engine¶
RainTPL již není vyvíjen! Proto je vložen do core systému přímo a je upravovaný v rámci CMS pro vlastní potřebu.
Je to skvělý a hlavně jednoduchý systém šablon, který lze krásně ohýbat pro potřeby CMS, na rozdíl od vynikajícího Latte.
Základní příklad¶
Šablona index.tpl:
PHP kód:
$tpl = new Template();
$tpl->data('title', 'Moje stránka');
$tpl->data('content', '<h1>Vítej!</h1>');
echo $tpl->draw(__DIR__ . '/index.tpl');
Tagy a příkazy¶
{$proměnná} - Proměnné¶
Výstup dynamického obsahu šablony. Proměnné se nastavují metodou data().
Příklad:
Výstup:
Přístup k polím a vlastnostem¶
Tečková notace funguje pro pole i objekty – typ dat nezáleží:
{$data.key} {* Prvek pole nebo vlastnost objektu *}
{$data.user.name} {* Zanořený přístup – mix array/object transparentně *}
Modifikátory a operace¶
Matematické operace a funkce na proměnné:
{$a=1}
{$b=2}
{$sum=$a+$b}
{$title|cut:10} {* Ořízne na 10 znaků *}
{$title|touppercase|cut:7} {* Velká písmena, pak ořízne *}
{$value|Core\String\cut:100} {* Vlastní funkce *}
{$value|noescape} {* Neuniká HTML *}
{#konstanta#} - Konstanty¶
Přístup ke konstantám definovaným v PHP:
{if="výraz"} - Podmínky¶
Kontrola výrazu a podmíněný výstup:
{loop="$pole"} - Cykly¶
Smyčka přes prvky pole nebo objektu:
Výstup:
Speciální proměnné v cyklu¶
{loop="$items"}
{$key} {* Klíč prvku *}
{$value} {* Hodnota prvku *}
{$counter} {* Počet iterací (od 0) *}
{if="$counter == 5"} {break} {/if} {* Ukončit cyklus *}
{if="$counter == 3"} {continue} {/if} {* Přeskočit iteraci *}
{/loop}
{function="funkce()"} - Funkce¶
Volání PHP funkce a výpis výsledku:
Výstup:
{* komentář *} - Komentáře¶
Vše mezi {* a *} se ignoruje:
Výstup:
Alternativa s {ignore}:
{noparse} - Bez parsování¶
Obsah mezi {noparse} a {/noparse} se nekompiluje:
Výstup:
{autoescape="off"} - Escapování HTML¶
Standardně se HTML escapuje. Vypnout escapování:
Příklad:
Výstup:
Bez vypnutí escapování by výstup byl:
Bezpečnost a ochrana¶
RainTPL v Petrovo CMS má zabudovanou ochranu proti nebezpečným operacím v šablonách.
Blocklist validátor¶
Všechny šablony jsou kontrolovány v průběhu kompilace prostřednictvím BlocklistValidator třídy. Blokovány jsou PHP funkce, které by mohly:
- Provádět kód –
eval,exec,system,shell_exec, atd. - Manipulovat souborovým systémem –
unlink,rmdir,mkdir,file_put_contents, atd. - Přistupovat k síti –
curl_exec,fsockopen,ftp_*, atd. - Odhalovat informace –
phpinfo,php_uname,posix_getpwuid, atd. - Dynamicky volat funkce –
call_user_func,call_user_func_array,forward_static_call, atd. - Manipulovat konfigurací –
ini_alter,ini_get_all,parse_ini_file, atd.
Pokud se pokusíte použít blokovanou funkci, kompilace šablony selže s chybou:
Automatické escapování¶
RainTPL automaticky escapuje všechny proměnné pro bezpečnost proti XSS útokům. Escapuje se přes htmlspecialchars(..., ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'):
ENT_QUOTES– escapuje dvojité i jednoduché uvozovky, takže je proměnná bezpečná i v HTML atributech.ENT_SUBSTITUTE– nevalidní UTF-8 se nahradí znakem U+FFFD místo zahození celého řetězce. Bez tohoto flagu byhtmlspecialcharspři rozbitém vstupu (špatně zakódovaná data z DB apod.) vrátil prázdný řetězec a hodnota by tiše zmizela.
Příklad:
Pokud $user_input obsahuje <script>alert('XSS')</script>, bude vypsáno:
Vypnutí escapování¶
Sometimes you need to allow safe HTML. Use |noescape modifier or {autoescape="off"} block:
⚠️ UPOZORNĚNÍ: Vypněte escapování POUZE pro obsah, kterému 100% věříte! Nikdy ne pro user input.
Bezpečné vs nebezpečné vzory¶
Bezpečné – automatické escapování:
Bezpečné – explicitní noescape pro zařízené HTML:
Nebezpečné – dynamické generování kódu:
{* ❌ NEVĚNUJTE SE TOMU – Blokováno! *}
{function="eval($code)"}
{function="call_user_func($callback)"}
Kontextové escapování¶
Důležité: HTML escapování není vhodné pro všechny kontexty. Pro JavaScript, URL nebo CSS buďte extra opatrní:
{* ✅ HTML kontext – bezpečné *}
<div title="{$user_title}">{$user_name}</div>
{* ⚠️ JavaScript kontext – escapování nestačí! *}
<script>
var username = "{$user_name}"; {* Potřeba JSON escapování! *}
</script>
{* ⚠️ URL kontext – escapování nestačí! *}
<a href="search?q={$query}">Search</a> {* Potřeba urlencode! *}
Doporučené řešení pro specifické kontexty:
{* JavaScript – json_encode vytvoří bezpečný JS literál, noescape zabrání HTML-escapování *}
<script>
var userData = {$user_data|json_encode|noescape};
</script>
{* URL – escapujte v PHP *}
{* Nastavte v controlleru: $tpl->data('safe_query', urlencode($query)) *}
<a href="search?q={$safe_query}">Search</a>
{* Atribut – HTML escapování stačí *}
<div data-config="{$config|noescape}">
Automatická ochrana URL atributů (UrlSanitizer)¶
Kromě escapování běží v post-processing fázi (after(), viz core/Template/After/UrlSanitizer.php) automatický skener hotového HTML, který slouží jako druhá obranná vrstva proti XSS přes nebezpečná URL schémata.
Skenují se atributy href, src, action, formaction. Pokud jejich hodnota začíná schématem javascript:, data: nebo vbscript: (case-insensitive, i s úvodními bílými/řídicími znaky), je hodnota nahrazena # a incident se zaloguje do security logu.
{* Vstup z dat (např. uživatelem zadaná URL) *}
<a href="{$link}">Odkaz</a>
{* Pokud $link = "javascript:alert(1)", výsledné HTML bude: *}
<a href="#">Odkaz</a>
Tohle řeší přesně třídu útoků, kterou samotné HTML escapování neumí — javascript: URL projde htmlspecialchars beze změny, protože neobsahuje žádné HTML speciální znaky. UrlSanitizer ji zachytí až nad hotovým HTML.
Pozn.:
UrlSanitizerje pojistka, ne náhrada za rozvahu. Pro plnou kontrolu nad URL ji ideálně validuj/normalizuj už v controlleru. Skener pokrývá pouze uvozené atributy z výčtu výše.
Konfigurace¶
RainTPL se konfiguruje přes BaseTemplate::configure() před prvním použitím. V CMS probíhá automaticky — konstanta DIR slouží jako fallback. Pro standalone použití mimo CMS je nutné konfiguraci předat explicitně:
Dostupné klíče:
| klíč | typ | popis |
|---|---|---|
tpl_dir |
string | povinné — absolutní cesta k adresáři šablon |
cache_dir |
string | povinné — absolutní cesta k adresáři zkompilovaných šablon |
auto_escape |
bool | automatické HTML escapování proměnných (výchozí: true) |
Poznámky¶
- Proměnné jsou case-sensitive
- RainTPL je součást CMS a je upravován pro vlastní potřebu
{include}tag není podporován — skládání šablon zajišťuje nadřazený systém{+ partial}vBaseTemplate- RainTPL slouží jako podklad pro finální renderování šablon — vlastní tagy
{T},{+},{S}se zpracovávají vBaseTemplatepřed předáním do Rain