Vývojářské postupy
Instalace
Nejlepší způsob instalace Latte je pomocí Composeru:
composer require latte/latte
Podporované verze PHP (platí pro poslední setinkové verze Latte):
verze | kompatibilní s PHP |
---|---|
Latte 3.0 | PHP 8.0 – 8.2 |
Vykreslení šablony
Jak vykreslit šablonu? Stačí k tomu tento jednoduchý kód:
$latte = new Latte\Engine;
// nastavení adresáře pro cache
$latte->setTempDirectory('/path/to/tempdir');
$params = [ /* proměnné šablony */ ];
// nebo $params = new TemplateParameters(/* ... */);
// vykreslení na výstup
$latte->render('template.latte', $params);
// vykreslení do proměnné
$output = $latte->renderToString('template.latte', $params);
Parametry mohou být pole nebo ještě lépe objekt, který zajistí typovou kontrolu a napovídání v editorech.
Ukázky použití najdete také v repozitáři Latte examples.
Výkon a cache
Šablony v Latte jsou extrémně rychlé, protože se kompilují přímo do PHP kódu a ukládají do cache na disk. Nemají tedy žádnou režii navíc oproti šablonám psaným v čistém PHP.
Cache se automaticky regeneruje při změně zdrojového souboru. Během vývoje tedy pohodlně editujete šablony v Latte a změny okamžitě vidíte v prohlížeči. Pro mírné zvýšení výkonu v produkčním prostředí můžete automatickou regeneraci vypnout:
$latte->setAutoRefresh(false);
Při nasazení na produkční server může prvotní vygenerování cache, zejména u rozsáhlých aplikací, chvíli trvat. Latte má vestavěnou prevenci proti cache stampede, což je situace, kdy velký počet souběžných požadavků spustí generování cache současně, což by mohlo přetížit server. Latte tento problém řeší chytře – při více souběžných požadavcích generuje cache pouze první vlákno, zatímco ostatní čekají a následně využijí vytvořenou cache.
Parametry jako třída
Místo předávání proměnných do šablony jako pole je lepší vytvořit si třídu. Získáte tak typově bezpečný zápis, příjemné napovídání v IDE a možnost registrace filtrů a funkcí.
class MailTemplateParameters
{
public function __construct(
public string $lang,
public Address $address,
public string $subject,
public array $items,
public ?float $price = null,
) {}
}
$latte->render('mail.latte', new MailTemplateParameters(
lang: $this->lang,
subject: $title,
price: $this->getPrice(),
items: [],
address: $userAddress,
));
Vypnutí auto-escapování proměnné
Pokud proměnná obsahuje HTML řetězec, můžete ji označit tak, aby ji Latte automaticky (a tedy dvojitě) neescapovalo.
Tím se vyhnete potřebě uvádět v šabloně |noescape
.
Nejjednodušší způsob je zabalit řetězec do objektu Latte\Runtime\Html
:
$params = [
'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];
Latte také neescapuje objekty implementující rozhraní Latte\HtmlStringable
. Můžete si vytvořit vlastní
třídu, jejíž metoda __toString()
bude vracet HTML kód, který se nebude automaticky escapovat:
class Emphasis implements Latte\HtmlStringable
{
public function __construct(
private string $str,
) {
}
public function __toString(): string
{
return '<em>' . htmlspecialchars($this->str) . '</em>';
}
}
$params = [
'foo' => new Emphasis('hello'),
];
Metoda __toString
musí vracet korektní HTML a zajistit escapování parametrů, jinak může
dojít ke zranitelnosti XSS!
Jak rozšířit Latte o filtry, značky atd.
Informace o přidávání vlastních filtrů, funkcí, značek atd. najdete v kapitole rozšiřujeme Latte. Pokud chcete své úpravy znovu použít v různých projektech nebo je sdílet s ostatními, měli byste vytvořit rozšíření.
Libovolný PHP kód v šabloně {php ...}
Zatímco uvnitř značky {do}
lze zapisovat pouze PHP
výrazy, rozšíření RawPhpExtension
přidává značku {php ...}
, která umožňuje vkládat
jakýkoliv PHP kód. Použití je na zodpovědnost autora šablony, protože se na ni nevztahují pravidla sandbox režimu.
$latte->addExtension(new Latte\Essential\RawPhpExtension);
Kontrola vygenerovaného kódu
Latte kompiluje šablony do PHP kódu a dbá na jeho syntaktickou správnost. Nicméně při použití rozšíření třetích
stran nebo RawPhpExtension
nemůže Latte zaručit korektnost vygenerovaného souboru. V PHP lze také zapsat kód,
který je syntakticky správný, ale zakázaný (například přiřazení hodnoty do $this
) a způsobí PHP Compile
Error. Pokud takovou operaci zapíšete v šabloně, dostane se i do vygenerovaného PHP kódu. Jelikož v PHP existují na
dvě stovky různých zakázaných operací, nemá Latte ambici je odhalovat. Upozorní na ně až samotné PHP při vykreslení,
což obvykle ničemu nevadí.
Pokud chcete odhalit tyto problémy už v době kompilace šablony, zejména pokud šablony mohou editovat uživatelé nebo
používáte Sandbox, můžete zapnout kontrolu pomocí
Engine::enablePhpLint()
. Ke kontrole je potřeba volat binárku PHP, jejíž cestu předáte jako parametr:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
// zachytí chyby v Latte a také Compile Error v PHP
echo 'Error: ' . $e->getMessage();
}
Národní prostředí
Latte umožňuje nastavit národní prostředí, které ovlivňuje formátování čísel, datumů a řazení. Nastavuje se
pomocí metody setLocale()
. Identifikátor prostředí se řídí standardem IETF language tag, který používá
rozšíření PHP intl
. Skládá se z kódu jazyka a případně kódu země, např. en_US
pro
angličtinu ve Spojených státech, de_DE
pro němčinu v Německu atd.
$latte = new Latte\Engine;
$latte->setLocale('cs');
Nastavení prostředí ovlivňuje filtry localDate, sort, number a bytes.
Vyžaduje PHP rozšíření intl
. Nastavení v Latte neovlivňuje globální nastavení locale
v PHP.
Striktní režim
Ve striktním režimu parsování Latte kontroluje, zda nechybí uzavírací HTML značky a zakazuje používání proměnné
$this
. Zapnete jej takto:
$latte = new Latte\Engine;
$latte->setStrictParsing();
Generování šablon s hlavičkou declare(strict_types=1)
zapnete takto:
$latte = new Latte\Engine;
$latte->setStrictTypes();
Překládání v šablonách
Rozšíření TranslatorExtension
přidává do šablony značky {_...}
, {translate}
a filtr translate
pro překládání hodnot nebo částí
šablony do jiných jazyků. Jako parametr uvedeme metodu provádějící překlad:
class MyTranslator
{
public function __construct(private string $lang)
{}
public function translate(string $original): string
{
// z $original vytvoříme $translated dle $this->lang
return $translated;
}
}
$translator = new MyTranslator($lang);
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...), // [$translator, 'translate'] v PHP 8.0
);
$latte->addExtension($extension);
Translator se volá za běhu při vykreslování šablony. Latte ovšem umí všechny statické texty překládat už během kompilace šablony. Tím se ušetří výkon, protože každý řetězec se přeloží jen jednou a výsledný překlad se zapíše do zkompilované podoby. V adresáři s cache tak vznikne více zkompilovaných verzí šablony, jedna pro každý jazyk. K tomu stačí pouze uvést jazyk jako druhý parametr:
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...),
$lang,
);
Statickým textem je myšleno třeba {_'hello'}
nebo {translate}hello{/translate}
. Nestatické texty,
jako třeba {_$foo}
, se nadále budou překládat za běhu.
Překladači lze ze šablony předávat i doplňující parametry pomocí {_$original, foo: bar}
nebo
{translate foo: bar}
, které získá jako pole $params
:
public function translate(string $original, ...$params): string
{
// $params['foo'] === 'bar'
}
Debuggování a Tracy
Latte se vám snaží vývoj co nejvíce zpříjemnit. Nabízí několik nástrojů pro debugování, včetně značek {dump}
, {debugbreak}
a {trace}
.
Největší komfort získáte, když ještě si nainstalujete skvělý ladicí nástroj Tracy a aktivujete doplněk pro Latte:
// zapne Tracy
Tracy\Debugger::enable();
$latte = new Latte\Engine;
// aktivuje rozšíření pro Tracy
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
Nyní se vám budou všechny chyby zobrazovat v přehledné červené obrazovce, včetně chyb v šablonách se zvýrazněním řádku a sloupce (video). Zároveň v pravém dolním rohu v tzv. Tracy Baru se objeví záložka pro Latte, kde jsou přehledně vidět všechny vykreslované šablony a jejich vzájemné vztahy (včetně možnosti se do šablony nebo zkompilovaného kódu prokliknout) a také proměnné:
Jelikož Latte kompiluje šablony do přehledného PHP kódu, můžete je pohodlně krokovat ve svém IDE.
Linter: validace syntaxe šablon
Pro kontrolu syntaxe všech šablon můžete použít nástroj Linter, který se spouští z konzole:
vendor/bin/latte-lint <cesta>
Parametrem --strict
aktivujete striktní režim.
Pokud používáte vlastní značky, vytvořte si vlastní verzi Linteru, např. custom-latte-lint
:
#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
$path = $argv[1] ?? '.';
$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
// zde přidejte svá rozšíření
$latte->addExtension(/* ... */);
$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);
Alternativně můžete předat vlastní objekt Latte\Engine
do Linteru:
$latte = new Latte\Engine;
// zde nakonfigurujeme objekt $latte
$linter = new Latte\Tools\Linter(engine: $latte);
Načítání šablon z řetězce
Pro načítání šablon z řetězců, například pro účely testování, můžete použít StringLoader:
$latte->setLoader(new Latte\Loaders\StringLoader([
'main.file' => '{include other.file}',
'other.file' => '{if true} {$var} {/if}',
]));
$latte->render('main.file', $params);
Exception handler
Můžete si definovat vlastní obslužný handler pro očekávané výjimky. Předají se mu výjimky vzniklé uvnitř {try}
a v sandboxu.
$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
$logger->log($e);
};
$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);
Automatické dohledávání layoutu
Pomocí značky {layout}
šablona určuje svou rodičovskou šablonu. Je taky možné nechat dohledávat layout automaticky, což zjednoduší psaní
šablon, neboť v nich nebude nutné značku {layout}
uvádět.
Dosáhne se toho následujícím způsobem:
$finder = function (Latte\Runtime\Template $template) {
if (!$template->getReferenceType()) {
// vrací cestu k souboru s layoutem
return 'automatic.layout.latte';
}
};
$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);
Pokud šablona nemá mít layout, použije se značka {layout none}
.