Fejlesztői eljárások
Telepítés
A Latte telepítésének legjobb módja a Composer használata:
composer require latte/latte
Támogatott PHP verziók (a Latte legutolsó alverzióira vonatkozik):
verzió | kompatibilis PHP-vel |
---|---|
Latte 3.0 | PHP 8.0 – 8.2 |
Hogyan rendereljünk sablont
Hogyan rendereljünk sablont? Ehhez elég ez az egyszerű kód:
$latte = new Latte\Engine;
// könyvtár a gyorsítótárhoz
$latte->setTempDirectory('/path/to/tempdir');
$params = [ /* sablon változók */ ];
// vagy $params = new TemplateParameters(/* ... */);
// rajzolás a kimenetre
$latte->render('template.latte', $params);
// rajzolás változóba
$output = $latte->renderToString('template.latte', $params);
A paraméterek lehetnek tömbök vagy még jobb egy objektum, amely biztosítja a típusellenőrzést és a súgást a szerkesztőkben.
Használati példákat a Latte examples repozitóriumban is találhat.
Teljesítmény és gyorsítótár
A Latte sablonok rendkívül gyorsak, mivel a Latte közvetlenül PHP kódra fordítja őket, és a lemezen lévő gyorsítótárban tárolja. Így nincs többlet terhelésük a tiszta PHP-ban írt sablonokhoz képest.
A gyorsítótár automatikusan újragenerálódik minden alkalommal, amikor megváltoztatja a forrásfájlt. Így a fejlesztés során kényelmesen szerkesztheti a Latte sablonokat, és a változásokat azonnal láthatja a böngészőben. Ezt a funkciót a produkciós környezetben kikapcsolhatja, hogy egy kis teljesítményt spóroljon:
$latte->setAutoRefresh(false);
A produkciós szerverre történő telepítéskor a gyorsítótár kezdeti generálása, különösen nagyobb alkalmazások esetén, természetesen eltarthat egy ideig. A Latte beépített védelemmel rendelkezik a cache stampede ellen. Ez egy olyan helyzet, amikor nagyobb számú párhuzamos kérés érkezik, amelyek elindítják a Latte-t, és mivel a gyorsítótár még nem létezik, mindegyik egyszerre kezdené el generálni. Ez aránytalanul megterhelné a szervert. A Latte okos, és több párhuzamos kérés esetén csak az első szál generálja a gyorsítótárat, a többiek várnak, majd azt használják.
Paraméterek osztályként
Jobb, mint a változókat tömbként átadni a sablonnak, ha létrehozunk egy osztályt. Így típusbiztos írást, kellemes súgást az IDE-ben és utat kapunk a szűrők és függvények regisztrálásához.
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,
));
Változó automatikus escapelésének kikapcsolása
Ha egy változó HTML stringet tartalmaz, megjelölheti úgy, hogy a Latte ne escapelje automatikusan (és így duplán). Ezzel
elkerülheti a |noescape
használatának szükségességét a sablonban.
A legegyszerűbb módja, ha a stringet egy Latte\Runtime\Html
objektumba csomagolja:
$params = [
'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];
A Latte továbbá nem escapeli az összes olyan objektumot, amely implementálja a Latte\HtmlStringable
interfészt. Így létrehozhat saját osztályt, amelynek __toString()
metódusa olyan HTML kódot ad vissza, amely
nem lesz automatikusan escapelve:
class Emphasis extends Latte\HtmlStringable
{
public function __construct(
private string $str,
) {
}
public function __toString(): string
{
return '<em>' . htmlspecialchars($this->str) . '</em>';
}
}
$params = [
'foo' => new Emphasis('hello'),
];
A __toString
metódusnak korrekt HTML-t kell visszaadnia, és biztosítania kell a paraméterek
escapelését, különben XSS sebezhetőség léphet fel!
Hogyan bővítsük a Latte-t szűrőkkel, tagekkel stb.
Hogyan adjunk hozzá saját szűrőt, függvényt, taget stb. a Latte-hoz? Erről szól a Latte bővítése fejezet. Ha a módosításait különböző projektekben szeretné újra felhasználni, vagy megosztani másokkal, akkor hozzon létre egy kiterjesztést.
Tetszőleges kód a sablonban {php ...}
A {do}
tag belsejében csak PHP kifejezéseket lehet írni,
így például nem illeszthet be olyan konstrukciókat, mint if ... else
vagy pontosvesszővel lezárt
utasításokat.
Azonban regisztrálhatja a RawPhpExtension
kiterjesztést, amely hozzáadja a {php ...}
taget. Ezzel
bármilyen PHP kódot beilleszthet. Rá nem vonatkoznak a sandbox mód szabályai, így a használata a sablon szerzőjének
felelőssége.
$latte->addExtension(new Latte\Essential\RawPhpExtension);
Generált kód ellenőrzése
A Latte a sablonokat PHP kódra fordítja. Természetesen ügyel arra, hogy a generált kód szintaktikailag érvényes
legyen. Azonban harmadik féltől származó kiterjesztések vagy a RawPhpExtension
használata esetén a Latte nem
tudja garantálni a generált fájl helyességét. Továbbá PHP-ban lehet olyan kódot írni, amely bár szintaktikailag helyes,
de tiltott (például érték hozzárendelése a $this
változóhoz), és PHP Compile Errort okoz. Ha ilyen
műveletet ír a sablonba, az bekerül a generált PHP kódba is. Mivel a PHP-ban több mint kétszáz különböző tiltott
művelet létezik, a Latte-nak nincs ambíciója ezeket felderíteni. Ezekre csak maga a PHP hívja fel a figyelmet a
rendereléskor, ami általában nem okoz problémát.
Vannak azonban helyzetek, amikor már a sablon fordításakor tudni szeretné, hogy nem tartalmaz PHP Compile Errort.
Különösen akkor, ha a sablonokat a felhasználók szerkeszthetik, vagy Sandboxot használ. Ebben az esetben ellenőriztesse a sablonokat már a
fordításkor. Ezt a funkcionalitást az Engine::enablePhpLint()
metódussal kapcsolhatja be. Mivel az
ellenőrzéshez PHP bináris fájlt kell hívnia, adja át annak elérési útját paraméterként:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
// elkapja a Latte hibáit és a PHP Compile Error-t is
echo 'Hiba: ' . $e->getMessage();
}
Nemzeti beállítások
A Latte lehetővé teszi a nemzeti beállítások megadását, amelyek befolyásolják a számok, dátumok formázását és a
rendezést. Ezt a setLocale()
metódussal állíthatja be. A környezet azonosítója az IETF language tag
szabványt követi, amelyet a PHP intl
kiterjesztése használ. A nyelv kódjából és adott esetben az ország
kódjából áll, pl. en_US
az angolhoz az Egyesült Államokban, de_DE
a némethez
Németországban stb.
$latte = new Latte\Engine;
$latte->setLocale('hu');
A környezet beállítása befolyásolja a localDate, sort, number és bytes szűrőket.
Szükséges a PHP intl
kiterjesztés. A Latte beállítása nem befolyásolja a PHP globális locale
beállításait.
Szigorú mód
Szigorú parzolási módban a Latte ellenőrzi, hogy hiányoznak-e a záró HTML tagek, és letiltja a $this
változó használatát is. Így kapcsolhatja be:
$latte = new Latte\Engine;
$latte->setStrictParsing();
A sablonok generálását declare(strict_types=1)
fejléccel így kapcsolhatja be:
$latte = new Latte\Engine;
$latte->setStrictTypes();
Fordítás sablonokban
A TranslatorExtension
kiterjesztés segítségével hozzáadhatja a sablonhoz a {_...}
, {translate}
tageket és a translate
szűrőt. Ezek értékek vagy sablonrészek
más nyelvekre történő fordítására szolgálnak. Paraméterként megadjuk a fordítást végző metódust (PHP callable):
class MyTranslator
{
public function __construct(private string $lang)
{}
public function translate(string $original): string
{
// az $original alapján létrehozzuk a $translated-et a $this->lang szerint
return $translated;
}
}
$translator = new MyTranslator($lang);
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...), // [$translator, 'translate'] PHP 8.0-ban
);
$latte->addExtension($extension);
A fordító futásidőben hívódik meg a sablon renderelésekor. A Latte azonban képes az összes statikus szöveget már a sablon fordítása során lefordítani. Ezzel teljesítményt takarítunk meg, mivel minden string csak egyszer fordítódik le, és az eredményül kapott fordítás beíródik a lefordított formába. Így a gyorsítótár könyvtárában több lefordított sablonverzió jön létre, minden nyelvhez egy. Ehhez elég csak a nyelvet megadni második paraméterként:
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...),
$lang,
);
Statikus szöveg alatt például a {_'hello'}
vagy {translate}hello{/translate}
értendő. A nem
statikus szövegek, mint például {_$foo}
, továbbra is futásidőben kerülnek fordításra.
A fordítónak a sablonból kiegészítő paramétereket is átadhatunk a {_$original, foo: bar}
vagy
{translate foo: bar}
segítségével, amelyeket $params
tömbként kap meg:
public function translate(string $original, ...$params): string
{
// $params['foo'] === 'bar'
}
Debuggolás és Tracy
A Latte igyekszik a fejlesztést a lehető legkellemesebbé tenni. Közvetlenül a debuggolás céljára létezik három tag:
{dump}
, {debugbreak}
és {trace}
.
A legnagyobb kényelmet akkor éri el, ha még telepíti a kiváló Tracy hibakereső eszközt és aktiválja a Latte kiegészítőt:
// bekapcsolja a Tracy-t
Tracy\Debugger::enable();
$latte = new Latte\Engine;
// aktiválja a Tracy kiterjesztést
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
Mostantól minden hiba áttekinthető piros képernyőn jelenik meg, beleértve a sablonhibákat is a sor és oszlop kiemelésével (videó). Ugyanakkor a jobb alsó sarokban, az ún. Tracy Barban megjelenik egy fül a Latte számára, ahol áttekinthetően láthatók az összes renderelt sablon és azok kölcsönös kapcsolatai (beleértve a sablonba vagy a lefordított kódba való átkattintás lehetőségét is), valamint a változók:

Mivel a Latte a sablonokat áttekinthető PHP kódra fordítja, kényelmesen lépésenként végigkövetheti őket az IDE-jében.
Linter: sablonok szintaxisának validálása
Az összes sablon átnézéséhez és annak ellenőrzéséhez, hogy nem tartalmaznak-e szintaktikai hibákat, a Linter eszköz segít. Konzolból indítható:
vendor/bin/latte-lint <útvonal>
A --strict
paraméterrel aktiválhatja a szigorú módot.
Ha saját tageket használ, hozzon létre saját Linter verziót is, pl. custom-latte-lint
:
#!/usr/bin/env php
<?php
// adja meg az autoload.php fájl tényleges elérési útját
require __DIR__ . '/vendor/autoload.php';
$path = $argv[1] ?? '.';
$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
// itt adja hozzá az egyes saját kiterjesztéseit
$latte->addExtension(/* ... */);
$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);
Alternatívaként átadhatja a saját Latte\Engine
objektumát a Linternek:
$latte = new Latte\Engine;
// itt konfiguráljuk a $latte objektumot
$linter = new Latte\Tools\Linter(engine: $latte);
Sablonok betöltése stringből
Szüksége van sablonok betöltésére stringekből fájlok helyett, például tesztelési célokra? Segít a 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
Definiálhat saját kezelőt a várt kivételekhez. Átadódnak neki a {try}
belsejében és a sandboxban keletkezett kivételek.
$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
$logger->log($e);
};
$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);
Layout automatikus keresése
A {layout}
tag
segítségével a sablon meghatározza a szülő sablonját. Lehetőség van a layout automatikus keresésére is, ami
leegyszerűsíti a sablonok írását, mivel nem lesz szükség bennük a {layout}
tag megadására.
Ezt a következő módon érhetjük el:
$finder = function (Latte\Runtime\Template $template) {
if (!$template->getReferenceType()) {
// visszaadja a layout fájl elérési útját
return 'automatic.layout.latte';
}
};
$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);
Ha a sablonnak nem kell layout, azt a {layout none}
taggal jelzi.