Chovanie a dedičnosť blokov v Latte

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

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Omyl. Blok se vždy vykresluje a pak se může volat znova. Okamžitě-se-nevykreslující blok se dělá makrem {define}.

Cifro
Člen | 245
+
0
-

Ani {define} nepomáha… viď https://github.com/…9c8bc31d793f

redhead
Člen | 1313
+
0
-

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).

Cifro
Člen | 245
+
0
-

redhead napsal(a):

A nebo to hoď na github jako bug, on se k tomu snad David vyjádří (odkaž ho sem, ať vidí i use-case).

Jop, to je dobrý nápad.

Filip Procházka
Moderator | 4668
+
0
-

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žíš.