Latte bloky, HTML kontexty a context-aware escapování

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jan Konáš
Člen | 1
+
+6
-

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?

GEpic
Člen | 566
+
0
-

A proč to prostě nedáš do proměnné? Blok k tomuto určený není.

petrknap
Člen | 6
+
0
-

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.

postolka
Člen | 2
+
0
-

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.

David Grudl
Nette Core | 8218
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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)

CZechBoY
Člen | 3608
+
0
-

@GEpic neco takovyho pouzivame taky + jeste to je ve snippetu takze si komponenta muze pridat js i pokud je zobrazena az pri signalu.

petrknap
Člen | 6
+
+1
-

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.