Razvojni postopki
Namestitev
Najboljši način za namestitev Latte je s pomočjo Composerja:
composer require latte/latte
Podprte različice PHP (velja za zadnje stotinske različice Latte):
različica | združljivo s PHP |
---|---|
Latte 3.0 | PHP 8.0 – 8.2 |
Kako izrisati predlogo
Kako izrisati predlogo? Dovolj je ta preprost koda:
$latte = new Latte\Engine;
// imenik za predpomnilnik
$latte->setTempDirectory('/path/to/tempdir');
$params = [ /* spremenljivke predloge */ ];
// or $params = new TemplateParameters(/* ... */);
// izriši na izhod
$latte->render('template.latte', $params);
// izriši v spremenljivko
$output = $latte->renderToString('template.latte', $params);
Parametri so lahko polja ali še bolje objekt, ki zagotavlja tipsko kontrolo in predlaganje v urejevalnikih.
Primeri uporabe najdete tudi v repozitoriju Latte examples.
Zmogljivost in predpomnilnik
Predloge v Latte so izjemno hitre, Latte jih namreč prevede neposredno v PHP kodo in shrani v predpomnilnik na disk. Nimajo torej nobene dodatne režije v primerjavi s predlogami, napisanimi v čistem PHP.
Predpomnilnik se samodejno regenerira vsakič, ko spremenite izvorno datoteko. Med razvojem si torej udobno urejate predloge v Latte in spremembe takoj vidite v brskalniku. To funkcijo lahko v produkcijskem okolju izklopite in prihranite malo zmogljivosti:
$latte->setAutoRefresh(false);
Pri uvajanju na produkcijski strežnik lahko prvotno generiranje predpomnilnika, zlasti pri obsežnejših aplikacijah, seveda traja nekaj časa. Latte ima vgrajeno preprečevanje pred `cache stampede. Gre za situacijo, ko se zbere večje število sočasnih zahtev, ki sprožijo Latte, in ker predpomnilnik še ne obstaja, bi ga vse začele generirati hkrati. Kar bi nesorazmerno obremenilo strežnik. Latte je pameten in pri več sočasnih zahtevah generira predpomnilnik samo prva nit, ostale čakajo in ga nato uporabijo.
Parametri kot razred
Bolje kot predajati spremenljivke v predlogo kot polje je ustvariti si razred. Dobite tako tipsko varen zapis, prijetno predlaganje v IDE in pot za registracijo filtrov in funkcij.
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,
));
Izklop samodejnega ubežanja spremenljivke
Če spremenljivka vsebuje niz v HTML, jo lahko označite tako, da je Latte samodejno (in torej dvakrat) ne ubeži. Izognete se
tako potrebi po navajanju |noescape
v predlogi.
Najenostavnejša pot je niz zaviti v objekt Latte\Runtime\Html
:
$params = [
'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];
Latte nadalje ne ubeži vseh objektov, ki implementirajo vmesnik Latte\HtmlStringable
. Lahko si tako ustvarite
lasten razred, katerega metoda __toString()
bo vračala HTML kodo, ki se ne bo samodejno ubežala:
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'),
];
Metoda __toString
mora vrniti korekten HTML in zagotoviti ubežanje parametrov, sicer lahko pride
do ranljivosti XSS!
Kako razširiti Latte s filtri, značkami itd.
Kako v Latte dodati lasten filter, funkcijo, značko itd.? O tem govori poglavje razširjamo Latte. Če želite svoje prilagoditve ponovno uporabiti v različnih projektih ali jih deliti z drugimi, bi morali ustvariti razširitev.
Poljubna koda v predlogi {php ...}
Znotraj značke {do}
je mogoče zapisovati le PHP izraze, ne
morete pa na primer vstaviti konstrukcij, kot sta if ... else
ali stavkov, zaključenih s podpičjem.
Lahko pa si registrirate razširitev RawPhpExtension
, ki dodaja značko {php ...}
. S pomočjo te je
mogoče vstavljati kakršno koli PHP kodo. Zanjo ne veljajo nobena pravila peskovniškega načina, uporaba je torej na odgovornost
avtorja predloge.
$latte->addExtension(new Latte\Essential\RawPhpExtension);
Preverjanje generirane kode
Latte prevaja predloge v PHP kodo. Seveda skrbi za to, da je generirana koda sintaktično veljavna. Vendar pri uporabi
razširitev tretjih oseb ali RawPhpExtension
Latte ne more zagotoviti pravilnosti generirane datoteke. Prav tako je
mogoče v PHP zapisati kodo, ki je sicer sintaktično pravilna, vendar je prepovedana (na primer dodelitev vrednosti
spremenljivki $this
) in povzroči PHP Compile Error. Če tako operacijo zapišete v predlogi, pride tudi
v generirano PHP kodo. Ker v PHP obstaja na dvesto različnih prepovedanih operacij, Latte nima ambicije jih odkrivati. Nanjo
opozori šele sam PHP pri izrisovanju, kar običajno ničesar ne ovira.
So pa situacije, ko želite vedeti že v času prevajanja predloge, da ne vsebuje nobenega PHP Compile Error. Zlasti takrat,
ko lahko predloge urejajo uporabniki ali uporabljate Sandbox. V takem primeru si
pustite predloge preverjati že v času prevajanja. To funkcionalnost vklopite z metodo Engine::enablePhpLint()
.
Ker za preverjanje potrebuje klicati PHP binarno datoteko, pot do nje predajte kot parameter:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
// prestreže napake v Latte in tudi Compile Error v PHP
echo 'Napaka: ' . $e->getMessage();
}
Nacionalno okolje
Latte omogoča nastavitev nacionalnega okolja, ki vpliva na formatiranje števil, datumov in razvrščanje. Nastavlja se
s pomočjo metode setLocale()
. Identifikator okolja sledi standardu IETF language tag, ki ga uporablja PHP
razširitev intl
. Sestavljen je iz kode jezika in po potrebi kode države, npr. en_US
za angleščino
v Združenih državah, de_DE
za nemščino v Nemčiji itd.
$latte = new Latte\Engine;
$latte->setLocale('sl');
Nastavitev okolja vpliva na filtre localDate, sort, number in bytes.
Zahteva PHP razširitev intl
. Nastavitev v Latte ne vpliva na globalno nastavitev locale v PHP.
Strogi način
V strogem načinu razčlenjevanja Latte preverja, ali manjkajo zaključne HTML značke in tudi prepoveduje uporabo
spremenljivke $this
. Vklopite ga takole:
$latte = new Latte\Engine;
$latte->setStrictParsing();
Generiranje predlog z glavo declare(strict_types=1)
vklopite takole:
$latte = new Latte\Engine;
$latte->setStrictTypes();
Prevajanje v predlogah
S pomočjo razširitve TranslatorExtension
dodate v predlogo značke {_...}
, {translate}
in filter translate
. Služijo za prevajanje vrednosti ali delov
predloge v druge jezike. Kot parameter navedemo metodo (PHP callable), ki izvaja prevod:
class MyTranslator
{
public function __construct(private string $lang)
{}
public function translate(string $original): string
{
// iz $original ustvarimo $translated glede na $this->lang
return $translated;
}
}
$translator = new MyTranslator($lang);
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...), // [$translator, 'translate'] v PHP 8.0
);
$latte->addExtension($extension);
Prevajalnik se kliče med izvajanjem pri izrisovanju predloge. Latte pa zna vse statične tekste prevajati že med prevajanjem predloge. S tem se prihrani zmogljivost, ker se vsak niz prevede le enkrat in končni prevod se zapiše v prevedeno obliko. V imeniku s predpomnilnikom tako nastane več prevedenih različic predloge, ena za vsak jezik. Za to je dovolj le navesti jezik kot drugi parameter:
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...),
$lang,
);
Statični tekst je mišljeno na primer {_'hello'}
ali {translate}hello{/translate}
. Nestatični
teksti, kot na primer {_$foo}
, se še naprej prevajajo med izvajanjem.
Prevajalniku lahko iz predloge predajate tudi dopolnilne parametre s pomočjo {_$original, foo: bar}
ali
{translate foo: bar}
, ki jih dobi kot polje $params
:
public function translate(string $original, ...$params): string
{
// $params['foo'] === 'bar'
}
Razhroščevanje in Tracy
Latte vam skuša razvoj čim bolj olajšati. Neposredno za namene razhroščevanja obstaja trojica značk {dump}
, {debugbreak}
in {trace}
.
Največje udobje dobite, če si še namestite odlično orodje za razhroščevanje Tracy in aktivirate dodatek za Latte:
// vklopi Tracy
Tracy\Debugger::enable();
$latte = new Latte\Engine;
// aktivira razširitev za Tracy
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
Zdaj se vam bodo vse napake prikazovale v preglednem rdečem zaslonu, vključno z napakami v predlogah s poudarkom vrstice in stolpca (video). Hkrati se v desnem spodnjem kotu v t.i. Tracy Baru pojavi zavihek za Latte, kjer so pregledno vidne vse izrisane predloge in njihove medsebojne povezave (vključno z možnostjo klikanja v predlogo ali prevedeno kodo) ter tudi spremenljivke:

Ker Latte prevaja predloge v pregledno PHP kodo, jih lahko udobno korakate v svojem IDE.
Linter: validacija sintakse predlog
Pregledati vse predloge in preveriti, ali ne vsebujejo sintaktičnih napak, vam pomaga orodje Linter. Zažene se iz konzole:
vendor/bin/latte-lint <pot>
S parametrom --strict
aktivirate strogi način.
Če uporabljate lastne značke, si ustvarite tudi lastno različico Linterja, npr. custom-latte-lint
:
#!/usr/bin/env php
<?php
// navedite dejansko pot do datoteke autoload.php
require __DIR__ . '/vendor/autoload.php';
$path = $argv[1] ?? '.';
$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
// tukaj dodajte posamezne svoje razširitve
$latte->addExtension(/* ... */);
$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);
Alternativno lahko lasten objekt Latte\Engine
predate v Linter:
$latte = new Latte\Engine;
// tukaj konfiguriramo objekt $latte
$linter = new Latte\Tools\Linter(engine: $latte);
Nalaganje predlog iz niza
Potrebujete nalagati predloge iz nizov namesto datotek, na primer za namene testiranja? Pomagal vam bo StringLoader:
$latte->setLoader(new Latte\Loaders\StringLoader([
'main.file' => '{include other.file}',
'other.file' => '{if true} {$var} {/if}',
]));
$latte->render('main.file', $params);
Obravnavalnik izjem
Lahko si definirate lasten obravnavalni handler za pričakovane izjeme. Predale se mu bodo izjeme, nastale znotraj {try}
in v peskovniku.
$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
$logger->log($e);
};
$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);
Samodejno iskanje postavitve
S pomočjo značke {layout}
predloga določa svojo starševsko predlogo. Mogoče je tudi pustiti samodejno iskanje postavitve, kar poenostavi pisanje predlog,
saj v njih ne bo treba navajati značke {layout}
.
To dosežemo na naslednji način:
$finder = function (Latte\Runtime\Template $template) {
if (!$template->getReferenceType()) {
// vrača pot do datoteke s postavitvijo
return 'automatic.layout.latte';
}
};
$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);
Če predloga ne sme imeti postavitve, to sporoči z značko {layout none}
.