Chovanie a dedičnosť blokov v Latte
- Cifro
- Člen | 245
Prekvapilo ma chovanie blokov v latte, kde som očakával, že keď podmienka nevyhovuje tak blok sa ani „neinicializuje“. Príklad: Majme v layoute v hlavičke nejaký globálny slajder s obrázkamy, ktorý sa zobrazuje na každej stránke, ale v admine je možné nastaviť pre konkrétnu stránku iný slajder s inými obrázkamy. Využil som dedičnosť šablón a bloky ale je tam ale…
layout.latte
{block slider}
{* v slider.latte sa len iteruje a vypisujú obrázky do <li> *}
{include slider.latte slides => (data pre globálny slider)}
{/block}
page.latte
{if $options->overrideGlobalSlider}
{block slider}
{include slider.latte slides => (data pre lokálny slider)
{/block}
{/if}
Očakával som, že keď podmienka nevyhovuje tak s blokom sa nič nerobí a vykreslí sa ten slider v layoute, ale vykreslil sa ten z page.latte i keď podmienka neplatila. Dáta pre podmienku sa vyhodnocujú správne. Pozeral som na definíciu makra block, a asi to bude tým, že je tam premenná $namedBlocks do ktorej sa ukladajú najdené bloky pri parsovaní a nepozerá sa na podmienku.
Musel som to ohackovať takto:
{if $options->overrideGlobalSlider}
{var $localSlider = 'slider'}
{else}
{var $localSlider = 'someRandomNotImportantString'}
{/ifset}
{block $localSlider}
{include slider.latte, slides => (data pre lokálny slider)}
{/block}
Je to očakávané chovanie blokov alebo je niečo zlé?
Editoval Cifro (26. 8. 2011 11:27)
- Filip Procházka
- Moderator | 4668
Bloky se vyzobají ze šablony a definují se mimo všechny struktury jako funkce. Pak se v šabloně na různých místech už jen volají. Takže blok se nadefinuje vždy, ale nemusí se vykreslit.
- Cifro
- Člen | 245
Tak blok sa nadefinoval a aj sa vykreslil, čo by nemal :/
Trochu som sa v tom vŕtal, a prišiel som na to, že možno sa zle resetuje pointer…
layout
// definicia bloku
if (!function_exists($_l->blocks['slider'][] = '_lb810e62f073_slider')) { function _lb810e62f073_slider($_l, $_args)
// volanie bloku
if (!$_l->extends) { call_user_func(reset($_l->blocks['slider'])
page
// definicia
if (!function_exists($_l->blocks['slider'][] = '_lbf1b6bda84d_slider')) { function _lbf1b6bda84d_slider($_l, $_args)
// volanie
// tu malo byť podľa mňa end() namiesto reset()
if ($options->overrideGlobalSlider): call_user_func(reset($_l->blocks['slider']),...
Update: tá funkcia end()
nezaberá :/ Pretože
v poli $_l->blocks[‚slider‘] v danej chvíli je iba jeden prvok
Editoval Cifro (26. 8. 2011 11:35)
- Cifro
- Člen | 245
Urobil som testovacie demo https://github.com/…-Blocks-Test
Vyskušal som aj includeblock
makro a s ním to funguje, len
v includovanej šablóne musí byť {extends layout…}
- redhead
- Člen | 1313
Já vím, že to fungovat nebude, jen jsem vás opravil, že se to vykresluje
okamžitě. Ono jde o to, že {block}
(a asi tedy i
{define}
) je vždy provedeno. Vnoření do jiných maker by podle
mě mělo a v minulosti myslím, že i zobrazovalo (ale jistý si
nejsem) chybu.
A nebo to hoď na github jako bug, on se k tomu snad David vyjádří (odkaž ho sem, ať vidí i use-case).
- Filip Procházka
- Moderator | 4668
Bloky se vykreslí vždy, pokud šablona ale rozšiřuje jinou
{extends layout.latte}
pak se vykreslují bloky podle toho, jak je
volá šablona, která je rozšiřována. Tohle chování je podle mě naprosto
v pořádku.
To o co se snažíš bych přirovnal k definování tříd v podmínkách. Prostě se to nedělá. Bloky jsou základní řídící struktura, nadřazená podmínkám. Najdi jiný způsob jak docílit to, o co se snažíš.