Nová verze Nette a dynamické snippety
- jansfabik
- Člen | 193
https://forum.nette.org/…ce-nette-2-0
Bohužel to nejde, v nové verzi musí mít všechny snippety statický
název. Nešlo by ten snippet pojmenovat rate
a pak v presenteru
do $this->template->...
uložit všechny v něm používané
proměnné?
- tomees
- Člen | 59
HosipLan napsal(a):
zkoušel jsi
{snippet "rate$id"}
?
<?php
{snippet "rate$id" span}
{foreach $stars as $star}
<img src="{$basePath}/images/site/icons/star_{$star}_red.gif" title="{$id}" />
{/foreach}
{/snippet}
?>
Nette\Templates\LatteException
Block name must be alphanumeric string, ‚_"rate$id"‘ given in …\components\RatingControl.phtml:5
Editoval tomees (14. 11. 2010 16:40)
- jansfabik
- Člen | 193
Možná by pomohlo, kdyby někdo implementoval toto:
https://forum.nette.org/…nette-sablon
Ale nevím, jestli by bylo správným krokem jenom kvůli snippetům přepisovat odladěný 45-kilobajtový LatteFilter.
- norbe
- Backer | 405
Toto chování dle mého názoru cílené a způsobí to mimo jiné i rychlejší odezvu v systému při použití ajaxu.
Člověk si musí uvědomit, jak by se šablony při ajaxu měli chovat. Myslíte si snad, že by se měli zpracovávat kompletně? Já myslím že by se měla zpracovat pouze ta část šablony, které je uvnitř invalidovaného snippetu a to je důvodem toho, že dynamické snippety nemohou fungovat. Na závěr musím říct, že jsem nestudoval jak je to implementovaný, jen uvažuju proč to je tak jak to je a proč si myslím že to tak je správně…
- redhead
- Člen | 1313
Ono s rychlostí to stejně bude nastejno:
Když budu mít nějaký výpis položek, tak s nynější implementací budu muset posílat celý výpis místo oné jedné položky, která se změnila (tedy projít cyklem všechny položky a vypsat je). S dynamickými snippety by se sice prošli všechny položky, ale odeslala by se jen ta, co se změnila. Čili na straně serveru je to prakticky totožné. Dynamické snippety by ale navíc byly teoreticky menší a rychlejší na transport dat – včetně práce JS na klientu.
Editoval redhead (14. 11. 2010 23:29)
- tomees
- Člen | 59
norbe napsal(a):
S tím bych zase moc nesouhlasil, jelikož dynamický snippet lze nahradit dynamickou komponentou, kterou vykreslim v cyklu. Pokud pak komponenta přijme nějaký signál, invaliduje se a odešle pouze svůj kód.
já to tak teď prakticky mám, mám hlasovací komponentu, která je na stránce 30× a v každé je snippet, který obsahuje hvězdičky
no ale i když bude komponenta dynamická, stále bude muset nějaký snippet vykreslovat ne? A když bude vykreslovat snippet rate, pak na stránce bude 30× blok „rate“.. a potom JS aktualizuje obsahy všech těchto bloků ne?
Editoval tomees (15. 11. 2010 8:24)
- norbe
- Backer | 405
Myslel jsem to nějak takhle:
// tovarnicka
public function createComponent($name) {
if (preg_match("/^rateControl/", $name)) {
$rateControl=new RateControl($this, $name);
// z nazvu si ziskam predane id a nastavim ho komponente...
$rateControl->setId($id)
}
else {
return parent::createComponent($name);
}
// sablona
{foreach $articles as $article}
{control rateControl.$article->id}
{/foreach}
Edit: Sice budeš mít jednu komponentu, ale s jiným názvem, takže se vždycky invaliduje pouze jedna konkrétní…
Editoval norbe (15. 11. 2010 9:02)
- David Grudl
- Nette Core | 8218
Implementace zatím není kompletní, info viz https://forum.nette.org/…zi-nette-2-0
- jansfabik
- Člen | 193
Pokud by byly zavedeny dynamické snippety, tak by se vždycky generovala část stránky zbytečně a pak se zahodila.
Napadá mě řešení: Snippety by zůstaly statické, ale mohly by být vícekrát invalidovány.
{foreach $items as $item}
...
{snippet rate $item->id} {* to $item->id se vloží nakonec ID snippetu (a <div>u) *}
<img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++">
{/snippet}
...
{/foreach}
v presenteru:
$items = $model->getRatings(); // načteme jenom to, co je potřeba (rating a id)
foreach ($items as $item) {
$this->template->item = $item;
$this->invalidateControl('rate');
}
Vlastně by šlo jen o to, aby se snippety vykreslily už při volání
invalidateControl
, a aby se drobně upravilo makro
{snippet}
. Takové řešení by pak bylo velmi efektivní.
edit: Vylepšen kód presenteru.
Editoval jansfabik (15. 11. 2010 17:16)
- David Grudl
- Nette Core | 8218
Bych to viděl tak, že
- zruší se druhý parametr snippetu. Pokud budu chtít snippet z jiného
elementu než div, napíšu to
takto
<tbody n:snippet="name">
- dynamické snippety by byly povoleny jen uvnitř statických. Invalidoval by se jen ten statický-obalovací a vykreslil by všechny dynamické uvnitř.
- Filip Procházka
- Moderator | 4668
David Grudl: 1) +1
co něco takového?
šablona – prostě se parametry předají
{foreach $items as $item}
...
{snippet rate, 'item' => $item, 'jen_pro_ukazku' => 'ahojky'} {* stejně jsou to teď bloky ... *}
<img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++"> {$jen_pro_ukazku}
{/snippet}
...
{/foreach}
volání – parametry předám znovu, nemusím lézt do „rodiče“
$id = $this->getParam('id');
$item = $this->model->getRankById($id);
$this->invalidateControl('rate', array('item' => $item, 'jen-pro-uKazku' => NULL));
$this->invalidateControl('rate', array('item' => $item)); // notice, jen_pro_ukazku je undefined, popř dosazení výchozí NULL
takhle nějak by se mohlo generovat ID, ale to už je detail
$hmtlId = 'rank-' . substr(md5(serialize($params)), 0, 8);
vytvořila by se žádost, která by zavolala snippet s těmi hodnotami a
tím by byla zaručena dynamičnost,
jenom by to fungovalo trochu jinak :)
//edit: hmmm nápad to byl dobrý než jsem si uvědomil že když změním nějakou hodnotu $item tak mi to pošle jiné ID … :)
a nebo ještě jinak
{foreach $items as $item}
...
{var $jen_pro_ukazku = 'ahojky'}
{snippet rate, 'itemId' => $item->id} {* v podstatě tagy, ostatní parametry se vezmou od rodiče ... *}
<img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++"> {$jen_pro_ukazku}
{/snippet}
...
{/foreach}
trochu jiná invalidace
$this->invalidateControl('rate', $tags = array('itemId' => $item->id), $args = array('jen_pro_ukazku' => 'cauky'));
$this->invalidateControl('rate', $tags = array('itemId' => $item->id), $args = array(''));
Popř by se to mohlo zjednodušit na něco podobného původní implementaci a dovolit identifikaci pouze na základě jednoho řetězce ať už int nebo string
{* ted si vymyslim, netuším jaký formát mají htmlId snippetů *}
{snippet rate}
<div id="snippet-rate"> ... </div>
<td n:snippet="rate">
<td id="snippet-rate"> ... </td>
{snippet rate, $item->nejakeid}
<div id="snippet-rate-<?=webalize($item->nejakeId) ?>"> ... </div>
<td n:snippet="rate, $item->nejakeid">
<td id="snippet-rate-<?=webalize($item->nejakeId) ?>"> ... </td>
$this->invalidateControl('rate', $item->nejakeid, $args = array('item' => $item, 'jen_pro_ukazku' => 'cauky'));
$this->invalidateControl('rate', $item->nejakeid); // notice, nemá proměnné
případně ještě trochu jinak, a zavolat pouze vykreslení bloku s proměnnými templaty
$this->template->item = $item;
$this->template->jen_pro_ukazku = 'čauky'
$this->invalidateControl('rate', $item->nejakeid);
Pochybuju, že někdo bude potřebovat jemnější rozlišení, stejně se to páruje většinou ‚jméno‘ + ‚nejakeid‘ takže by to věc ještě zjednodušilo, id snippetu by se nepředávalo, ale jenom by se použilo na vygenerování tagu
tak jo, nakonec jsem přišel zpátky k tomu že stačí 1 parametr navíc
{snippet rate} nebo <td n:snippet="rate">
{snippet rate, $item->nejakeid} nebo <td n:snippet="rate, $item->nejakeid">
a generovat z něj hmtlId
$this->template->item = $item;
$this->template->jen_pro_ukazku = 'čauky'
$this->invalidateControl('rate');
$this->invalidateControl('rate', $item->nejakeid);
//edit: lol, taková prasárna tady :D
Editoval HosipLan (16. 11. 2010 10:27)
- jansfabik
- Člen | 193
David Grudl napsal(a):
- zruší se druhý parametr snippetu. Pokud budu chtít snippet z jiného elementu než div, napíšu to takto
<tbody n:snippet="name">
s tím souhlasím, +1
- dynamické snippety by byly povoleny jen uvnitř statických. Invalidoval by se jen ten statický-obalovací a vykreslil by všechny dynamické uvnitř.
To by ale se zase zbytečně generoval kód, který by nebyl potřeba. Nenapadá mě důvod, proč by měly snippety být dynamické, když stačí statické snippety, které lze invalidovat pokaždé s jinými proměnnými. Existuje nějaký případ, kdy by toto nestačilo?
HosipLan napsal(a):
No, v podstatě jsi došel ke stejnému kódu jako já. ;-)
Pro lepší představu:
{snippet rate, $item->id}
<img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++">
{/snippet}
by bylo ekvivalentní zhruba s něčím takovým:
{block _rate}
<div id="snippet-{$control->getName()}-rate-{$item->id}">
<img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++">
</div>
{/block}
Při invalidaci snippetu rate
by se pak jen zavolala ta
zkompilovaná šabloní funkce s blokem _rate
a výstup by se
uložil do payload
u.
- bojovyletoun
- Člen | 667
Ahoj,
To by ale se zase zbytečně generoval kód, který by nebyl potřeba. Nenapadá mě důvod, proč by měly snippety být dynamické, když stačí statické snippety, které lze invalidovat pokaždé s jinými proměnnými. Existuje nějaký případ, kdy by toto nestačilo?
Jak se to používá?: statické snippety, které lze invalidovat pokaždé s jinými proměnnými.
- jannemec
- Člen | 78
jansfabik napsal(a):
David Grudl napsal(a):
- zruší se druhý parametr snippetu. Pokud budu chtít snippet z jiného elementu než div, napíšu to takto
<tbody n:snippet="name">
s tím souhlasím, +1
ano, to vypadá dobře +1
>
- dynamické snippety by byly povoleny jen uvnitř statických. Invalidoval by se jen ten statický-obalovací a vykreslil by všechny dynamické uvnitř.
To by ale se zase zbytečně generoval kód, který by nebyl potřeba. Nenapadá mě důvod, proč by měly snippety být dynamické, když stačí statické snippety, které lze invalidovat pokaždé s jinými proměnnými. Existuje nějaký případ, kdy by toto nestačilo?
HosipLan napsal(a):
No, v podstatě jsi došel ke stejnému kódu jako já. ;-)
Pro lepší představu:
{snippet rate, $item->id} <img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++"> {/snippet}
by bylo ekvivalentní zhruba s něčím takovým:
{block _rate} <div id="snippet-{$control->getName()}-rate-{$item->id}"> <img src="star.gif" n:for="$i = 0; $i < $item->rating; $i++"> </div> {/block}
Při invalidaci snippetu
rate
by se pak jen zavolala ta zkompilovaná šabloní funkce s blokem_rate
a výstup by se uložil dopayload
u.
Takhle to vypadá zajímavě a myslím, že dynamické snippety jsou
užitečná věc – od více hlasování, přes nějaké AJAX kusy textu …
přijde mi toto řešení lepší než tvorba více controlů
JN