Latte bloky, HTML kontexty a context-aware escapování
- Jan Konáš
- Člen | 1
Pokud mám v layoutu blok uvnitř HTML tagu:
<div {block #divAttrs}{/block}>
a zkusím ho v šabloně přepsat:
{block #divAttrs}style="background: red;"{/block}
tak dostanu Warning: Overridden block divAttrs with content type HTMLTAG by incompatible type HTML.
Nenašel jsem způsob, jak deklarovat v šabloně, že blok je opravdu typu HTMLTAG. Makro {contentType} jednak nemůžu použít uvnitř bloku a hlavně přes něj lze nastavit pouze typ HTML ale už ne kontext TAG.
Můžu to obejít tím, že přesunu blok dovnitř atributu:
<div style="{block #divStyle}{/block}">
{block #divStyle}background: red;{/block}
protože HTML je nastavené jako kompatibilní s HTMLATTR, ale to má stále nevýhodu v tom, že zmatu context-aware escapování, které mi vnitřek bloku escapuje jako HTML a ne obsah HTML atributu (HTMLATTR).
Existuje jiné řešení než do bloku přesunout celý tag?
- petrknap
- Člen | 6
Mám v podstatě stejný problém. V šabloně (control) mi v cyklu dynamicky vznikají bloky
<td class="{block table-td-$key-classes}table-control-col-{$key}{/block}">
a v další šabloně je rozšiřuji
{block table-td-actions-classes}{include #parent} text-center{/block}
což od aktualizace Nette na 2.4 vede k
Overridden block table-td-actions-classes with content type HTMLATTR by incompatible type HTML.
- David Grudl
- Nette Core | 8218
což od aktualizace Nette na 2.4 vede k Overridden block table-td-actions-classes with content type HTMLATTR by incompatible type HTML.
To by se stávat nemělo. Můžeš třeba na GitHub hodit příklad na bázi Sandboxu?
- GEpic
- Člen | 566
postolka napsal(a):
Resim stejny problem s inline inicializaci JS :/. Mam na strance vice modulu – kazdy s vlastnim JS kodem pro inicializaci a potreboval bych ho ulozit do promenne a na konci vlozit do spolecneho <script> elementu.
Jakože v komponentě si nadefinuješ block a ten pak chceš vypsat v patičce layoutu?
Chápu asi o co ti jde, chceš prostě veškerý vlastní JS kód jednotlivých komponent spustit až po načtení ostatních JS knihoven (které se dávají do patičky webu).
- Pavel Kravčík
- Člen | 1195
Mně docela funguje následující, i ve 2.4 a navíc je js pěkně v samostatné souboru v komponentě.
//layout
<script>
{block #js}
</script>
//presenter latte
{define #js}
{component:js}
{/define}
//KIMjongUNenta
class Component
{
pf renderJs()
{
$this->template->setTemplate('javascript.latte');
$this->template->render();
}
}
- postolka
- Člen | 2
GEpic napsal(a):
postolka napsal(a):
Resim stejny problem s inline inicializaci JS :/. Mam na strance vice modulu – kazdy s vlastnim JS kodem pro inicializaci a potreboval bych ho ulozit do promenne a na konci vlozit do spolecneho <script> elementu.
Jakože v komponentě si nadefinuješ block a ten pak chceš vypsat v patičce layoutu?
Chápu asi o co ti jde, chceš prostě veškerý vlastní JS kód jednotlivých komponent spustit až po načtení ostatních JS knihoven (které se dávají do patičky webu).
Presne tak.
Latte pouzivam bez Nette, takze Pavlovo reseni mi moc nepomuze.
Zatim jsem to vyresil tak, ze sablonam predavam jako parametr kontejner, do
ktereho stringem nacpou vsechno co chcou a z toho se pak v paticce vsechno
precte. Tim ale prichazim o vsechny syntakticke vychytavky, protoze IDE
(PHPStorm) mi ten retezec nerozpozna jako JS a
<<<JS heredoc
, v {php }
zrejme
nefunguje vubec
Jednotlive moduly:
{php
$container->code .= "var useModuleA = true;";
}
… a pak v master view:
<script type="application/javascript">
{$container->code|noescape}
</script>
Editoval postolka (27. 9. 2016 10:03)
- GEpic
- Člen | 566
Pavel Kravčík napsal(a):
Mně docela funguje následující, i ve 2.4 a navíc je js pěkně v samostatné souboru v komponentě.
//layout <script> {block #js} </script> //presenter latte {define #js} {component:js} {/define} //KIMjongUNenta class Component { pf renderJs() { $this->template->setTemplate('javascript.latte'); $this->template->render(); } }
No, já řešení tohoto problému mám v tuto chvíli pomocí JS defer, kdy jednoduše počkám, až se načtou knihovny v patičce, každopádně není to úplně ideální.
Problém je v tom, že máme dynamické komponenty, které mohou být pomocí speciálního zápisu / makra vloženy i do textu, obsahu stránky, do boxu. Prostě kdekoliv na stránce může být vložena jakákoliv komponenta (tudíž jsou doopravdy absolutně znovupoužitelné) a tady nastává problém. Dopředu nevím, jaké komponenty se kde vypíšou (Uživatel si jednoduše v půlce článku může vypsat třeba znovu menu, nebo galerii, cokoliv.). A toto bych chtěl vyřešit.
Napadlo mě jedině udělat si nějaký collector jako službu, do ní si v každé komponentě vygenerovat template a pak jí do collectoru vložit. Veškeré templaty pak nechat vypsat v patičce.
PS: Omlouvám se za offtopic
Editoval GEpic (28. 9. 2016 5:53)
- petrknap
- Člen | 6
David Grudl napsal(a):
což od aktualizace Nette na 2.4 vede k Overridden block table-td-actions-classes with content type HTMLATTR by incompatible type HTML.
To by se stávat nemělo. Můžeš třeba na GitHub hodit příklad na bázi Sandboxu?
Příklad vytvořen, issue založeno – https://github.com/…e/issues/146 –
stává se to na ENV
docker run -p 8080:80 -v $(pwd):/var/www/html --rm php:5.6-apache
.