Snippety a inkludovana šablona
- dakota
- Člen | 148
Neviem či je to chyba alebo je to len nedoriešené. Vo najnovšej vývojovej verzii pri použití snippetu v inkludovanej šablone nedôjde k prekresleniu snippetu pri ajaxovom volaní. Ak tento snippet premiestnim do neinkludovanej šablony prekreslenie funguje v poriadku. Pred odstranením zavináčov to išlo aj v inkludovaných šablonách.
- dakota
- Člen | 148
V najnovšej revízii NetteFramework-2.0dev z 15.11. to nejde.
Vo vrátenom JSON chýba premenná snippets.
Uvádzam aj zjednodušený kod. Ak je snippet vo vloženej šablone @form.phtml tak sa neprekreslí,
ak ho dam do šablony add.phtml | edit.phtml za kod include tak prekreslenie snippetu funguje v poriadku.
content šablona add.phtml | edit.phtml
{block #content}
{include '@form.phtml'}
inkludovaná šablona @form.phtml
javascript - jQuery
...
{snippet person}
... {$person->name} ...
{/snippet}
...
v presenteri
public function handlePerson($person_id)
{
$this->template->person = ... // načitanie z databázy
$this->invalidateControl('person');
}
Vyskušal som osobitne v inej šablone jednoduchý snippet či nerobím chybu niekde ja, ale tiež nefunguje snippet ak je vo vloženej šablone:
{snippet time}{=time()}{/snippet}
$this->invalidateControl(‚time‘)
Editoval dakota (15. 11. 2010 8:36)
- David Grudl
- Nette Core | 8227
Aha, už rozumím. Akorát mě nenapadá, jak to řešit, protože
{block #content}
se nevykonává a tudíž ani
{snippet person}
se nedohledá. Popřemýšlím.
- romansklenar
- Člen | 655
Není podmínkou, že snippet musí být uvnitř includované šablony.
I když snippet obaluje makro {include}
, tak se nic neincludne
(makro se nevykoná). Ve vráceném payloadu je pak jen
<div></div>
.
# show.phtml
{snippet}
<div>{include 'members.phtml'}</div>
{/snippet}
Nette e1a3fa8 released on 2010–11–15, PHP 5.3.3
- arron
- Člen | 464
romansklenar napsal(a):
Není podmínkou, že snippet musí být uvnitř includované šablony. I když snippet obaluje makro
{include}
, tak se nic neincludne (makro se nevykoná). Ve vráceném payloadu je pak jen<div></div>
.
Hehe, tak to vysvetluje to zvlastni chovani, ktere uz par dni pozoruju, ale zatim jsem se nepustil do toho to resit…
Mno ale to asi neni uplne dobre, ze se to takhle chova…snad Davida napadne nejaka spasna myslenka, ja se sice kouknu do implementace, ale pochybuju ze pochopim, jak to vlastne funguje :-D
- dakota
- Člen | 148
KillPrd napsal(a):
Jde to nějak řešit jinak než se vyřeší tenhle bug?
Zatiaľ používať snippet len v content šablone a nedávať ho do inkludovanej šablony.
V prípade:
{block #content}
{include '@form.phtml'}
ak je snippet vo @form.phtml a @form.phtml sa používa pre action add aj edit, tak si v action add a tiež action edit nastaviť $this->setView(‚form.phtml‘); a doplniť do form.phtml {block #content}
Editoval dakota (21. 12. 2010 9:05)
- Chbox
- Člen | 125
KillPrd napsal(a):
Jde to nějak řešit jinak než se vyřeší tenhle bug?
Taky jsem se s tím teď mořil a naštěstí jde to obejít dedičností
šablon, kde si udělaš pro danný presenter nějakou master šablonu která
musí zase dědit od hlavního layoutu. Do ní hodíš ten obsah toho půvpdně
includovaného souboru (předpokládám, že je to nějaký společný kód pro
více pohledů, např. interní menu presenteru) a zbytek šablon extenduješ na
týhle šabloně.
P.S.: Nezapomeň zapsat název šablony do uvozovek.
{layout '../@layout.latte'} //v dokumentaci se uvádí zápis bez uvozovek
- bojovyletoun
- Člen | 667
Nebude problém právě v tom, že nette se nemá jak dostat k blokům, které jsou v include? Zkoumá při invalidaci snippetu i ty snippety které jsou ve vřazených blocích(include)..
PS:
- když mám top šablonu (která nedědí) a chci v ní blok pouze definovat a nikoliv i zároveň vypsat, jak to udělám?
- Co v dokumentaci znamená „Každá stránka musí definovat všechny bloky, které layout makrem {include} načítá (a sám je nedefinuje).“
- bojovyletoun
- Člen | 667
1). nemohu ho nechat prázdný(možná jsem špatně použil slovo defonovat), když chci, aby v něm byl nějaké obsah. Který pak někde jinde použiju (třeba víckrát, s růzmými paramatry)… Komponenty mi na to přijdou nevhodné (kvůli problém v šabloně se „vracet“ zpátky" do php a presenterům).
Taky by to šlo vyřešit použitím include v layoutu a definicí toho bloku v child šabloně. Jenže mi to přijde nepohodlné.
- Chbox
- Člen | 125
no, musí se u toho docela přemejšlet :-) ale asi myslíš tohle, ne?
https://latte.nette.org/cs/tags#…
- honzajavorek
- Člen | 57
Koukám, že na GitHubu má ten bug nejvíc hlasů. Pohlo se to někam? Taky mi to dnes večer přistřihlo křidýlka :(
- dakota
- Člen | 148
funguje:
{snippet members}
<div>{include 'members.phtml'}</div>
{/snippet}
snippet umiestnený v inkludovanej šablone:
// šablona add.phtml
{block #content}
{include '@form.phtml'}
// šablona @form.phtml
{snippet person}
... {$person->name} ...
{/snippet}
zatial nefunguje
Editoval dakota (3. 6. 2011 18:54)
- Filip Procházka
- Moderator | 4668
A není čistě náhodou, přesně na tohle
{includeblock '@form.phtml'}
?
- Neklan
- Člen | 21
David Grudl napsal(a):
Mohlo by pomoci invalidovat snippet, v němž je includeblock.
No ale to nic nevyřeší, ono funguje obnovení celé includnuté šablony, ale když potřebuji v šabloně jen nějaký menší kus takto znovunačíst, tak jsem nahranej. Dá se to tedy nějak obejít, nebo vyřešit, aby to fungovalo?
- crempa
- Člen | 198
nemuzu si pomoct ale nefunguje me ani
{snippet members}
<div>{include 'members.phtml'}</div>
{/snippet}
pokud je umisten v sablone komponenty, pri klasickem dotazu vse OK, pri ajaxu a invalidaci cele komponenty se snippet vyrenderuje bez includu… (posledni dev. verze Nette)
Editoval crempa (27. 6. 2011 10:39)
- stenly
- Člen | 6
crempa napsal(a):
nemuzu si pomoct ale nefunguje me ani
{snippet members} <div>{include 'members.phtml'}</div> {/snippet}
pokud je umisten v sablone komponenty, pri klasickem dotazu vse OK, pri ajaxu a invalidaci cele komponenty se snippet vyrenderuje bez includu… (posledni dev. verze Nette)
Mám naprosto stejný problém máte někdo řešení? Zkoušel jsem {include ‚soubor‘} i čistě php include a taky nezabralo
- crempa
- Člen | 198
22 napsal(a):
dědičnost šablon to řeší..
Muzu se zeptat jak to resi v pripade, ze jeden soubor includuju v jedne sablone vicekrat a pokazde s jinymi parametry a navic v cyklu tudiz dopredu nemuzu stanovit konkretni oznaceni bloku?
priklad: v bunce datagridu potrebuju includovat nejaky komplexnejsi vypis dany samostatnou sablonou…
Editoval crempa (2. 9. 2011 19:15)
- polonium
- Člen | 22
Čistě teoreticky.
Bylo by možný obejít tenhle bug tím, že by ten soubor, který chceme
includovat
načetli v presenteru? Vlastně by to mohlo fungovat na
podobném principu jako se načítají views
.
Tohle:
{snippet members}
<div>{include 'members.phtml'}</div>
{/snippet}
Udělat takhle:
{snippet members}
<div>{block members}</div>
{/snippet}
A v presenteru:
$this->template->members = $template->setFile('members.phtml');
Napadlo mě to když jsem koukal do dokumentace na práci s ajaxem. Hned nad popisem invalidace snippetu se píše o html šablonách.
- crempa
- Člen | 198
@22 dik za zajimavy napad, sice to asi odporuje KISS a vsem tem
podobnym zkratkam :) ale reseni by to asi bylo…
rikam asi, protoze tomu brani dalsi bug zminovany Ondrejem, ja si do te
komponenty nejsem schopen poslat vubec zadne parametry, navic pri ajaxu havaruje
i volani jine metody nez render()
- Nox
- Člen | 378
@**OndřejMirtes** je to ještě aktuální? V nové verzi Nette mám
normálně {control someControl:neco $argument, $argument}
a to
třeba uvnitř jinýho controlu a funguje to i s AJAXem bez problému (vím
že to dřív nejelo)
edit: no fakt to asi nejede, asi jsem řešil něco trochu jiného
Editoval Nox (30. 9. 2011 14:03)
- crempa
- Člen | 198
Ahoj, nastin docasneho (funkcniho) reseni k diskusi – tvorba vlastniho
makra ainclude
, ktere se pouzije namisto klasickeho includu
do beforeRender() v nejakem base presenteru prasknout
$latte = new LatteFilter();
$t = new FileTemplate();
$t->setCacheStorage(new FileStorage(Environment::getVariable('tempDir')));
$t->presenter = $this;
$t->user = $this->getUser();
$t->baseUri = $t->baseUrl = rtrim(Environment::getHttpRequest()->getUrl()->getBaseUrl(), '/');
$t->registerFilter($latte);
$t->registerHelperLoader('TemplateHelpers::loader');
$this->template->it = $t;
$macroSet = new MacroSet($latte->parser);
$macroSet->addMacro(
'ainclude',
'$it->setFile(Environment::expand(%node.word)); $it->render()'
);
$this->template->registerFilter($latte);
a v sablone pak uz jen klasicky
{ainclude '%appDir%/templates/submenu.phtml'}
kod zatim neresi vlozeni atributu do sablony, ale to by nemel byt problem dopsat, pouziti v komponente je obdobne jen se to vrazi do nejakeho render v default controlu treba
uvedene reseni me funguje, ale strelil jsem to znacne od boku takze prosim o pripadnou revizi nebo navrhy jak to doladit :)
- Achse
- Člen | 44
@crempa: díky zdá se že to funguje celkem dobře jediné co jsem musel udělat bylo:
new LatteFilter()
→ new \Nette\Latte\Engine()
Nejsem si jistý korektností této úpravy. Mám totiž potíže uvnitř
šablony kterou vkládám s věcmi jako jsou proměnné, ty se zdají vyřešit
přes $presenter->variable
, s čím si však nevím rady je
Notice: Undefined variable: control
({control registrationForm}
)
Kde dělám prosím chybu?
Stahl jsem nejnovější dev verzi a ozkoušel, stejné. Nette Framework 2.0-beta (revision 7f6bc92 released on 2011–12–07)
Editoval Achse (7. 12. 2011 15:18)
- crempa
- Člen | 198
namespace revize drive uvedeneho reseni vcetne funkcnich parametru, jedine omezeni oproti originalu je nefunkcni makro control ve kterem je ten bug zda se… netestovano na poslednim monster updatu :-)
pouziti uplne stejne jako u klasickeho include, az bude bug opraven staci udelat v celem projektu rename z {ainclude na {include
$latte = new Nette\Latte\Engine();
$templ = new \Nette\Templating\FileTemplate();
$templ->setCacheStorage(new \Nette\Caching\Storages\FileStorage(Environment::getVariable('tempDir')));
$templ->presenter = $this;
$templ->user = $this->getUser();
$templ->baseUri = $templ->baseUrl = rtrim(Environment::getHttpRequest()->getUrl()->getBaseUrl(), '/');
$templ->registerFilter($latte);
$templ->registerHelperLoader('TemplateHelpers::loader');
$this->template->it = $templ;
$macroSet = new Nette\Latte\Macros\MacroSet($latte->parser);
$macroSet->addMacro(
'ainclude',
'
$path = pathinfo($presenter->template->getFile());
$path = $path["dirname"] . "/" . %node.word;
$it->setFile($path);
$it->setParams(%node.array);
$it->render();
'
);
$this->template->registerFilter($latte);
Editoval crempa (17. 12. 2011 22:42)
- henry
- Člen | 1
Ahojte!
právě jsem dořešil obdobný problém, kdy se nepřenášela includovaná šablona ve snippetu.
Šablona
{snippet list}
{for $i = 0; $i < count($list); $i++}
<h1>Agáta Hanychová se otrávila jídlem. Celé dny jenom zvrací</h1>
{include @item.latte item => $list[$i]}
{/for}
{/snippet}
Problém se projevil tím, že AJAXem se přenesla ve snippetu jen
h1
, ale už ne obsah šablony @item.latte
Mohla za to v presenteru zapnutá invalidace snippetu, který v šabloně neexistoval (v minulosti byl smazán)
Presenter
<?php
...
$this->invalidateControl('list');
$this->invalidateControl('header');//Invalidace neexistujícího (odstraněného) snippetu
...
?>
Stačilo ji tedy jen odstranit
<?php
...
$this->invalidateControl('list');
...
?>
A všechno začalo fungovat.
- hrach
- Člen | 1838
Možné řešení jsem odeslal jako pull: https://github.com/…tte/pull/556
{snippetRunner list}
{for $i = 0; $i < count($list); $i++}
{include @item.latte item => $list[$i]}
{/for}
{/snippetRunner}
Sablona @item.latte muze obsahovat co chces. Invalidovat je treba ale
i list
! Ten se nicmene do prohlizece neodesle!!!
→ byl by totiz prazdny a automaticka obsluha by tak vymazala obsah daneho
elementu. Snippety v sablone pak budou fungovat, jak se predpoklada.