Latte 3.1: Když šablonovací systém skutečně rozumí HTML

před 2 hodinami od David Grudl  

Latte dlouhodobě drží pozici nejbezpečnějšího šablonovacího systému pro PHP. Není to jen marketingová fráze – je to důsledek toho, že Latte (na rozdíl od Twigu či Blade) chápe kontext. Nerozlišuje jen „HTML“ a „PHP kód“. Vidí tagy, vidí atributy, vidí hodnoty. A ve verzi 3.1 jsme toto porozumění posunuli na úroveň, která radikálně zlepší vaše DX.

Zatímco verze 3.0 přinesla kompletně nový kompilátor a parser, verze 3.1 se soustředí na sémantiku a čistotu kódu. Přichází s konceptem Smart HTML Attributes, který eliminuje desítky řádků zbytečných podmínek a helperů.

Pojďme se podívat na to, co Latte 3.1 dělá pod kapotou a proč to budete chtít používat.

Nativní mapping PHP typů na HTML atributy

Doposud byla šablona pasivním generátorem stringů. Pokud jste do <span title="{$title}"> poslali null, dostali jste prázdný řetězec title="". Pokud jste poslali pole, dostali jste title="Array". Latte 3.1 mění pravidla hry a zavádí striktní logiku vykreslování podle typu dat.

Null znamená „atribut neexistuje“

V DOMu je rozdíl mezi <div title=""> (prázdný titulek) a <div> (žádný titulek). Latte 3.1 tento rozdíl respektuje.

  • Chování: Hodnota null v jakémkoli HTML atributu způsobí jeho kompletní odstranění z výstupu.
  • Dopad: Konec n:attr nebo podmínek {if} uvnitř tagů. Prostě jen posíláte data.

Boolean atributy bez magie

Atributy jako disabled, checked nebo required jsou binární. Buď tam jsou, nebo ne. Latte nyní akceptuje výraz přímo v hodnotě atributu.

  • Chování: Truthy výraz ⇒ atribut se vykreslí. Falsey výraz ⇒ atribut zmizí.
  • Výhoda: n:attr je skvělý nástroj, ale pro tento běžný use-case byl „overkill“. Nyní je syntaxe čistá a deklarativní:
<input disabled={$isDisabled}>

Arrays v class a style

Atributy, které očekávají seznam hodnot (class, rel, sandbox…), nyní nativně přijímají pole. Latte se postará o inteligentní vykreslení.

<div class={[
    btn,
    btn-primary => $isPrimary, // přidá se jen pokud true
]}></div>

<div style={[
	background => lightblue,
	display => $isVisible ? block : null,
	font-size => '16px',
]}></div>

Automatická JSON serializace

Do atributů data-* můžete poslat pole nebo objekt (stdClass). Latte detekuje kontext a automaticky provede json_encode.

WAI-ARIA compliance bez námahy

Přístupnost je důležitá, ale specifikace WAI-ARIA má svá specifika. Na rozdíl od standardních HTML boolean atributů, kde rozhoduje pouhá přítomnost atributu, ARIA vyžaduje explicitní textové hodnoty "true" a "false".

Latte 3.1 tento problém řeší za vás. Detekuje prefix aria- a automaticky zajistí správnou stringifikaci.

<button aria-expanded={$isExpanded} aria-hidden={=false}>
{* <button aria-expanded="true" aria-hidden="false"> *}

Výhoda: Už žádné ruční psaní ternárních operátorů typu {$val ? 'true' : 'false'}. Latte garantuje validní výstup.

Type safety v šablonách

Latte 3.1 je přísnější. A to je dobře. Běžné šablonovací systémy vám dovolí vypsat pole do href, což vygeneruje nefunkční odkaz <a href="Array">.

Latte 3.1 zavádí Runtime Type Checking pro atributy.

  • Snažíte se vypsat boolean do href? Warning.
  • Snažíte se vypsat objekt bez __toString do title? Warning.

Díky tomu odhalíte chyby v logice prezentace okamžitě při vývoji, nikoliv až když si uživatel stěžuje na rozbité UI. Navíc, varování obsahuje přesnou řádku a sloupec v šabloně.

Strict Types by Default

Jdeme s dobou. PHP ekosystém dospěl k strict_types=1 a Latte nezůstává pozadu. Všechny šablony v Latte 3.1 jsou defaultně kompilovány s touto direktivou. To zajišťuje konzistentní chování s vaším backendovým kódem a zabraňuje nechtěnému přetypování v kritické logice šablon.

Nullsafe filtry: Svatý grál pro Strict Types

Možná si říkáte, jak spolu souvisí filtry, striktní typy a HTML atributy. V Latte 3.1 velmi úzce.

Představte si situaci, že chcete vypsat titulek velkými písmeny, ale proměnná může být null.

<div title={$title|upper}>

Pokud je $title === null, narazíte na dva problémy:

  1. Strict types: Pokud filtr upper očekává string, ale dostal null, došlo by dříve k tiché konverzi na prázdný řetězec, ale s aktivním strict types padne TypeError.
  2. Ztráta „Smart“ chování: I když filtr akceptuje null, vrátí prázdný řetězec "", pro Latte to už není null. Výsledkem je <div title="">. Atribut nezmizí, jen je prázdný.

Řešením je nový Nullsafe filtr operátor ?|.

Funguje přesně jako ?-> v PHP. Pokud je hodnota na vstupu null, filtr se vůbec nezavolá (ani následující filtry) a výraz vrátí null.

<div title={$title?|upper}>

Výsledek? Žádný TypeError, protože filtr se na null nevolá. A Smart Attribute zafunguje a title z HTML úplně zmizí.

Syntaktický cukr pro čistší kód

Vyslyšeli jsme volání komunity a doplnili chybějící střípky syntaxe:

  • n:elseif: Chybějící článek v řetězení podmínek pomocí n:atributů je konečně zde.
  • n:attributes: Alternativní syntax <div n:if={$cond}>, díky které můžete uvnitř {...} volně používat jednoduché i dvojité uvozovky

Jak bezpečně upgradovat?

Změna chování null a boolean atributů je BC break, ale mysleli jsme na to. Latte 3.1 obsahuje Migrační režim.

  • Zavoláte $latte->setMigrationWarnings().
  • Proklikáte aplikaci. Latte vám do Tracy/logu vypíše přesně ta místa, kde se výstup liší od verze 3.0.
  • Pomocí dočasného filtru |accept potvrdíte, že nové chování (např. zmizení prázdného atributu) je žádané, nebo kód upravíte.

Latte 3.1 není jen „další verze“. Je to posun k modernímu, typově bezpečnému a sémantickému generování HTML. Vyzkoušejte ho a uvidíte, o kolik čistší vaše šablony mohou být.

👉 Kompletní migrační příručka a dokumentace

David Grudl Vyvíjí webové aplikace již od roku 1999 a specializuje se na umělou inteligenci. Je autorem Nette Framework a knihoven jako Texy!, Tracy či Latte. Moderuje pořad Tech Guys a píše na Uměligence o AI novinkách. Jeho blog La Trine byl nominován na cenu Magnesia Litera. Věnuje se vzdělávání v oblasti AI a je pragmatický optimista.