Zavináčová magie v praxi
#1 před 3 lety
- Panda
- Nette guru

- Registrovaný: 4. 7. 2008
- Příspěvky: 573
Zavináčová magie v praxi
Protože spousta lidí, převážně těch začínajících, má problémy s pochopením a aplikací zavináčové magie, rozhodl jsem se sepsat tento krátký textík, který, doufám, alespoň některé mýty kolem zavináčů kousek poodhalí a mnohým usnadní bádání.
Nejprve krátký „teoretický“ úvod.
Co to vlastně je zavináč v šabloně? K čemu slouží?
Pokud nepoužíváme AJAX, nemá pro nás zavináč žádný význam. S prvním AJAXovým požadavkem ale přichází otázka: co budě vlastně při takovém požadavku potřeba vykreslovat? Na tuto otázku odpovídají snippety a k tomu jim napomáhají zavináče.
Zavináč umožňuje vykonání příkazu v šabloně nezávisle na tom, zda se šablona vykresluje pro normální požadavek, nebo pro AJAXový. Při AJAXovém požadavku šablona bez zavináčů a snippetů nevykreslí vůbec nic – její obsah se v podstatě přeskočí. Pokud přidáme snippet, tak se jeho obsah bude vykreslovat v závislosti na tom, zda je invalidován (Control::invalidateControl), případně zda je invalidována komponenta, které šablona náleží (v takovém případě se tedy vykreslují všechny snippety z šablony).
Každá šablona se překládá do PHP kódu. Všechny struktury a
vymoženosti, které nám poskytuje CurlyBracketsFilter, lze tedy
zapsat pomocí klasického PHP (ovšem kdo by se s tím psal, že?). Snippet
v podstatě není nic jiného, než podmínka, která kontroluje, zda se
snippet má nebo nemá vykreslit. Ale pokud se při AJAXovém požadavku obsah
šablony v podstatě přeskočí, jak se PHP dostane k podmínce? Pokud je
snippet zapsaný přímo v šabloně, tak to není žádný problém, snippet
si zajistí sám, aby ho bylo vidět. Jak ho ale PHP najde, pokud bude
uzavřený do nějaké podmínky, bloku, cyklu nebo komponenty? Nijak, musí se
mu pomoci. A nyní vstupují na scénu zavináče a vychutnávají si svůj
moment slávy…
Jak již bylo řečeno, zavináče umožní vykonání příkazu nezávisle na tom, zda se jedná o AJAXový požadavek, nebo normální. Příkaz se vykoná vždy. A právě to slouží k tomu, aby se PHP parser „probojoval“ až ke snippetu. V podstatě v tom tedy žádná magie není, stačí dát zavináč kolem všech řídicích struktur, bloků, komponent a vkládání šablon, ve kterých máme snippety. Jednoduché, že?
O generování kódu šablony jsem již psal. Pokud jste tedy zvědaví
na některé podrobnosti o tom, co se děje za
CurlyBracketsFilterem, podívejte se do jiného vlákna: http://forum.nette.org/…iewtopic.php?….
Kam tedy zavináč patří?
- Před
{include}, který vkládá obsah se snippety, ať už se jedná o blok nebo šablonu. Jeden takový bývá v šabloně s layoutem, většinou{include $content}, případně{include #content}u nových šablon. Zavináč se vždy píše před první složenou závorku:@{include #content}. - Před vykreslení komponenty, která obsahuje snippety, ať
už pomocí makra
{control ...}(popř.{control ...}, které je aliasem pro{widget}), nebo přímého volání vykreslovací funkce:{!$myControl->render()},{!$control['myControl']->render()}. - Před řídící struktury, ve kterých se nacházejí
snippety. Pokud má struktura více částí, například
{if} ... {else} ... {/if}, musí se zavináč vložit před každou její část. Zavináče se týkají následujících maker:{if},{elseif},{else},{/if},{ifset},{elseifset},{/ifset},{ifCurrent},{foreach},{/foreach},{for},{/for},{while},{/while},{continueIf},{breakIf},{cache},{/cache}. Při vnořování struktur je potřeba vložit zavináč na každou úroveň. - Před definice bloků se snippety:
{block ...} ... {/block}. Platí stejné pravidlo jako pro řídicí struktury – zavináč patří před všechny části. Pokud se jedná o poslední blok v šabloně a za jeho obsahem už nic není, můžeme ukončení{/block}vypustit, takže zavináč bude pouze na jeho začátku. - Před příkazy, které nějakým způsobem ovlivňují obsah,
který ve snippetu vykreslujeme. Jedná se například o makra
{assign}a{default}, ve kterých nastavujeme proměnné pro snippet. Může se také jednat o PHP kód vložený v{? ...}nebo volání funkcí s vedlejšími účinky.
Kam naopak zavináč nepatři?
- Před součásti makra
{snippet ...} ... {/snippet}. Pokud se PHP probojuje až k snippetu, řídí si snippet své vykreslování už sám na základě zmíněné invalidace. - Do obsahu snippetu. Uvedení zavináče ve snippetu může způsobit vygenerování kódu s úplně jinou logikou, než která byla původně zamýšlena.
- Před vykreslení komponent, jejichž vykreslování není založeno
na Nette šablonách. Zavináč před takovým vykreslováním by
způsobil, že se nám komponenta bude vykreslovat vždy. Jednou takovou
komponentou je i
FormsConventionalRenderernebo rendererem od něj odvozeným..
Příklad
Pro názornost jeden lehce komentovaný příklad. Jsou použity nové šablony a jakákoliv podobnost příkladu se skutečností je čistě náhodná.
@layout.phtml:
{* ... *}
<div id="content">
@{include #content}
</div>
{* ... *}
<presenter>/<action>.phtml:
{* nastavujeme titulek stránky pro layout
- není potřeba zavináč *}
{assign title => 'Nadpis'}
{* definujeme blok se snippety - @ *}
@{block #content}
{* komponenta používá šablonu se snippety - @ *}
@{control actionList}
{* před snippet zavináč nepatří *}
{snippet info}
{ifset $showInfo}
{* komponenta sice používá šablonu se snippety,
ale uvnitř snippetu nepoužíváme zavináče! *}
{control infoBar}
{/if}
{/snippet}
@{if count($items) > 0}
<ul>
{* vytváříme proměnnou, kterou použijeme ve snippetu - @
v cyklu foreach můžeme sice použít objekt $iterator,
ale toto je pouze demonstrace myšlenky *}
@{assign counter => 0}
@{foreach $items as $item}
@{if $item->visible}
{snippet item$item->id li} {* <li id="item$item->id"> *}
{* každý snippet musí mít jedinečné jméno,
proto do jeho názvu vkládáme $item->id *}
{= ++$counter}: {$item->title}
{snippet} {* </li> *}
@{/if}
@{/foreach}
</ul>
{* v této podmínce nemáme snippety,
zavináče nejsou potřeba *}
{if $orderingAllowed}
<div class="foo">
<a href="{link editPositions}">Upravit pořadí položek</a>
</div>
{/if}
@{/if}
{* formulář s ConventionalRenderer - bez zavináče! *}
{control createNewItemForm}
{* koncový @{/block} vypouštíme *}
Na závěr bych si dovolil jedno malé upozornění: špatné umístění zavináčů může vést k velmi nepříjemným komplikacím, od neškodného nepřekreslování snippetu, přes vykreslení snippetu na samotný začátek stránky až po vygenerování kódu s úplně jinou logikou, než bylo původně zamýšleno. Proto buďte při jejich používání opatrní a pokud si s něčím nebudete jisti, nebojte se zeptat. Minimálně já vždy rád pomohu…
Pokud jsem na něco zapomněl, tak se omlouvám. Ozvěte se – doplníme, upravíme, poladíme.
Pomůžeš-li jednomu člověku, pomůžeš tím celému světu.
– Talmud
#2 před 3 lety
- pmg
- Nette guru

- Registrovaný: 30. 8. 2007
- Příspěvky: 451
Re: Zavináčová magie v praxi
Tomuto návodu zbývá už jen popřát, aby co nejrychleji zastaral. :-)
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
#3 před 3 lety
- crempa
- Nette guru

- Registrovaný: 21. 8. 2008
- Příspěvky: 208
Re: Zavináčová magie v praxi
Diky za navod, ale nema uz byt nahodou zavinacova magie pohrbena? Osobne porad jeste cekam na nejakou finalni verzi novych sablon + dokumentaci od Davida.. neprehlidnul sem to nekde? :-)
#4 před 3 lety
- Panda
- Nette guru

- Registrovaný: 4. 7. 2008
- Příspěvky: 573
Re: Zavináčová magie v praxi
Zavináče ještě potřeba jsou a minimálně do další stabilní verze to bude aktuální. Ale asi by to chtělo vyjádření Davida, jak to s nimi je a bude.
Pomůžeš-li jednomu člověku, pomůžeš tím celému světu.
– Talmud
#5 před 3 lety
- dRaGen
- Člen

- Registrovaný: 1. 8. 2009
- Příspěvky: 104
Re: Zavináčová magie v praxi
No co sem koukal na záznam z (před)poslední soboty o těch šablonách, tak bylo řečeno že je to mrtvá technologie a co sem z toho vyvodil, tak v novejch šablonách by to mělo bejt vyřešený jinak než prerušováním ifu(@) při vykreslování
#6 před 3 lety
- Panda
- Nette guru

- Registrovaný: 4. 7. 2008
- Příspěvky: 573
Re: Zavináčová magie v praxi
Mno nové šablony pravděpodobně ještě nejsou úplně hotové, protože zavináče nám ve zdrojáku stále straší, bez nich AJAX nefunguje a žádnou alternativu jsem nenašel. Pokud jsem něco přehlédl, opravte mě…
Pomůžeš-li jednomu člověku, pomůžeš tím celému světu.
– Talmud
#7 před 3 lety
- jasir
- Nette guru

- Registrovaný: 4. 12. 2008
- Příspěvky: 768
Re: Zavináčová magie v praxi
Zavináče jsou stále potřeba. Díky za článek, je to moc pěkný souhrn.
#8 před 3 lety
- rokerkony
- Člen

- Registrovaný: 29. 7. 2008
- Příspěvky: 137
Re: Zavináčová magie v praxi
něco takového tu opravdu chybělo!!! moc děkujem :-) konečně ucelenej pohled na zavináče :-)
#9 před 3 lety
- Jakub Šulák
- Nette guru

- Registrovaný: 26. 8. 2008
- Příspěvky: 253
Re: Zavináčová magie v praxi
Zdravím s pár měsíčním odstupem, bych se rád zeptal, jak to vypadá s odstraněním „zavináčové magie“ z Nette? Je to moje malá noční můra. Mám aplikaci, ke které kodéři píší jen templates. Zavináče jim ale dělají stále problémy…
#10 před 3 lety
- Honza Marek
- Moderator

- Registrovaný: 31. 3. 2007
- Příspěvky: 1632
Re: Zavináčová magie v praxi
David má silnou motivaci dodělat to před 17. říjnem, aby o zavináčích nemusel přednášet.
A také se podíváme na několik žhavých novinek v Nette Frameworku.
Editoval Honza M. (5. 10. 2009 17:17)
Online
#11 před 3 lety
- Jakub Šulák
- Nette guru

- Registrovaný: 26. 8. 2008
- Příspěvky: 253
Re: Zavináčová magie v praxi
:-)
Tak to se těším, zda se mu to podaří.
#12 před 2 lety
- Matúš Matula
- Člen

- Registrovaný: 3. 9. 2009
- Příspěvky: 167
Re: Zavináčová magie v praxi
ahoj, mam nasledovnu sablonu komponenty
{snippet content}
{if $count > 0}
{foreach $jokes as $joke}
{control rating:thumb $joke->rating, $joke->id, $joke->user_rated}
{/foreach}
{/if}
{/snippet}
sablona subkomponenty rating je obaleny v {snippet} znacke.
problemom zrejme je, ze sa program nedostane k prekresleniu komponenty rating,
pretoze rodicovsky snippet content nie je invalidovany. signal
subkomponenty sa spracuje, akurat sa neprekresli obsah.
Podla vyssie uvedeneho navodu, by to malo fungovat, nie?
Vdaka za odpoved
#13 před 2 lety
#14 před 2 lety
- Panda
- Nette guru

- Registrovaný: 4. 7. 2008
- Příspěvky: 573
Re: Zavináčová magie v praxi
K moderátorům: snippety stále nejsou pořádně vyřešené, nestálo by za zvážení klepnout tomuto tématu „sticky“ (zvárazněno)?
Pomůžeš-li jednomu člověku, pomůžeš tím celému světu.
– Talmud
#15 před 2 lety
- Majkl578
- Moderator

- Registrovaný: 2. 5. 2009
- Příspěvky: 665
Re: Zavináčová magie v praxi
Panda napsal(a):
K moderátorům: snippety stále nejsou pořádně vyřešené, nestálo by za zvážení klepnout tomuto tématu „sticky“ (zvárazněno)?
Dobrý nápad, hotovo.
Debian experimental/sid 64 bit (kernel 3.3.0-trunk-amd64), PHP 5.4 (FPM), nginx, MySQL 5.5
„There are 10 types of people in this world. Those who understand binary and those who don't.“
#16 před 2 lety
- v6ak
- Člen

- Registrovaný: 1. 5. 2008
- Příspěvky: 194
Re: Zavináčová magie v praxi
Pro atributy n: (např. n:if) tu asi nejsou zavináče, že?
#17 před 2 lety
- Jan Tvrdík
- Nette guru

- Registrovaný: 13. 4. 2008
- Příspěvky: 1262
Re: Zavináčová magie v praxi
O ničem takovém bohužel nevím.
#18 před 2 lety
- Majkl578
- Moderator

- Registrovaný: 2. 5. 2009
- Příspěvky: 665
Re: Zavináčová magie v praxi
Pokud je mi známo, zavináčový problém by měl být vyřešen do vydání bety 1.0 (19. září 2010).
Debian experimental/sid 64 bit (kernel 3.3.0-trunk-amd64), PHP 5.4 (FPM), nginx, MySQL 5.5
„There are 10 types of people in this world. Those who understand binary and those who don't.“
#19 před 2 lety
- na1k
- Nette guru

- Registrovaný: 18. 2. 2008
- Příspěvky: 277
Re: Zavináčová magie v praxi
Co takhle dát tohle téma (odkaz na něj?) jako „sticky“ i do sekce AJAX?
#20 před 2 lety
- Jan Tvrdík
- Nette guru

- Registrovaný: 13. 4. 2008
- Příspěvky: 1262
Re: Zavináčová magie v praxi
Spíš ho chce zahrnout do dokumentace pro Nette 0.9.x-
#21 před rokem
- neznalek
- Člen

- Registrovaný: 12. 1. 2011
- Příspěvky: 64
Re: Zavináčová magie v praxi
Co delam spatne kdyz mam:
´@{include $foo}´
A zavinac se mi vykresli pred include?
Editoval neznalek (8. 3. 2011 16:34)
#22 před rokem
- bojovyletoun
- Nette guru

- Registrovaný: 6. 10. 2010
- Příspěvky: 672
Re: Zavináčová magie v praxi
tady 7.10.2009 zavináče se už nepoužívají
Nette 2dev from github/Netbeans 7.0.1/(Tortoise)git/
Apache 2.4/fcgid/PHP 5.3.9+xdebug+wincache