Řešení dynamických snippetů

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
hrach
Člen | 1823
+
0
-

Zápis v Latte

{foreach array(1,2,3) as $id}
	{snippet rater-$id}
		Rater for {$id} {=microtime(true)}
	{/snippet}
{/foreach}

Je povinný formát: jmeno-$klic

Invalidace:

$this->invalidateControl('rater-2', array(
	'id' => 2,
));

Invalidace je nova. Nutne:

  • jmeno je opet format jmeno-klic
  • druhy parametr jsou vsechny promenne, ktere maji byt v dannem snippetu dostupne a jsou zavisla na danem scope, tzn. promenne zavisle na cyklu

Toto reseni mam nyni implementovane a funkcni.

Poznamky

  • nelze invalidovat vsechny dynamicke snippety zaraz, aktualni kod tento pokus jeste nehlida, bylo by dobre nejak doplnit
  • pri potrebe invalidovat vsechny dynamicke snippety je resenim obalit dany cyklus vlastnim snippetem

Děkuji za návodné návrhy HosipLanovi: https://forum.nette.org/…cke-snippety#…

Co si o tom myslite?

Patrik Votoček
Člen | 2221
+
0
-

Neznám implementační detaily ale ale proč je nutné uvádět tu dvojku 2×? pokud tedy platí: Je povinný formát: jmeno-$klic

hrach
Člen | 1823
+
0
-

Jasny, chapu dotaz, zkusim rozepsat duvody k tomuto reseni.

Problém 1
Je treba jednoznacne identifikovat dany dynamick blok. K tomu se pouziva nejaky primarni klic. Predani tohoto klice lze resit:

  1. predanim v nazvu snippetu
  2. predanim jako promenne

Prvni verzi vidite viz vyse, druha by vypadala nejak takhle:

{snippet rater, $id} // nebo
{snippet rater, id => $id}

Coz by rozbilo aktualni funkcnost s definovanim vlastniho obalovaciho tagu + by to evokovalo predavani promennych do {block}, coz je zase jina problematika.

Problem 2
V kazdem pripade bude pri ajaxovem volani treba predavat snippetu aktualni scope. Protoze se samotny cyklus spoustet nebude.
Tedy zbyva vyresit, jestli pri beznem requestu snippetu predavat promenne jako do {block}u, nebo danemu snippetu „pushnout“ aktualni scope. Zvolil sem cestu 2, aby bylo co nejmene zmatku a co nejvetsi zpetna kompatibilita.

K aktualni navrhovane verzi
K duplikaci „$id“ vůbec dojit nemusi, pokud se na to podivas treba takhle:

{foreach $items as $item}
	{snippet rater-$item->id}
		<h1>Item {$item->title}</h1>
	{/snippet}
{/foreach}
$this->invalidateControl('rater-2', array(
        'item' => ItemModel::get(2),
));
Patrik Votoček
Člen | 2221
+
0
-

už to chápu díky za vysvětlení. btw napadá mě jeden potencionální „problém“ aka $iterator

sinacek
Člen | 23
+
0
-

Funguje vám způsob popsaný nahoře? mě to stále hází

LatteException

Block name must be alphanumeric string, ‚_rater-$id‘ given

Editoval sinacek (10. 5. 2011 21:31)

Patrik Votoček
Člen | 2221
+
0
-

protože to není implementované… tohle je RFC (návrh řešení)

sinacek
Člen | 23
+
0
-

Patrik Votoček napsal(a):

protože to není implementované… tohle je RFC (návrh řešení)

Omlovám se, našel jsem si to přes vyhledavač a nepodival se na kategorii. Díky

hrach
Člen | 1823
+
0
-

A ani nebude. V podstatě se dá to různě obcházet. (Je to dobře?) Problém je v tom, že dříve to fungovalo a nyní ne. (Byla to předtím feature, nebo jen náhodná funkčnost…)

Patrik Votoček
Člen | 2221
+
0
-

Mám takové tušení že aktuálně je to „uměle“ vypnuto. Kvůli nějakým možným komplikacím. (nevzpomenu si jaké to byly)

dotTwelve
Člen | 167
+
0
-

Jak to vypada s dynamickymi snippety? Budou / nebudou a kdy?

Editoval dotTwelve (26. 5. 2011 15:14)

hrach
Člen | 1823
+
0
-

spíš nebudou :) osobně na to netlačím, pač je moc nepotřebuji, většina věcí se dá totiž vyřešit jinak a možná i efektivněji. asi by to chtělo probrat jednotlivé usecase. Tu je něco o jiných cestách: https://forum.nette.org/…v-presenteru#…

David Grudl
Nette Core | 7887
+
0
-

Podle mého se téhož dá dosáhout takto:

{foreach array(1,2,3) as $id}
	{var $template->id = $id}
        {snippet rater}
                Rater for {$id} {=microtime(true)}
        {/snippet}
{/foreach}
$this->template->id = 2;
$this->invalidateControl('rater');
22
Člen | 1478
+
0
-

..akorát to bude nevalidní HTML :-(

David Grudl
Nette Core | 7887
+
0
-

Aha, to jsem si neuvědomil.

David Grudl
Nette Core | 7887
+
0
-

Ok, přidal jsem tedy podporu pro dynamické snippety, mělo by to fungovat takto:

{snippet rater}
	{foreach array(1,2,3) as $id}
        	{snippet rater-$id} // format je libovolny
	                Rater for {$id} {=microtime(true)} // uvnitr jsou videt promenne
        	{/snippet}
	{/foreach}
{/snippet}

A invalidace:

$this->template->id = 2;
$this->invalidateControl('rater');
hrach
Člen | 1823
+
0
-

Nechápu to moc. Jak nette pozná, kže chcu jen rater-2? To ono parsuje „rater-$id“ a ví, že do id jsem dal 2?

Filip Procházka
Moderator | 4668
+
0
-

Davide? Jak invaliduju 2 i 3 ?

Milanov
Člen | 51
+
0
-

Toto je super, nicméně mám stránku s diskuzemi a ke každé několik komentářů. Pod komentáři je form pro odpověď. Když odpovím, chci invalidovat pouze související komentáře. V šabloně jsem doteď, úspěšně, používal tento kód (ve verzi 0.9.7 se zavináči), který jsem zkusil obalit:

{foreach ... as $disk}
	{snippet komentare}
		{snippet komentare-$disk['id_diskuze']}
			{include 'komentare.latte', 'komentare' => $disk['komentare']}
		{/snippet}
	{/snippet komentare}
{/foreach}

Samozřejmě to nefunguje. Moje šablona by mezi obalovacím snippetem a obalovaným měla obsahovat spoustu kódu, včetně jiných snippetů. Předpokládám, že musím obalovací snippet přesunout před foreach, ale ani v tom případě to nefunguje, šablona se přeloží jako if (!function_exists($_l->blocks[_komentare-$disk['id_diskuze']][] a vyhodí se Noticka s nedefinovanou konstantou. Otázka zní: lze použít mezi obalovacím a obalovaným snippetem jiný kód? Lze vytvořit název snippetu ve tvaru komentare-$disk[‚id_diskuze‘]? Verze Nette Framework 2.0-beta (revision 2488680 released on 2011–06–01). Díky

David Grudl
Nette Core | 7887
+
0
-

Název snippetu musí být zapsán v uvozovkách, nebo „jako v uvozovkách“ a bez uvozovek, tj. {snippet "komentare-$disk[id_diskuze]"} nebo {snippet komentare-$disk[id_diskuze]}.

Statický snippet je skutečně výstřižek, při vykreslování se doslova vystřihne ze stránky a neexistuje nic před ním nebo za ním. Má-li tedy „existovat“ nějaký foreach a proměnná $disk, musí být zahrnuta do statického snippetu.

Invaliduje se pouze statický snippet. Ten může vykreslit tolik dynamických, kolik potřebuje. Pokud chcete vykreslit jen 2 a 3, upravte DB dotaz tak, aby získal jen tyto data.

(neuvažujte nad tím jako: vykreslím 100 komentářů, všechny zahodím a jen dvojku pošlu ven, to je přece prasárna)