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

David Grudl
Nette Core | 7780
+
0
-

@kukulich potřebuješ, aby %raw vykreslovalo i Node?

kukulich
Člen | 55
+
+2
-

David Grudl napsal(a):

@kukulich potřebuješ, aby %raw vykreslovalo i Node?

Nepočítám s tím. Všude, kdy posílám Node, tak už mám %node. A %raw mám jen tam, kde to chápu jako “nijak to nechci modifikovat”

David Grudl
Nette Core | 7780
+
0
-

Tak budeme muset udělat ještě jedno RC kolečko, protože jsem objevil chybu v escapování HTML atributů. Zase je fajn, že oprava té chyby vedla k lepšímu návrhu kodu.

Ještě jsem si všiml chybějících typehintů u třídy Filter, které jsem doplnil, a také odstranil $iterations, viz.

kukulich
Člen | 55
+
0
-

Tak budeme muset udělat ještě jedno RC kolečko

Mám prst na spoušti, tedy na composer.json :)

David Grudl
Nette Core | 7780
+
0
-

Jde to ňák pomalu, protože zobu prášky na alergii a furt spím :)

David Grudl
Nette Core | 7780
+
+3
-

Latte 3 RC 3 je venku

Tato verze řeší nějaké problémy s parsováním a escapováním HTML atributů, což si vyžádalo netriviální úpravu. Neměla by se ale ničeho dotknout, tedy pokud uvnitř HTML značky nepoužíváte nějaké hodně překvapivé konstrukce.

kukulich
Člen | 55
+
+3
-

David Grudl napsal(a):

Latte 3 RC 3 je venku

Tato verze řeší nějaké problémy s parsováním a escapováním HTML atributů, což si vyžádalo netriviální úpravu. Neměla by se ale ničeho dotknout, tedy pokud uvnitř HTML značky nepoužíváte nějaké hodně překvapivé konstrukce.

Slevomat má Latte 3 na produkci :)

V rámci toho jsem zaregistroval jednu změnu a nevím, zda je to bug nebo feature.

data-boolean="{$boolean}"

Pro false to původně vygenerovalo HTML data-boolean="", nově to vygeneruje data-boolean="0".

David Grudl
Nette Core | 7780
+
+3
-

nově to vygeneruje data-boolean=„0“.

Jo, to bude důsledek toho doplnění typehintů ve třídě Filter. Fixnu.

David Grudl
Nette Core | 7780
+
+8
-

Tak je to venku :-)

David Grudl
Nette Core | 7780
+
+2
-

Ad manuální instalace rozšíření pro Latte.

Ve verzi dva se to dělalo takto:

$latte->onCompile[] = function ($latte) {
	// nette/application
	Nette\Bridges\ApplicationLatte\UIMacros::install($latte->getCompiler());

	// nette/forms
	Nette\Bridges\FormsLatte\FormMacros::install($latte->getCompiler());

	// nette/caching
	$latte->getCompiler()->addMacro('cache', new Nette\Bridges\CacheLatte\CacheMacro);
};

// nette/application
$latte->addProvider('uiControl', $control);
$latte->addProvider('uiPresenter', $presenter);
$latte->addFilter('translate', [$translator, 'translate']);

// nette/caching
$latte->addProvider('cacheStorage', $cacheStorage);

// ...

Ve verzi tři se je to jednodušší, všechno řeší metoda addExtension(), která přidá značky, filtry, providery, zkrátka všechno:

// nette/application
$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($control));
$latte->addExtension(new Nette\Bridges\ApplicationLatte\TranslatorExtension($translator));

// nette/forms
$latte->addExtension(new Nette\Bridges\FormsLatte\FormsExtension);

// nette/caching
$latte->addExtension(new Nette\Bridges\CacheLatte\CacheExtension($cacheStorage));

V případě nette/application jsou rozšíření dvě. UIExtension řeší vše týkající se presenterů, tedy n:href, {link}, {control}, {snippet}, atd. TranslatorExtension řeší překlady, tedy značky {_xxx} a novou {translate}...{/translate}.

Pozor

TranslatorExtension se aktivuje tím, že nastavíte šabloně translator metodou $template->setTranslator($translator). Bez toho značky pro překlad nejsou k dispozici.

David Grudl
Nette Core | 7780
+
+15
-

Ještě jsem doplnil jednu experimentální featurku: pokud uvedete jazyk $template->setTranslator($translator, $lang), tak Latte se pokusí všechny statické texty přeložit už během kompilace šablony a výsledné překlady přímo zapíše do vygenerovaného souboru. V cache tak vznikne víc souborů, jeden pro každý jazyk.

MKI-Miro
Člen | 237
+
0
-

mne to po nasadeni verziu 3.0 hlasi pre tento kod:

<a href="/{$product->alias}"
Latte\Runtime\Filters::safeUrl(): Argument #1 ($s) must be of type string, null given, called in

ako to opraviť?

David Grudl
Nette Core | 7780
+
0
-

@MKI-Miro opravím to v Latte, jako workaround by mohlo fungovat <a href="/{$product->alias|nocheck}"

Kamil Valenta
Člen | 562
+
0
-

Nebyl by lepší workaround

<a n:href="product, alias => $product->alias">

a v routě to třeba jen hloupě bez testů splácnout?

MKI-Miro
Člen | 237
+
0
-

Workaround pomohol

ale natrafil som este na jeden problem

Tracy\DeferredContent::sendAssets() called after some output has been sent. Try Tracy\OutputDebugger to find where output started
23:        public function renderDefault(mixed $exception): void
24:        {
25:            $req = $this->getHttpRequest()->getHeader("user-agent");
26:
27:            Debugger::enable(Debugger::DETECT, __DIR__ . '/../../log/500');
Milo
Nette Core | 1256
+
0
-

@DavidGrudl Mám vlastní makro s argumenty:

{icon 'svg.file', class: 'my-class', width: $w}

a snažím se ho zkompilovat.

$fileName = $tag->parser->parseUnquotedStringOrExpression();
$tag->parser->stream->tryConsume(',');
$args = $tag->parser->parseArguments();

# A nyní bych chtěl $args ve zkompilovaném PHP vypsat jako pole.
foreach (['class' => 'my-class', 'width' => $w]...)

Našel jsem $context->format('%args', $args) ale výsledkem jsou argumenty ve formátu pro metodu:

class: 'my-class', width: $w

Teď si to poskládám ručně a použuju %raw, ale zajímá mě, jestli není příhodnější způsob. V Latte2 jsem používal rovnou %raw.

Tomáš Votruba
Moderator | 1114
+
0
-

@Milo Jestli to pomůže, v téhle větvi jsem dělal upgrade tvého makra ještě z Githubu na node v Latte 3:
https://github.com/…pull/4/files#…

Je tam i test a výpis všech argumentů.

Editoval Tomáš Votruba (20. 5. 15:48)

Milo
Nette Core | 1256
+
0
-

Jestli dobře koukám, tak nepomůže, protože jsi tam vynechal možnost použít dynamickou hodnotu atributů.

Tomáš Votruba
Moderator | 1114
+
0
-

@Milo To by nemělo vadit, protože jsou tam dynamické parametery z configu a obojí je user-defined pole.

Pomohlo mi použít %dump pro jednoduché pole.

Našel jsem $context->format(‚%args‘, $args) ale výsledkem jsou argumenty ve formátu pro metodu:

Named args vypadá jako nízké zanoření. Co se stane, když ten vstup obalíš ještě jedním polem?

Editoval Tomáš Votruba (20. 5. 19:57)

Tomáš Votruba
Moderator | 1114
+
0
-

@Milo Přidal jsem ty dynamické atributy zpět https://github.com/…b33d7eace793

Nakonec je to %node :)

Milo
Nette Core | 1256
+
0
-

Nemyslím si, že ti to funguje jak by mělo. A nemusíme to tu řešit, už to mám vyřešené. Jen mě zajímá snazší cesta.

Tomáš Votruba
Moderator | 1114
+
0
-

@Milo Původní fungovalo stejně, hodnoty se vypsaly jako pole do foreach args: https://github.com/…6e92a0eb4b9a#… (Latte 2). Teď mě zajímá, cos tam udělal jinak :)

radas
Člen | 218
+
0
-

Ahoj, jak v Latte 3 nahradit zápis {do break 2}? Latte lint křičí “Unexpected ‘2’, expecting end of tag in {do}”.

joe
Člen | 313
+
0
-

Ahoj, přicházím pozdě, ale přece – s otázkou, co vedlo k tomu nahradit makro pro překlady za dlouhé {translate}...{/translate} místo jednoduchécho {_}...{/_} a jestli je nějaký důvod zbavovat se zápisu {_'Text to translate'}?

  • v IDE se mi více líbí zápis {_'Text to translate'}, je to krátké, jasné (protože se to používá roky) a text k překladu vidím obarvený jako string, takže vím, že je přeložený, narozdíl od způsobu, kdy text bude mezi párovýma značkama.
  • {translate} je poměrně dost dlouhé, na psaní (pravda, dá se řešit nějakou zkratkou), ale i v kódu, kde pak samotné texty k překladu celkem zanikají a ztrácí se. {translate}Yes{/translate} mi prostě nepřijde elegantní, jednoduché a hezké jako dřív…
  • K variantě {_'Text to translate'} se dají jednoduše doplnit placeholdery na {_'Text to %s', 'translate'}, u párového makra si to moc nedovedu představit psát do otevírací značky a nedává mi to při čtení a kontrole smysl.

Tak to jen takový rychlý feedback :)

David Grudl
Nette Core | 7780
+
-1
-

@radas https://latte.nette.org/cs/develop#…

@joe {translate} je párové a {_'Text to translate'} zůstává jako nepárové. Že je to dlouhé, s tím jdeš opravdu trošku pozdě :)

joe
Člen | 313
+
0
-

David Grudl napsal(a):
@joe {translate} je párové a {_'Text to translate'} zůstává jako nepárové. Že je to dlouhé, s tím jdeš opravdu trošku pozdě :)

:) Spíš mě zajímala ta myšlenka, proč vlastně přejmenovávat něco, co roky fungovalo? Aby šlo na první pohled poznat, že to dělá překlady (i pro ty, co se s tím dřív nesetkali)?

David Grudl
Nette Core | 7780
+
+2
-

Protože v Latte 3 může být značka buď párová, nebo nepárová. Nejde to míchat.

joe
Člen | 313
+
0
-

David Grudl napsal(a):

Protože v Latte 3 může být značka buď párová, nebo nepárová. Nejde to míchat.

Jo díky, už tomu rozumím, problém je v tom, že nejde mít teď značku zároveň párovou a nepárovou, takže byla potřeba vymyslet jiný název. Čemu vlastně ale nerozumím, tak proč ta párová značka vlastně existuje :-)

Matey
Člen | 142
+
+1
-

Drobný projekt premigrovaný z latte 2.11.* na latte 3.0.*

Pár poznámok, latte-linter neodhalil že oddeľovač premenných v tagu {var ...; ...} je nesprávny po novom je to {var ..., ...}

{var $inputName = 'note'; $input = end($this->global->formsStack)[$inputName]} //nesprávne
{var $inputName = 'note', $input = end($this->global->formsStack)[$inputName]} //správne

Filter |breakLines už nejde použiť na null hodnoty.
Nebolo by vhodné povoliť null hodnotu pre tento filter?

Inak zvyšok šiel hladko. Diky, dobrá práca.

David Grudl
Nette Core | 7780
+
+8
-

Latte 3.0.1 a nette/application 3.1.7

Řeší nějaké věci, co byly hlášeny:

  • filtry |breakLines |substring a |truncate akceptují null
  • {first} uvnitř n:foreach https://github.com/…e/issues/298
  • necheckuje URL, pokud ho generujete značkami n:href nebo {link}
  • značky pro překlad {_expr} a {translate} přímo v Latte

Došlo mi, že je legitimní chtít používat značky pro překlad i bez nette/application, tak jsem přesunul TranslatorExtension z nette/application do Latte, tudíž je to nyní Latte\Essential\TranslatorExtension. Samozřejmě jde o BC break, pokud instalujete rozšíření ručně, tak sorry.

Milo
Nette Core | 1256
+
0
-

Aktualizuji jednu aplikaci, kde jsem používal <h4 n:inner-_>Text</h4>, to jsem pro 2.11.4 přepsal na <h4 n:inner-translate>Text</h4>, ale 3.0.1 lint protestuje Unexpected attribute n:inner-translate. Je k tomu důvod?

David Grudl
Nette Core | 7780
+
+2
-

Opraveno

Milo
Nette Core | 1256
+
0
-

Díky!

ali
Člen | 342
+
+1
-

@DavidGrudl jde nejak u translate znacky vypnout spojovani stringu, kdyz neni v uvozovkach?

{_messages.hello} prelozi Latte jako 'messages' . 'hello' coz posila do translatoru string messageshello

{_"messages.hello"} funguje dle ocekavani

Editoval ali (10. 6. 22:24)

David Grudl
Nette Core | 7780
+
+6
-

Latte 3.0.2

  • opraveno n:inner-translate, {_messages.hello}
  • vylepšeno chování {syntax} a n:syntax (+ úprava v TemplateLexer)
  • vrácena podpora pro HEREDOC/NOWDOC (před vydáním 3.0.0 jsem ji odstranil, ale chyběla mi :-)
  • dovolil jsem si ještě zjednodušení tříd v Latte\Compiler\Nodes\Php\Expression nodech, což je samozřejmě BC break, tak snad nikoho nepostihne
pcs
Člen | 22
+
0
-

Když se v Latte zrušilo Engine::addFilter(null, …) ve prospěch addFilterLoader() bylo by dobré v Nette\Bridges\ApplicationLatte\Template umožnit addFilterLoader() použít. Pokud tedy neexistuje nějaká lepší metoda jak zaregistrovat filtry než jejich registrace v Presenteru v protected function createTemplate()🙂

Marek Bartoš
Nette Blogger | 717
+
0
-

@pcs Application bridge nikdy nebyl ideální cesta. Filtry se dají registrovat v Extension, viz: https://github.com/…xtension.php#L99

David Grudl
Nette Core | 7780
+
+1
-

@pcs použij $this->template->getLatte()->addFilterLoader(...)

Martk
Člen | 633
+
0
-

@DavidGrudl Půjde u $tag->parser->parseArguments() i vlastní latte funkce? Nyní mi přeloží customFunction() jako customFunction() namísto $this->global->fn->customFunction()