Latte 3: největší vývojový skok v dějinách Nette

David Grudl
Nette Core | 8082
+
+29
-

Prosím fanfáry, 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 Nette nastal.

Proč vlastně Latte

Latte má překvapivou historii. Původně totiž nebylo myšleno vážně. Mělo dokonce demonstrovat, že žádný šablonovací systém není v PHP potřeba. Bylo pevně spjato s presentery v Nette, kde však nebylo defaultně zapnuté a programátor jej musel aktivovat přes tehdejší ošklivý název CurlyBracketsFilter.

…pokračování na blogu

David Grudl
Nette Core | 8082
+
+17
-

Kompatibilita a Latte 2.11

Nové Latte má formálně přesně definovanou gramatiku, která by měla co nejvíce odpovídat tomu, co jsme si zvykli psát v Latte 2. Nový kompilátor by tak měl fungovat stejně jako předchozí, až na určité konstrukce, kde to buď není možné, nebo by to bylo extrémně komplikované. Proto vyšla přechodová verze Latte 2.11.

Tato verze není klasická 2.x verze Latte, ale slouží jako přechodová na Latte 3. Nepřináší nic nového, jen pomocí E_USER_DEPRECATED upozorňuje na vše, co v novém Latte nebude fungovat.

Změny v syntaxi (aktualizováno)

  • Ve filtrech se jako oddělovač parametrů používá čárka, dříve |filtr: arg : arg a nyní |filtr: arg, arg
  • Zrušení automatického rozlišování párového a nepárového {label foo} vs. {label foo}...{/label} (nepárové je potřeba psát {label /})
  • A také párový vs nepárový {_$var} vs {_}...{/}, druhou variantu nahrazuje nové {translate}...{/translate}
  • Chybějící dvojité uvozovky u výrazů jako {block foo-$var} je potřeba psát jako {block foo-{$var}} nebo {block "foo-$var"}
  • Značku {includeblock file.latte} nahrazuje {include file.latte with blocks}
  • Atributy n:inner-xxx, n:tag-xxx a n:ifcontent nelze použít u nepárových HTML elementů
  • Atribut n:inner-snippet musí být psán bez inner-
  • {include "abc"} by mělo být psáno jako {include file "abc"}, pokud „abc“ neobsahuje tečku a není tak jasné, že jde o soubor
  • |noescape musí být uveden jako poslední filtr
  • Je třeba dodržet velikost písmenek u filtrů (v Latte 3 bude case sensitive)
  • odstranění magické proměnné $iterations (nejde o $iterator!)
  • zrušení Engine::addFilter(null, …) ve prospěch addFilterLoader()
  • musí být ukončené značky </script> a </style>

Většina bodů jsou krajní případy, na které v šablonách nenarazíte. Ale na ty první asi jo. Pokusím se k tomu dát vysvětlení.

  • Dvojtečka jako oddělovač argumentů se stala problematická, protože koliduje s ternárním operátorem a není jasné, jestli |filter: $a ? $b : c znamená |filter: ($a ? $b) , $c nebo |filter: ($a ? $b : $c). A do toho ještě navíc přišly pojmenované argumenty |filter: arg: $val. Takže je už nějakou dobu deprecated, jen teď na to Latte upozorní notickou.
  • Automatické rozlišování párového a nepárového dělá problém v pluginu pro PhpStorm. Cca polovina uživatelů používá {label} lako párovou a polovina jako nepárovou značku. Nyní je nepárové použití potřeba zapsat jako {label .../}. Totéž se to týká i značky {_} pro překlad. Tady si myslím, že {_$var} je ideální pro nepárové použití, zatímco párové {_}text{/} vypadá blbě a nahrazuje ho {translate}text{/translate}.
  • ad {block foo-$var}: V Latte se běžně píšou řetězce bez uvozovek, například {include file.latte} atd. Přitom přísně vzato, tečka je operátor pro spojování a alfanumerické identifikátory se považují za řetězce, takže file.latte znamená 'file' . 'latte', tedy ve výsledku 'filelatte'. Latte 3 se snaží bezuvozovkové řetězce z velké míry podporovat, ale v některých případech, jako je právě foo-$var, už je bude chtít. Věřte, že to i přidá na srozumitelnosti, značka {block "foo-$var"} se čte líp.

Nebo lze doplnit složené závorky, tj. {block foo-{$var}} a pak uvozovky nejsou potřeba. Tohle se spíš využije v n:attributech, ve kterých se tedy místo `n:block="foo-$var" použije n:block="foo-{$var}".

Latte linter

Součástí Latte je i triviální lintovací nástroj, takže jestli jsou všechny šablony na disku OK by se mělo dat zjistit pomocí něj.

{php kod}

Dialekt PHP v Latte 3 podporuje pouze výrazy. To znamená, že uvnitř značky nemůžete napsat třeba konstrukce jako if…else apod. Ty ostatně ani nikdy nedávaly v žádné značce smysl, s výjimkou značky {php} resp. {do}.

V Latte 3 můžete v těchto značkách psát výrazy (i šílené, jako {do $a += match ($var) { 10 => $y } }), ale ne statementy ukončené středníkem.

Můžete však snadno aktivovat rozšíření RawPHPExtension, které umožní ve značce {php} psát úplně cokoliv na zodpovědnost autora šablony.

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

Rozšíření pro Latte

S kompletním přepsáním parseru se zcela změnil i způsob psaní vlastních maker. Pokud máte pro Latte vytvořené vlastní značky, bude třeba je napsat znovu pro verzi 3. V tuto chvíli je nejlepším návodem se prostě podívat, jak jsou napsané výchozí značky.

Rozšíření pro Latte je standardně součástí balíčků nette/application, nette/caching a nette/forms. Ve všech jsem už přidal podporu pro Latte 3. Nachází se jak v masteru, tak i v 3.1-dev větvích. Nic by vám tedy nemělo bránit testování

Btw, značky pro překlad a snippety už nejsou přímo součástí Latte, ale jejich rozšíření v nette/application.

Testování

Ano, přichází na řadu testování. Třeba tento web na Latte 3 v pohodě běží. Ale je potřeba zjistit, co všechno neběží, aby se to mohlo vyřešit.

Pro testování stačí, když si nainstalujete Latte 3.0-dev a výše uvedené balíčky v 3.1-dev verzích (a máte PHP 8). A pokud si partu doplníte o Tracy 2.9.2, zjistíte, že umí zobrazovat nejen řádek kde je chyba v šabloně, ale nově i sloupec.

Můžete také nainstalovat v2.11 a ověřit, jestli vaše šablony jsou ready na trojku.

filbar
Člen | 13
+
0
-

Teď se dívám na https://github.com/…rmMacros.php a vidím tu starou syntax – bude teda možné používat i původní kód?

jiri.pudil
Nette Blogger | 1028
+
0
-

filbar napsal(a):

Teď se dívám na https://github.com/…rmMacros.php a vidím tu starou syntax – bude teda možné používat i původní kód?

Spíš bych si tipnul, že další nette balíčky budou minimálně nějakou dobu kompatibilní s oběma major verzemi Latte

filbar
Člen | 13
+
0
-

Když to zkoumám, tak to vypadá moc pěkně. Dívám se pro úvod na tento příklad – https://github.com/…FormNode.php a jestli to chápu dobře, tak create se volá jako úvod na začátku, print obsahuje ve volání return $context->format řetězec a další parametry cca jako ve sprintf? To co je pro mně ale záhadou je jaké parametry má obsahovat getIterator?

David Grudl
Nette Core | 8082
+
+12
-

Zkusím stručně popsat jak fungují rozšíření, jen upozorňuju, že jsme ve fázi beta a může docházet k nějakým změnám.

https://latte.nette.org/…ng-extension#…

Pozn: chování je vlastně evolucí Latte v2. Hlavní rozdíl je doplnění mezikroku, kdy funkce parsující tag vrací objekt node a až ten vykresluje PHP kód v print(). A také v použití yield, které v době vzniku Latte 2 neexistovalo a díky kterému není potřeba parsující funkci rozdělovat na dvě, jednu pro otevírací značku a jednu pro uzavírací.

dakur
Člen | 493
+
+3
-

Wow, super! Těším se na nový zápis vlastních maker. 👍 Tedy extensions..

filbar
Člen | 13
+
0
-

Ještě mě napadnul jeden dotaz – věci jako {nl2br($value->custom_value)} v nové implementaci budou fungovat, nebo nee?

David Grudl
Nette Core | 8082
+
0
-

Ne, od toho je |breakLines

mkoula
Backer | 52
+
+1
-

Čte Latte Linter latte-lint konfiguraci projektu a umí rozpoznat vlastní makra? Nebo je nějaká možnost to do linteru dostat?

❯ vendor/bin/latte-lint

Latte linter
------------
Usage: latte-lint <path>

V rámci ClI není žádný help, ani konfigurace. Našlo mi to nějaké chyby, což je přínosné, ale zároveň to vyhodí chybu ala:
Unknown tag {stars} (on line 117)
a najít pak ty skutečné chyby od chybějících vlastních maker je v tom výstupu ne zrovna čitelné…

mkoula
Backer | 52
+
0
-

David Grudl napsal(a):

Ne, od toho je |breakLines

Píšeš o tom, že nová verze bude case sensitive a zde je breakLines. Tak jsem si vzpomněl, že zrovna včera jsem to používal a PHPStorm a jeho Latte plugin (asi pro @JanTvrdík) nabízí v rámci našeptávání jen breaklines. A fakt se mi to nechce zpětně ručně dopřepisovat :-)

Tak nevím jestli tohle bude problém s novou verzí nebo ne?

Martin Dřímal
Člen | 16
+
+2
-

mkoula napsal(a):
Tak nevím jestli tohle bude problém s novou verzí nebo ne?

V CoreExtension se registrujou obě varianty – https://github.com/…xtension.php#L103

David Grudl
Nette Core | 8082
+
+3
-

Čte Latte Linter latte-lint konfiguraci projektu a umí rozpoznat vlastní makra? Nebo je nějaká možnost to do linteru dostat?

V tuto chvíli jenom tak, že si instalaci rozšíření do kódu sám doplníš sem https://github.com/…n/latte-lint#…

Píšeš o tom, že nová verze bude case sensitive a zde je breakLines…

Mělo by fungovat obojí, stejně jako stripHtml a striphtml a nějaké další.

David Grudl
Nette Core | 8082
+
0
-

K té značce {label /} bych rád udělal ještě průzkum, jak často se používá jako párová a nepárová. Měl by to spočítat tento skript https://gist.github.com/…de700d0b721f. Zkuste tím prosím projít své šablony.

Můžete zahlasovat i tady https://twitter.com/…415332519945

Pokud by se ukázalo, že většinové použití je jako nepárová, tak bych našel pro Latte 3 řešení, aby se nemuselo psát {label /}, a naopak bych vytvořil novou značku pro párový label.

mskocik
Člen | 52
+
+3
-

David Grudl napsal(a):
Pokud by se ukázalo, že většinové použití je jako nepárová, tak bych našel pro Latte 3 řešení, aby se nemuselo psát {label /}, a naopak bych vytvořil novou značku pro párový label.

Parovy label som pouzil asi v jednom forme kedysi davno a ani som sa s tym nestretol na inych projektoch. Na druhu stranu upravit {label} na {label /} bola rychlovka pomocou regex search & replace vo VS code.

Martin Dřímal
Člen | 16
+
+1
-

Ty jo, celkem mě v anketě na twitteru překvapuje rozsáhlé používání nepárové varianty.. :) Nemám jediné nepárové použití, mám zažitý klasický label jako povinně párový tag a dodnes mě ani nenapadlo zkoušet to nepárově :D Mám pak třeba i css selectory navěšené na nějaký input uvnitř konkrétního labelu, atd..

Marek Bartoš
Nette Blogger | 1146
+
0
-

@DavidGrudl Když už děláš ty velké změny, bylo by možné řešit i tenhle edge-case?

Před názvem bloku je občas třeba zapsat hashtag. Bude ještě třeba nebo je čas označit ho za deprecated? Bez předešlé znalosti bych čekal, že se dvojité uvozovky budou chovat jako string interpolation v php.

{ifset #"col-{$column->name}"}
	{include #"col-{$column->name}", row: $row, cell: $cell, iterator: $iterator}

Editoval Marek Bartoš (7. 4. 2022 16:10)

David Grudl
Nette Core | 8082
+
+1
-

Použij {ifset block ...} a {include block ...}

Dvojité uvozovky se chovají jako string interpolation v php.

filbar
Člen | 13
+
0
-

Ještě jsem narazil, že mi přestalo fungovat

<option value="{plink this,(expand)$presenter->getParameters()}" {if $presenter->getParameter('ordering')==''}selected="selected"{/if}>{_ "GLOBAL_DEFAULT"}</option>

Dostávám hlášku – Cannot unpack array with string keys

Siki
Člen | 9
+
+1
-

Používám Latte 2.11.1

Mám následující zápis (funkční ve starších verzích Latte):

<div n:snippet="row-{$row->id}">

Nyní dostávám Deprecated hlášku: The expression ‚row-{$row->id}‘ should be put in double quotes.

Když jsem přidal uvozovky, tak vyskakuje Warning (Use of undefined constant ‚row‘ (this will throw an Error in a future version of PHP)):

<div n:snippet='row-"{$row->id}"'>

Jaké je řešení?

David Grudl
Nette Core | 8082
+
0
-
<div n:snippet='"row-{$row->id}"'>
Polki
Člen | 553
+
+9
-

David Grudl napsal(a):

<div n:snippet='"row-{$row->id}"'>

ugly

Kamil Valenta
Člen | 752
+
+4
-

A co je vlastně na výrazu

<div n:snippet="row-{$row->id}">

špatně? Vůbec by mě nenapadlo tam ještě něco přidávat, když latte vychovává člověka, aby makra ničím dalším neobaloval.
Pak také nevím, zda jsem sám, komu hláška připadá zavádějící, protože já už v prvním zápisu dvojité uvozovky vidím.
Výsledná konstrukce by mne nenapadla a ani když už ji vidím, si ji nedokážu nijak zdůvodnit…

Pavel Janda
Člen | 977
+
0
-

Souhlasím s oběma komentáři výše.

Latte oplývá (dneska by se řeklo umělou) inteligencí pro rozpoznání kontextu – což je skvělý! Ale – takto to působí, že pro jistotu musím obalit vypisovaný řetězec několika typy uvozovek, aby to bylo jó-safe..

Pokud se to týká pouze maker snippet, tak to jde asi překousnout, ale nevypadá to zkrátka moc inteligentně.

Editoval Pavel Janda (11. 4. 2022 12:28)

Jan Tvrdík
Nette guru | 2595
+
+3
-

Alternativě by mi přišlo intuitivní i

<div n:snippet={"row-$row->id"}>

resp.

<div n:snippet={"row-{$row->id}"}>
David Grudl
Nette Core | 8082
+
+8
-

Hele mně se to taky nelíbí, takže to mi psát nemusíte, smysl má zkusit navrhnout konstruktivní řešení.

A co je vlastně na výrazu <div n:snippet="row-{$row->id}"> špatně? Odpověď je tady. Naopak korektní varianty jsou tyto.

Latte 2 se tak ňák dokázalo vypořádat s různými zápisy. Jenže dnes už není otázkou jen jedné knihovny – každou výjimkou komplikuju život třeba @mesour, který programuje plugin. Zároveň sandbox režim mění pravidla hry, protože nejisté chování může vést k chybám, které jsou najednou považovány za bezpečnostní. Takže se snažím jazyk co nejvíc zbavit výjimek a formalizovat. Stejně jako v PHP nemůžete jen tak vynechat dvojité uvozovky a doufat, že to kompilátor nějak zvládne, nejde to ani ve formálně přísném Latte 3.

Tedy je potřeba určit jasná pravidla. Například zda má chápat 123-$a jako 123 - $a nebo jako "123-$a"? A co třeba M_PI-$a, je to M_PI - $a nebo "M_PI-$a"? A co $a-123? Nebo foo.$b, nebo foo.{$b}, atd… Dřívější pravidlo „chápej vše do první mezery nebo čárky jako string“ má taky svá úskalí.

Ty pravidla je stále prostor upravit. Technicky jde o funkci parseUnquotedString(), můžete si s ní klidně pohrát.

Osobně se víc kloním k tomu co nejvíce eliminovat magii. Jak jsem psal, {block "foo-$var"} se mi jeví srozumitelnější než {block foo-$var}, protože chování interpolation v PHP řetězcích znám a vím, co si v nich můžu dovolit, zatímco bez těch uvozovek je to tricky. Bohužel ale v n:atributech to vede k nehezkému zdvojení uvozovek. Jenže zároveň to musí fungovat stejně, ať už je značka zapsaná jako {...} nebo n:xxx="...", protože jinak by šlo o výjimku dosti kolosální. …nebo ne? ;-)

Pavel Janda
Člen | 977
+
+1
-

@DavidGrudl Zkusíme se nad tím zamyslet. To víš, dal jsi nám automatickou převodovku a teď chceš, abychom řadili ručně. :D

David Grudl
Nette Core | 8082
+
+4
-

Zkusím udělat tuhle úpravu: jelikož v PHP nelze uvnitř výrazů používat složené závorky { }, tak vlastně zápisy jako xxx-{$x}, {$x}.xxx apod jsou vždy nevalidní (teda krom $foo->{$bar}) . Tedy by je šlo bezpečně považovat za výrazy, které mají být chápány jako unquoted strings, tedy řetězce.

Dál by tedy platilo, že:

  • foo-$var MUSÍ být v uvozovkách jako "foo-$var" (btw $var-foo muselo být v uvozovkách vždy)
  • foo-{$var} nebo {$var}-foo NEMUSÍ být v uvozovkách

Krom písmen a číslic by unquoted strings mohly obsahovat znaky _ - . / @ ~.

Marek Bartoš
Nette Blogger | 1146
+
0
-

Super nápad. Jediná výjimka kdy složené závorky ve výrazu použít lze je v php 7.4 deprecated a v 8.0 removed offset access https://3v4l.org/58Rh8

Kamil Valenta
Člen | 752
+
0
-

David Grudl napsal(a):

A co je vlastně na výrazu <div n:snippet="row-{$row->id}"> špatně? Odpověď je tady. Naopak korektní varianty jsou tyto.

Mně to jako odpověď nepřipadá. Pokud to row- začíná uvozovkami, tak je jasně řečeno, že to má být string. Proč by se mělo dál row- vyhodnocovat v PHP?
Pokud napíšu <input size=„50“ n:name=„name“>, taky to nezhučí na tom, že by se vyhodnocovalo

<?php
name;

Kdy se jedná o pomlčku a kdy o mínus mi zase řekne kontext těch složených závorek, podobně jako třeba v bashi.

n:snippet="row-{$id}" // => "row-1"
n:snippet="{10-$id}" //  => "9"
David Grudl
Nette Core | 8082
+
+1
-

Uvozovky nejsou součástí hodnoty atributu.

Kamil Valenta
Člen | 752
+
+1
-

Nejsou.

$id = 1;
$foo = 'bar';

n:snippet="row" // => {snippet row}
n:snippet="row-{$id}" // => {snippet row-1}
n:snippet="row-{10-$id}" // => {snippet row-9}
n:snippet="row-10-{$id}" // => {snippet row-10-1}
n:snippet="{$foo}" // => {snippet bar}

Připadá mi, že to pokrývá všechny ty nejasné případy, které jsi nastínil. A je to pokryto jediným pravidlem, nemusím si pamatovat žádné „nebo“, kdy se to má či nemá obalovat uvozovkama. A v neposlední řadě to vychází ze zažité syntaxe $obj->{$var};

Marek Bartoš
Nette Blogger | 1146
+
+1
-

@KamilValenta Však David psal, že nynější řešení mělo situace, kdy nebylo jasné, jak se kód interpretuje, a tak se vynutilo zdvojení, a tady pak napsal, že je to řešitelné i pomocí složených závorek, tak kde vidíš problém?

Kamil Valenta
Člen | 752
+
+1
-

@MarekBartoš já nevidím problém nikde.
Reagoval jsem na to, že ‚„row-{$id}“‘ není úplně šťastné, David vyzval k diskuzi „Hele mně se to taky nelíbí, takže to mi psát nemusíte, smysl má zkusit navrhnout konstruktivní řešení.“
Ano, sám zmiňuje složené závorky, ale navrhuje řešení, které nestojí na jednotném pravidle, což podle mě snižuje použitelnost.

Moc nechápu, co jsi chtěl svým příspěvkem sdělit.

David Grudl
Nette Core | 8082
+
0
-

@KamilValenta to, co se píše do {...} a n:attr="...", je PHP kód. S určitými, ale pevně danými odlišnostmi, jako třeba že lze vynechávat uvozovky kolem „alfanumerickýchpomlčkových“ identifikátorů, používat zkrácený ternární operátor atd.

Ptáš se, co je špatně na <div n:snippet="row-{$row->id}">. Špatně je to, že row-{$row->id} není jednak validní výraz, ani výraz, který chceš zapsat. S uplatněním zmíněných pravidel jde o matematickou operaci 'row' - {$row->id}, ale ty chceš napsat řetězec "row-{$row->id}". Latte tyhle speciální případy, kdy chybí dvojité uvozovky, chápe, ale jsou to všechno výjimky, viz třeba jak se chápe file.latte v různých místech šablony https://fiddle.nette.org/latte/#….

Eda
Backer | 220
+
+1
-

Cením snahu to celé nějak sjednotit, zpřehlednit a zformalizovat :-)

Ale psát tady ty dvojité uvozovky mi tedy taky přijde dost neintuitivní.

filbar
Člen | 13
+
0
-

A co to dát do závorek celé?

n:snippet="{row-{$id}}"

případně

n:snippet="{row-$id}"

Za mě mi to přijde nejpřehlednější než míchání uvozovek, kde se člověk sdnadno přehlédne?

kukulich
Člen | 58
+
+3
-

Ok, tak mám za sebou tři dny přepisování všech maker Slevomatu na nový zápis. Je teda pravda, že jsem předtím už nějaký čas strávil řešením deprecated věcí z 2.11.0 a 2.11.1.

Plusy:

  • Rozhodně je to přehlednější. Dost pomohlo, že výstupem je teď PHP kód.
  • Lépe se to hackuje :) Např. je skvělé, že se snadno dají přepsat originální makra.
  • Je super, že je to striktnější. Našlo to spoustu i malých překlepů v šablonách.

Minusy:

  • Chvíli mi trvalo přijít na to, kterou metodu $tag->parser kdy použít.
  • Stejně tak, kdy použít %raw, %dump či %args.
  • Bojoval jsem s některými zápisy, ale věřím, že budoucí parseUnquotedString() to ještě vylepší, viz https://forum.nette.org/…jinach-nette#…

Počítám, že některé věci pořeší budoucí dokumentace či ještě úpravy před releasem, takže celkově je to za mne skvělý a už se těším, až to budu moct nasadit :)

Kamil Valenta
Člen | 752
+
0
-

David Grudl napsal(a):

@KamilValenta to, co se píše do {...} a n:attr="...", je PHP kód. S určitými, ale pevně danými odlišnostmi…

Vycházím z toho, že to až tak úplně PHP kód není. Nebo tedy že je těch odlišností celkem dost. Prostě jsou makra, která se vnitřně vyhodnocují různě.
Jak už jsem uvedl,

n:name="nazev"

se také nijak nevyhodnocuje a chápe se dle kontextu jako string,

<input type="text" n:attr="value: $item->getValue()">

se také nevyhodnotí „v PHP“, ale transformuje na value=„…“

Ale v zásadě je mi to jedno, zvyknu si na uvozovky v apostrofech, ač se to nejen mně zdá jako podivný krok někam stranou…
Už to dál rozvíjet nebudu, byl to jen návrh, který mi přišel přehledný.

David Grudl
Nette Core | 8082
+
+2
-

@KamilValenta Točíme se v kruhu a plevelíme tím vlákno, souhlas, ukončíme to. Každopádně uvozovky v apostrofech nebudou, viz předchozí posty.

David Grudl
Nette Core | 8082
+
0
-

@kukulich Tyjo, je to super, že to tak testuješ! Trošku se bojím, ať další bety nic nerozbijou. Dokumentaci dám na web až bude blížit do finále.

Ages
Člen | 127
+
0
-

Ahoj, aktualizoval jsem projekt, na Latte v2.11.0 a odstranil všechny deprecated věci.
Nicméně projekt běží na Nittru a spolu s verzí 2.11.1 jsem narazil na problém, že v názvu marka nově nemůže být tečka.
Tato změna, nevyvolá deprecated hlášku, ale shodí celou aplikaci díky LogicException Invalid tag name

Marek Bartoš
Nette Blogger | 1146
+
0
-

@Ages 2.11.2 bude fungovat. https://github.com/…85b56830c556

Ages
Člen | 127
+
0
-

@MarekBartoš ok – 2.11.1 tedy přeskočím a počkám na vydání nové verze.

kukulich
Člen | 58
+
0
-

@DavidGrudl Testuju právě 2.11.2 a dostávám hlášku:

Expression '/images/fortunewheel/banner/fortunewheel.jpg?v3' should be wrapped in double quotes.

Je možné otazník přidat do podporovaných znaků, nebo to technicky nejde?

David Grudl
Nette Core | 8082
+
+1
-

No jde o to rozlišit, jestli určitý „shluk znaků“ považovat za unquoted řetězec nebo PHP výraz. Zkusím rozebrat všechny znaky, jestli mohou být v unquoted řetězci, u řady fakt váhám:

  • znaky a-z0-9_ mohou být součástí takového řetězce (a whitespace být nemůže)
  • $ nemůže, protože $foo chceme vnímat jako proměnnou, ale lze jej použít uvnitř složených závorek {$foo}
  • {} tím pádem můžou, ovšem fungují jako string interpolation
  • () nemůžou, protože znaky foo() chceme vnímat jako volání
  • [] nemůžou, protože znaky [x] chceme vnímat jako pole
  • : zápis class::const chceme vnímat jako výraz, ale pokud bude dvojtečka jen jedna, musí být povolená, protože se používá v odkazech
  • '" uvozují řetězec, nemůžou být součástí unquoted řetězce
  • # je v PHP komentář, ale ne v Latte, tak klidně může být v řetězci
  • , nemůže, protože v {include xxxx,yyy} ji vnímáme jako oddělovač
  • | nemůže, protože v {include xxxx|yyy} chceme vnímat | jako filtr

A od této chvíle to přestává být jednoznačné.

  • +-*/%.^ jsou operátory. Otázka je, zda chceme 25-13 vnímat jako výraz. V tuto chvíli jsou v řetězci -/. povolené, protože se běžné používají v CSS třídách a souborových cestách, tudíž 25-13 není výraz ale řetězec. Nevím, zda +*%^ povolit taky.
  • !~ jsou unární operátory. Chceme !true nebo ~123 vnímat jako výraz? Nevím…
  • <=> chceme vnímat 10<=20 jako výraz? To sice nedává moc smysl, ale 1>>3 už jako výraz smysl dává a <<< je začátek phpdoc syntaxe. Tudíž se kloním k tomu, aby v řetězci být nemohly
  • ? chceme vnímat true?a:b jako výraz? nevím…
  • &@;\ nenapadá mě kolidující případ pro tyto znaky, asi by mohly být v řetězci

Samozřejmě kombinací znaků vznikají další operátory, jako třeba -> nebo +=, ale tím že není povolený $, tak nevytvářejí kolize.

hrach
Člen | 1834
+
+1
-
  • 25-13, 1>>3, true?a:b vnimam jako retezec, vyrazy by u me „musely“ obsahovat mezeru.
  • !true a ~123 moc nevim – jaky je workaround, kdyby toto byly retezce?
David Grudl
Nette Core | 8082
+
0
-

Workaround kdyby to byly řetězce? Tomu moc nerozumím. Řetězce se dají vždycky zapsat do uvozovek. Naopak kdyby to řetězce nebyly, tak by se tam asi musely dát mezery.

David Grudl
Nette Core | 8082
+
+8
-

Latte 3 beta 2

Dnes jsem vypustit druhou beta verzi Latte. Hlavní úpravou je to, co se probíralo tady ve vlákně, a to parsování tzv. unquoted řetězců. V nich je nyní možné používat výrazy ve složených závorkách, takže např. row-{$foo} není potřeba dávat do uvozovek, což se ocení hlavně u n:atributů. Takže by parsování mělo být daleko bližší Latte 2. Ještě zbývá rozhodnout drobnosti viz tady.

Zároveň jsem zaktualizoval nette/forms, nette/caching a nette/application. Pro testování stačí do composer.json dát (ano, použijte dev, protože postupně opravuju nalezené chyby)

	"require": {
		"nette/application": "^3.1-dev",
		"nette/caching": "^3.1-dev",
		"nette/forms": "^3.1-dev",
		"latte/latte": "^3.0-dev",

Interní změny

Pak jsou tu nějaké interní změny a zajímají tedy jen ty, kdo už zkoušeli psát tagy pro Latte 3:

  1. změna TagParser::parseFilters(): ?Expression\FilterNodeparseModifier(): Node\ModifierNode
  2. změna TagParser::parseWithModifier()tryConsumeModifier()
  3. v Node změna property int $startLineLatte\Compiler\Position $position

ad 1) filtry v tagu se parsují do nového (non-nullable) objektu ModifierNode, jelikož původní implementace se mi nakonec nelíbila
ad 2) jako důsledek změn parsování unquoted řetězců
ad 3) pro předávaní čísel řádků v kódu jsem vytvořil třídu Position, která navíc nese informaci o sloupci, který se pak předává do chybových hlášek a Tracy od verze 2.9.2 jej vyznačuje v bluescreenu.

Příklad kódu, kde se projevily všechny tři změny, je třeba soubor IncludeFileNode.php. Ve většině kódu stačilo zaměnit ->startLine za ->position.

Kdybyste potřebovali cokoliv rozepsat víc, napište.

A pak už jdeme do finále

Předpokládám, že tohle by mohla být poslední beta a na API už sahat nechci. Takže by mohl brzy následovat RC a pak stable.

(Tento celý web včetně fóra už na Latte 3 jede)