Prakse za razvijalce

Namestitev

Najboljši način za namestitev Latteja je uporaba Composerja:

composer require latte/latte

Podprte različice PHP (velja za najnovejše različice popravkov Latte):

različica združljiva s PHP
Latte 3.0 PHP 8.0 – 8.2

Kako izrisati predlogo

Kako izrisati predlogo? Uporabite to preprosto kodo:

$latte = new Latte\Engine;
// imenik predpomnilnika
$latte->setTempDirectory('/path/to/tempdir');

$params = [ /* template variables */ ];
// ali $params = new TemplateParameters(/* ... */);

// izrisovanje v izpis
$latte->render('template.latte', $params);
// ali izriši v spremenljivko
$output = $latte->renderToString('template.latte', $params);

Parametri so lahko polja ali še bolje predmeti, kar bo omogočilo preverjanje tipa in predlaganje v urejevalniku.

Primere uporabe lahko najdete tudi v skladišču Latte examples.

Zmogljivost in predpomnilnik

Predloge Latte so izjemno hitre, saj jih Latte sestavi neposredno v kodo PHP in jih predpomni na disku. Tako nimajo dodatnih režijskih stroškov v primerjavi s predlogami, napisanimi v čistem jeziku PHP.

Predpomnilnik se samodejno obnovi vsakič, ko spremenite izvorno datoteko. Tako lahko med razvojem priročno urejate predloge Latte in spremembe takoj vidite v brskalniku. V produkcijskem okolju lahko to funkcijo onemogočite in prihranite nekaj zmogljivosti:

$latte->setAutoRefresh(false);

Ko se namestite v produkcijski strežnik, lahko začetno ustvarjanje predpomnilnika, zlasti pri večjih aplikacijah, razumljivo traja nekaj časa. Latte ima vgrajeno preprečevanje stampede predpomnilnika. To je situacija, ko strežnik prejme veliko število hkratnih zahtevkov in ker predpomnilnik Latte še ne obstaja, bi ga vsi ustvarili hkrati. Zaradi tega se poveča število procesorjev. Latte je pameten in kadar je več hkratnih zahtevkov, samo prva nit ustvari predpomnilnik, druge počakajo in ga nato uporabijo.

Parametri kot razred

Bolje kot posredovati spremenljivke predlogi kot polja je ustvariti razred. Pridobite tipsko varen zapis, lepo sugestijo v IDE ter način 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,
));

Onemogočanje samodejnega pobega spremenljivke

Če spremenljivka vsebuje niz HTML, jo lahko označite tako, da je Latte ne bo samodejno (in s tem dvakratno) izločil. S tem se izognete potrebi po navedbi |noescape v predlogi.

Najlažji način je, da niz zapakirate v predmet Latte\Runtime\Html:

$params = [
	'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];

Latte prav tako ne pobegne vsem objektom, ki implementirajo vmesnik Latte\HtmlStringable. Tako lahko ustvarite svoj razred, katerega metoda __toString() bo vrnila kodo HTML, ki ne bo samodejno pobegnila:

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 pravilno kodo HTML in zagotoviti eskapiranje parametrov, sicer lahko pride do ranljivosti XSS!

Kako razširiti Latte s filtri, oznakami itd.

Kako v Latte dodati filter, funkcijo, oznako itd. po meri? To izveste v poglavju Razširitev sistema Latte. Če želite svoje spremembe ponovno uporabiti v različnih projektih ali če jih želite deliti z drugimi, morate nato ustvariti razširitev.

Katera koli koda v predlogi {php ...}

Znotraj okenca lahko zapišete samo izraze PHP {do} značko, zato ne morete na primer vstaviti konstrukcij, kot so if ... else ali izjave, zaključene s podpičjem.

Lahko pa registrirate razširitev RawPhpExtension, ki doda oznako {php ...}. Z njo lahko vstavite katero koli kodo PHP. Zanjo ne veljajo nobena pravila za način peskovnika, zato je za uporabo odgovoren avtor predloge.

$latte->addExtension(new Latte\Essential\RawPhpExtension);

Preverjanje generirane kode

Latte pripravi predloge v kodo PHP. Seveda poskrbi, da je generirana koda sintaktično pravilna. Vendar pri uporabi razširitev tretjih oseb ali RawPhpExtension Latte ne more zagotoviti pravilnosti generirane datoteke. Prav tako lahko v PHP napišete kodo, ki je sintaktično pravilna, vendar je prepovedana (na primer dodelitev vrednosti spremenljivki $this) in povzroči napako pri sestavljanju PHP. Če takšno operacijo zapišete v predlogi, bo vključena tudi v ustvarjeno kodo PHP. Ker je v PHP več kot dvesto različnih prepovedanih operacij, jih Latte ne poskuša zaznati. PHP jih bo sam označil ob izrisu, kar običajno ni težava.

Vendar pa obstajajo situacije, ko želite med sestavljanjem predloge vedeti, da ta ne vsebuje napak pri sestavljanju PHP. Zlasti kadar lahko predloge urejajo uporabniki ali kadar uporabljate peskovnik. V takem primeru preverite predloge med sestavljanjem. To funkcionalnost lahko aktivirate z metodo Engine::enablePhpLint(). Ker mora za preverjanje poklicati binarni strežnik PHP, mu kot parameter posredujte pot do njega:

$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');

try {
	$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
	// lovi napake Latte in tudi Compile Error v PHP
	echo 'Error: ' . $e->getMessage();
}

Strogi način

V strogem načinu razčlenjevanja Latte preverja manjkajoče zaključne oznake HTML in onemogoči uporabo spremenljivke $this. Če želite vklopiti to funkcijo:

$latte = new Latte\Engine;
$latte->setStrictParsing();

Če želite ustvariti predloge z glavo declare(strict_types=1), naredite naslednje:

$latte = new Latte\Engine;
$latte->setStrictTypes();

Prevajanje v predlogah

Uporabite razširitev TranslatorExtension za dodajanje {_...}, {translate} in filtrirajte translate v predlogo. Uporabljata se za prevajanje vrednosti ali delov predloge v druge jezike. Parameter je metoda (klic PHP), ki izvede prevod:

class MyTranslator
{
	public function __construct(private string $lang)
	{}

	public function translate(string $original): string
	{
		// ustvarite $translated iz $original 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 pokliče med izvajanjem, ko se predloga prikaže. Vendar lahko Latte vsa statična besedila prevede med sestavljanjem predloge. To prihrani zmogljivost, saj se vsak niz prevede samo enkrat, dobljeni prevod pa se zapiše v sestavljeno datoteko. Tako se v imeniku predpomnilnika ustvari več sestavljenih različic predloge, po ena za vsak jezik. Za to morate kot drugi parameter navesti le jezik:

$extension = new Latte\Essential\TranslatorExtension(
	$translator->translate(...),
	$lang,
);

S statičnim besedilom mislimo na primer na {_'hello'} ali {translate}hello{/translate}. Nestatično besedilo, kot je {_$foo}, se bo med izvajanjem še naprej prevajalo.

Predloga lahko prevajalniku prek {_$original, foo: bar} ali {translate foo: bar} posreduje tudi dodatne parametre, ki jih ta prejme kot polje $params:

public function translate(string $original, ...$params): string
{
	// $params['foo'] === 'bar'
}

Razhroščevanje in Tracy

Latte se trudi, da bi bil razvoj čim bolj prijeten. Za namene razhroščevanja so na voljo tri oznake {dump}, {debugbreak} in {trace}.

Največ udobja boste imeli, če namestite odlično orodje za razhroščevanje Tracy in aktivirate vtičnik Latte:

// omogoča Tracy
Tracy\Debugger::enable();

$latte = new Latte\Engine;
// aktivira Tracyjev podaljšek.
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);

Vse napake bodo zdaj vidne v preglednem rdečem zaslonu, vključno z napakami v predlogah s poudarjenimi vrsticami in stolpci (videoposnetek). Hkrati se v spodnjem desnem kotu v tako imenovani Tracyjevi vrstici prikaže zavihek za Latte, kjer lahko jasno vidite vse izrisane predloge in njihova razmerja (vključno z možnostjo klika v predlogo ali sestavljeno kodo) ter spremenljivke:

Ker Latte predloge sestavi v berljivo kodo PHP, jih lahko priročno pregledujete v svojem IDE.

Linter: Preverjanje sintakse predloge: Linter: preverjanje sintakse predloge

Orodje Linter vam bo pomagalo pregledati vse predloge in preveriti napake v sintaksi. Začne se iz konzole:

vendor/bin/latte-lint <path>

S parametrom --strict lahko aktivirate strogi način.

Če uporabljate oznake po meri, ustvarite tudi svoj prilagojeni Linter, npr. custom-latte-lint:

#!/usr/bin/env php
<?php

// vnesite dejansko pot do datoteke autoload.php
require __DIR__ . '/vendor/autoload.php';

$path = $argv[1] ?? '.';

$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
// tukaj dodajte svoje posamezne razširitve
$latte->addExtension(/* ... */);

$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);

Druga možnost je, da programu Linter posredujete svoj predmet Latte\Engine:

$latte = new Latte\Engine;
// tukaj konfiguriramo predmet $latte
$linter = new Latte\Tools\Linter(engine: $latte);

Nalaganje predlog iz niza

Potrebujete naložiti predloge iz nizov namesto iz datotek, morda za namene testiranja? StringLoader vam bo pomagal:

$latte->setLoader(new Latte\Loaders\StringLoader([
	'main.file' => '{include other.file}',
	'other.file' => '{if true} {$var} {/if}',
]));

$latte->render('main.file', $params);

Obvladovalec izjem

Za pričakovane izjeme lahko določite svoj lasten izvajalec. Izjeme, ki se pojavijo znotraj {try} in v peskovniku, se mu posredujejo.

$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
	$logger->log($e);
};

$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);

Samodejno iskanje postavitve

Uporaba oznake {layout} predloga določi svojo nadrejeno predlogo. Možno je tudi, da se postavitev išče samodejno, kar bo poenostavilo pisanje predlog, saj jim ne bo treba vključevati oznake {layout}.

To dosežemo na naslednji način:

$finder = function (Latte\Runtime\Template $template) {
	if (!$template->getReferenceType()) {
		// vrne pot do nadrejene datoteke predloge
		return 'automatic.layout.latte';
	}
};

$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);

Če predloga ne sme imeti postavitve, bo to označeno z oznako {layout none}.

različica: 3.0