Latte 3: impozantní skok vpřed

před 2 lety od David Grudl  

Znějí fanfáry a na scénu přichází Latte 3. S kompletně přepsaným kompilátorem. Nová verze představuje největší vývojový skok, jaký kdy v Latte nastal.

Proč vlastně Latte?

Latte má vtipnou historii. Původně totiž nebylo myšleno vážně. Mělo demonstrovat, že žádný šablonovací systém není v PHP potřeba. Zvrat přišel až s nápadem, že by šablonovací systém mohl HTML stránku chápat. Abyste rozuměli, pro ostatní šablonovací systémy je text v okolí značek {{...}} jen šumem bez jakéhokoliv významu. Je jedno, jestli jde o HTML stránku, CSS styl nebo třeba text v Markdownu, šablonovací engine vidí jen shluk znaků. Latte naopak dokument chápe. Což přináší spoustu zásadních výhod. Od komfortu v podobě vychytávek jako jsou třeba n:attributy, až po ultimátní bezpečnost.

Latte tak ví, jakou použít escapovací funkci (což většina programátorů neví, ale díky Latte to nevadí a nevytvoří bezpečnostní díru Cross-site scripting). Zabrání vypsání řetězce, který by v určitém místě byl nebezpečný. Dokonce dokáže předejít dezinterpretaci mustache závorek frontendovým frameworkem. …A bezpečnostní experti nebudou mít co žrát 🙂

Nečekal bych, že tímto nápadem přeběhne Latte ostatní systémy nejméně o 10 let, protože dodnes takto funguje pouze Latte a Soy od Google. Latte a Soy jsou jediné opravdu bezpečné šablonovací systémy pro web. (Byť teda Soy ze zmíněných vychytávek má pouze to escapování.)

Druhou klíčovou vlastností Latte je, že pro výrazy uvnitř značek používá jazyk PHP. Tedy syntaxi programátorovi důvěrně známou. Vývojář se tak nemusí učit další nový jazyk. Nemusí pátrat, jak se to či ono v Latte píše. Prostě to napíše tak, jak už dávno zná. Naopak třeba populární šablonovací systém Twig používá syntaxi Pythonu, kde se i zcela základní konstrukce píší odlišně. Například foreach ($people as $person) se v Pythonu (a tedy i Twigu) píše jako for person in people, což zcela zbytečně nutí mozek přepínat mezi dvěma opačnými konvencemi.

Latte svými vlastnostmi válcuje konkurenci. A proto si zasloužilo nový kompilátor.

Původní kompilátor

Latte a jeho syntax vznikla před 14 lety (rok 2008), do nynějška používaný kompilátor o tři roky později. Uměl už tehdy vše podstatné, co se dodnes používá, tedy i bloky, dědičnost, snippety atd.

Kompilátor fungoval jako jednoprůchodový, což znamená, že parsoval šablonu a rovnou ji přetvářel do výsledného PHP kódu, který se pak uložil do cache. Jazyk PHP používaný ve značkách se tokenizoval a poté procházel několika procesy, které stream tokenů upravovaly. Například přidávaly syntaktické vychytávky, které PHP tehdy neznalo nebo které nezná doposud a jsou specifické pro Latte (zkrácený ternární operátor, filtry ($var|upper|truncate), atd).

Za jedenáct let vývoje Latte se našly situace, kdy jednoprůchodový kompilátor nedostačoval. Ideální by bylo přejít na dvoukrokovou kompilaci, tedy nejprve šablonu naparsovat do mezipodoby, do AST stromu, a pak teprve z něj vygenerovat kód třídy.

Taktéž s postupným vylepšováním PHP-like jazyka používaného ve značkách přestávala dostačovat reprezentace v tokenech a ideální by bylo i jej naparsovat do AST stromu. Například Sandbox postavený nad AST stromem může lépe garantovat, že bude skutečně neprůstřelný.

Nový kompilátor je raketová věda 🙂

Trvalo mi pět let se do přepsání kompilátoru pustit, protože jsem věděl, že to bude extrémně náročné. Už samotná tokenizace šablony představuje výzvu, neboť musí běžet paralelně s parsováním. Parser totiž musí mít možnost ovlivňovat tokenizaci, když například narazí na atribut n:syntax=off.

Podporu pro paralelní běh dvou kódů přináší až Fibers v PHP 8.1, nicméně Latte je zatím nevyužívá, aby mohlo fungovat na PHP 8.0. Místo toho používá obdobné coroutines (v dokumentaci PHP o nich nic nenajdete, tak alespoň odkaz na úžasnou prezentaci). Pod kapotou Latte se tedy odehrávají kouzla.

Jako ještě mnohem náročnější úkol mi připadalo napsat lexer a parser pro tak komplexní jazyk, jako je dialekt PHP používaný ve značkách. V podstatě to znamenalo vytvořit něco jako nikic/PHP-Parser pro Latte. A zároveň i nutnost formalizovat gramatiku tohoto jazyka.

Po několika měsících usilovné práce se podařilo! Nový kompilátor považuji za splněný sen. Latte tak vstupuje do nové éry.


Podívejte se, jak migrovat na Latte 3