Šablona a layout – renderování v opačném pořadí

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8218
+
0
-

Je to už neuvěřitelných dva a půl roku, co jsem popisoval jeden filtr šablon, který se nakonec do distribuce nedostal. Důvodem je hlavně odklon od tehdy perspektivního XML k HTML5 a ztížené podmínky zpracování HTML v PHP.

Protože zatím nemám odpovídající náhradu, použil jsem něco, co vlastně považuju za naprostou zhovadilost, a tím je populární rozdělení šablony na layout + content :-)

Nedostatky dělení na layout a obsah se projeví už u těch nejjednodušších webů. Pokud chceme mít v <title> v layoutu stejný titulek jako v <h1> obsahové šablony, musíme titulek nastavit jako parametr šablony v presenteru. To stejné platí pro meta tagy, skripty a styly, jenž jsou specifické jen pro určitou stránku. Problém je zkrátka v tom, že layout se s každou stránkou také mění a přesouvat kvůli tomu části šablony do presenteru je nevyhovující.

Jak věc řešit? Jeden návrh bych měl. Nejprve je třeba, aby v době renderování layoutu byl již vyrenderován content. K tomu vede celkem jednoduchá úprava, kterou jsem se rozhodl v revizi 174 zveřejnit. DEPRECATED

Poté je možné v layoutu použít proměnnou…

// @layout.phtml
<head>
	<title>{$title}</title>
</head>

…kterou nastavíme v content-šabloně:

// default.phtml
{? $template->title = 'Editace položky'}

<h1>{$template->title}</h1>
...

CurlyBracketsFilter nabízí i syntax:

// default.phtml
{assign $title 'Editace položky'}

<h1>{$title}</h1>
...
LM
Člen | 206
+
0
-

SnippetHelper::$outputAllowed = FALSE by se měl nastavovat ještě před preRenderem, protože teď nefunguje ajax v presenteru.

David Grudl
Nette Core | 8218
+
0
-

LM napsal(a):

SnippetHelper::$outputAllowed = FALSE by se měl nastavovat ještě před preRenderem, protože teď nefunguje ajax v presenteru.

Zkus být konkrétnější, co přesně nefunguje?

LM
Člen | 206
+
0
-

Pokud mám v šabloně (view presenteru, ne šablona komponenty) snippet, tak v metodě Presenter::renderTemplate kde se volá $template->content->preRender() dojde k tomu že SnippetHelper::$outputAllowed bude TRUE i při Ajax režimu (pak to končí na: InvalidStateException: Cannot send header after HTTP headers have been sent (output started at /var/www/libs/Nette/Templates/Template.php:151).), podmínka která tu hodnotu mění je až po preRenderu.

Editoval LM (28. 12. 2008 21:46)

veena
Člen | 98
+
0
-

David Grudl napsal(a):

Je to už neuvěřitelných dva a půl roku, co jsem popisoval jeden filtr šablon, který se nakonec do distribuce nedostal. Důvodem je hlavně odklon od tehdy perspektivního XML k HTML5 a ztížené podmínky zpracování HTML v PHP.

Protože zatím nemám odpovídající náhradu, použil jsem něco, co vlastně považuju za naprostou zhovadilost, a tím je populární rozdělení šablony na layout + content :-)

Nedostatky dělení na layout a obsah se projeví už u těch nejjednodušších webů. Pokud chceme mít v <title> v layoutu stejný titulek jako v <h1> obsahové šablony, musíme titulek nastavit jako parametr šablony v presenteru. To stejné platí pro meta tagy, skripty a styly, jenž jsou specifické jen pro určitou stránku. Problém je zkrátka v tom, že layout se s každou stránkou také mění a přesouvat kvůli tomu části šablony do presenteru je nevyhovující.

Jak věc řešit? Jeden návrh bych měl. Nejprve je třeba, aby v době renderování layoutu byl již vyrenderován content. K tomu vede celkem jednoduchá úprava, kterou jsem se rozhodl v revizi 174 zveřejnit.

Poté je možné v layoutu použít proměnnou…

// @layout.phtml
<head>
	<title>{$title}</title>
</head>

…kterou nastavíme v content-šabloně:

// default.phtml
{? $template->title = 'Editace položky'}

<h1>{$template->title}</h1>
...

CurlyBracketsFilter nabízí i syntax:

// default.phtml
{param $title 'Editace položky'}

<h1>{$title}</h1>
...

Další možností je využít v layoutu SimpleXML (což má ovšem řadu úskalí):

// @layout.phtml
<head>
	<title>{$content->toXml()->h1}</title>
</head>

Pár nápadů.

Tohle mi přijde dost magické nastavovat proměnou pro soubor, který si tento soubor teprve inkluduje.

Ono by možná místo konceptu „layoutu“ bylo lepší použít dedění šablon. Podobně jako je to u presenterů. Vizuální rozložení stránek tomu dědění také odpovídá.

Pak by to mohlo vypadat třeba takhle:

// base.phtml
{param $title 'Editace položky'}
<head>
	<title>{$title}</title>
</head>

{block obsah}
<h1>Nejaky obecny H1</h1>
...
{/block}

…kterou nastavím v content-šabloně:

// default.phtml
{extends 'base.html'} // dědí šablonu z base.html

{block obsah} // zde přepíšeme vnitřek zděděného bloku
<h1>{$title}</h1>
{/block}
...

Ohledně toho zpracování (X)HTML v PHP. Supr by bylo mít něco jako jQuery selector. Voila http://code.google.com/p/phpquery/
Ale používá to PHP5 DOM extension a Zend, takže to možná neni úplně ono.

S tím PHP parserem, pokud ten DOM v PHPku má stále ty uvedené chyby, co si nalezl, tak pak už zbývá jen jediná možnost napsat vlastní parser %-( Našel sem sice ještě tohle: http://sourceforge.net/…mplehtmldom/
Ale nevim, jak to zvládá všechny možný možnosti.

Ondrej
Člen | 110
+
0
-

veena napsal(a):

Ono by možná místo konceptu „layoutu“ bylo lepší použít dedění šablon.

Dedení by bylo super :) Takový přistup jsem použival při šablonovaní přes XSLT. Při přechodu na Nette mi toto chybí :(

Např. v hlavním layoutu mam lévý sloupec, který na Homepage obsahuje něco a podstrance se zobrazí jiný(nebo rozsireny) obsah sloupce podle kontextu podstranky. Takze jen v sablone pro podstranku bych zdědil šablonu Homepage a přepsal block levy sloupec jak popisuje veena.

Jak toto resit nyni v Nette? Napada me jen udelat komponentu(control) levy sloupec, kde by se podle presenteru pridaval obsah i za vyuziti dedeni presenteru.

veena
Člen | 98
+
0
-

Ondrej napsal(a):

Dedení by bylo super :) Takový přistup jsem použival při šablonovaní přes XSLT. Při přechodu na Nette mi toto chybí :(

Teď jak jsem se kouknul do toho starého prvního článku, tak to tak David měl původně v plánu. Rozhodil mu ale sandál právě ten nespolehlivý HTML parser, jestli to chápu dobře.

Ondrej
Člen | 110
+
0
-

veena napsal(a):
Teď jak jsem se kouknul do toho starého prvního článku, tak to tak David měl původně v plánu. Rozhodil mu ale sandál právě ten nespolehlivý HTML parser, jestli to chápu dobře.

jojo, v puvodnim planu se ale pocitalo ze se budou pri dedeni prepisovat primo HTML elementy pojmenovane v id atributu. Tady by pri prepisovani celeho bloku nemusel byt zadny problem pri parsovani za pouziti nette syntaxe {block name}.

David Grudl
Nette Core | 8218
+
0
-

LM napsal(a):

Pokud mám v šabloně (view presenteru, ne šablona komponenty) snippet, tak v metodě Presenter::renderTemplate kde se volá $template->content->preRender() dojde k tomu že SnippetHelper::$outputAllowed bude TRUE i při Ajax režimu (pak to končí na: InvalidStateException: Cannot send header after HTTP headers have been sent (output started at /var/www/libs/Nette/Templates/Template.php:151).), podmínka která tu hodnotu mění je až po preRenderu.

Zkusil jsem to přesunout.

stpnkcrk
Generous Backer | 190
+
0
-

Pokud používám

{param $title 'Titulek stránky'}

Dá se k takovové proměnné potom dostat z presenterů, například v metodě afterRender();? Nepřišel jsem na to jak.

David Grudl
Nette Core | 8218
+
0
-

To se nedá. Ale ber to celé jako spíš návrh, koncept.

David Grudl
Nette Core | 8218
+
0
-

Říkám si, že celý tento koncept zruším.

Byl to experiment.

PetrP
Člen | 587
+
0
-

David Grudl napsal(a):

Říkám si, že celý tento koncept zruším.

Byl to experiment.

O co přesně se zruší?

To že se content vyrenderuje před layoutem, tedy nebude možné nic z tohoto?

Nebo CurlyBrackets syntaxy?

{param $title 'Editace položky'}

Nebo i toto?

{$content->toXml()->h1}

Sám jsem se zatím nedostal k tomu to použít (tedy neznám ty případné problémy), ale chystal jsem se k tomu.

David Grudl
Nette Core | 8218
+
0
-

Chci implementovat jiné a lepší řešení.

phx
Člen | 651
+
0
-

Mozna by nebylo spatne nastinit. Vic hlav vic vi:) A treba driv nez to zacnes implementovat si rekneme „Tudy ne pratele“

LM
Člen | 206
+
0
-

Co třeba takhle: parent template a child template, vlastně je to skoro jak psal veena.

Ondrej
Člen | 110
+
0
-

David Grudl napsal(a):

Nejprve je třeba, aby v době renderování layoutu byl již vyrenderován content. K tomu vede celkem jednoduchá úprava, kterou jsem se rozhodl v revizi 174 zveřejnit. DEPRECATED

Od rev. 187 mi prestalo fungovat logovani SQL dotazu do Firebugu a hlasi mi to chybu, ze hlavicky jiz byly odeslany. Je to tim, ze natazeni polozek z databaze do DataGridu resim az ve fazi renderovani. Konkretne mam v sablone $dataGrid->renderGrid(), ale to uz je pul stranky odeslano do prohlizece a nelze poslat hlavicky pro Firebug. (v rev. 186 to fungovalo, protoze to bylo pred renderovano.)

Zrusena funkce $template->content->preRender(), ktera renderovala content jeste pres samotnym celym renderem, byla dulezita. Je nejaka alternativa? Napadla me jednoducha uprava v presenter::renderTemplate();

<?php
	ob_start(); // vystup pozdrzim v bufferu
	$template->render(); // v ramci render() se mohou posilat dodatecne http hlavicky
        ob_end_flush(); // odeslani bufferu
?>
David Grudl
Nette Core | 8218
+
0
-

Pokusím se k tomu napsat víc. Nejprve shrnutí:

Problém

  • současná realizace Two-Step view pomocí dělení šablon na layout & content je napytel
  • XML je passé, v HTML je problematické detekovat konec elementu, původní řešení https://phpfashion.com/…icke-stranky nelze použít
  • je třeba zajistit zpětnou kompatibilitu

Průzkum terénu

V podstatě všechny systémy kromě Djanga mají velmi podobné pojetí a liší se v provedení, od zmateného po relativně čisté. Django je velmi milým překvapením (díky Veenovi za odkaz), objektové pojetí šablon je fajn, bohužel se tu nejvíc projevuje rozdím mezi PHP a Pythonem a podobné věci řešit v PHP je dost oříšek (slušně řečeno).

Řešení

V původním návrhu Nette se dědičnost realizovala přes HTML elementy <div id="sidebar">...</div>, Django k témuž používá bloky označené značkami {% block sidebar %} ... {% endblock %}. Z pohledu XHTML mi syntax Djanga připadá jako krok zpět (víc psaní, bloky mohou rozříznout elementy), z pohledu HTML to vidím jako rozumné řešení. Podporu bloků jsem tedy zkusmo implementoval (včetně dědičnosti).

Bloky jsou samostatné jednotky, které lze kdekoliv inkludovat, dokonce i uvnitř sebe samého (příklad).

Vzhledem k tomu, že šablony se v takovém případě zpracují ve směru od vnitřku ven, je možné zachovat podporu pro {param $title 'Editace položky'}. Možná by se dalo jít dál a ke každému souboru template.phtml přidat volitelný template.ini, kde by bylo možné definovat meta informace.

Kompatibilitu se současným stavem bych chtěl zachovat v tom smyslu, že současný stav je vlastně podmnožinou použití bloků & dědičnosti. Zde problém nevidím.

Další háček je v podpoře AJAXů a snippetů. Myslím, že snippety a bloky by se daly do velké míry sjednotit a díky novým vlastnostem bloků by mohlo zmizet těžko pochopitelné prefixování zavináčem @{...}.

gawan
Člen | 110
+
0
-

Neviem či poznáte silverstripe. Chvíľu som s tým robil a tiež sú tam zaujímavo riešené šablóny, stojí za pozretie (Using a subtemplate).

phx
Člen | 651
+
0
-

Jaky konkretni problem je s detekci koncu HTML elementu?

Ohledne ID mi problem ohledne HTML take nedotyka… :(

Ondrej
Člen | 110
+
0
-

David Grudl napsal(a):

Bloky jsou samostatné jednotky, které lze kdekoliv inkludovat, dokonce i uvnitř sebe samého (příklad).

Uvital bych typ bloku, ktery se hned nevypise, ale zachyti se jen do promenne. V nadrazene layoutove sablone se pak zachyceny blok zobrazi.

Priklad:
@layout.phtml

<?php
 <div id="left">
	{block #levysloupec}
		vychozi obsah, pokud neni levy sloupec v podsablone
	{/block}
 </div>
 <div id="content">
	{block #content}
		Text na momepage
	{/block}
 </div>
?>

articles.phtml

<?php
	{block #levysloupec}
		podobne clanky...
	{/block}

	{block #content}
		seznam clanku...
	{/block}

{* ostatni mimo bloky se klasicky pouzije do $content *}

?>
Petr Daňa
Člen | 109
+
0
-

Jestli se šablony budou překopávat, tak hlavně prosím zachovejte nějak zpětnou kompatibilitu (nebo možnost na to přepnout) s nynějším stavem, tj. layout + CurlyBracketsFilter. Jinak mě ve firmě zabijou :) (vypadá to, že alespoň částečně na vnitřní věci použijem Nette, teda zatím je to ve fázi zkoušení, tak snad to schválej).

David Grudl
Nette Core | 8218
+
0
-

S tím počítám, už teď je v Presenteru $oldLayoutMode

washo
Člen | 88
+
0
-

Proc je toto vlakno zruseno?

Editoval washo (5. 2. 2009 19:31)

romansklenar
Člen | 655
+
0
-

Vlákno ne, jen byla z distribuce odstraněna možnost renderovat v opačném pořadí.

washo
Člen | 88
+
0
-

romansklenar napsal(a):

Vlákno ne, jen byla z distribuce odstraněna možnost renderovat v opačném pořadí.

No prave ze mi nebylo jasne co bylo zruseno a co ne…
takze jednoduse:

zruseno: divny zpusob renderovani

ponechano: dedicnost sablon (jak bylo prezentovano v brne na skoleni)

ok?

Editoval washo (5. 2. 2009 20:44)

romansklenar
Člen | 655
+
0
-

Jojo, dědičnost ještě funguje.

washo
Člen | 88
+
0
-

romansklenar napsal(a):

Jojo, dědičnost ještě funguje.

Jeste?! :)

David Grudl
Nette Core | 8218
+
0
-

Jde to, jen to je stále předmětem vývoje:

Presenter:

	protected function beforeRender()
	{
		$this->oldLayoutMode = FALSE;
	}

Šablona view:

{extends $layout}

{block #title}Add New Album{/block}

{block #content}
	<h1>Add New Album</h1>

	{!$form}
{/block}

Šablona layoutu:

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>{block #title}Nette example{/block}</title>
</head>

<body>
	{foreach $flashes as $flash}<div class="flash {$flash->type}">{$flash->message}</div>{/foreach}

	<div id="content">
		{include #content}
	</div>

	{if isset($user)}
	<p id="logged-in">Logged in as {$user->real_name}. <a href="{link logout}">Logout</a></p>
	{/if}
</body>
</html>
pmg
Člen | 372
+
0
-

Jen návrh: bylo by pěkné, kdyby šlo uvnitř bloku vložit obsah jeho rodiče.

{* @layout.phtml *}
{block #css}
	<link rel="stylesheet" href="{$baseUri}yui/reset-fonts-grids/reset-fonts-grids.css" media="all" type="text/css" />
	<link rel="stylesheet" href="{$baseUri}yui/base/base.css" media="all" type="text/css" />
{/block}


{* default.phtml *}
{extends @layout.phtml}
{block #css}
	{extends #css}	{* vloží obsah bloku z @layout.phtml *}
	<link rel="stylesheet" href="{$baseUri}assets/main.css" media="all" type="text/css" />
{/block}
Vitek Jezek
hledá kolegy | 285
+
0
-

jo, ja jsem taky pro tento navrh!

David Grudl
Nette Core | 8218
+
0
-

Rodiče samozřejmě volat lze. Zkus {include #parent}

pmg
Člen | 372
+
0
-

Aha, špatně jsem to pochopil. Ale jak jsem mohl tušit, že tím {include #parent} se myslí {include #parent}? :-)

Moje pozorování ohledně zanořených bloků (rev. 223).

{* @layout.phtml *}

{block #a}
aaa
	{block #b}
		bbb
	{/block}
{/block}


{* default.phtml *}

Takto se blok `#b` nevypíše:

{block #a}
	AAA
	{block #b}
		BBB
	{/block}
{/block}

Ale lze to obejít takto:

{block #b}
	BBB
{/block}

{block #a}
	AAA
	{include #b}
{/block}
deric
Člen | 93
+
0
-

Výborné! Jsem pro poslední návrh.

Jak je to s podporou snippet?

{block #content}
	{snippet foo}
		<p>tento text se nevykresi</p>
	{/snippet}
{/block}

nebo je tam potřeba nějaká @-ová magie?

pmg
Člen | 372
+
0
-

To nebyl návrh, jen jsem pozoroval, jak to funguje. :-)

Proki
Člen | 66
+
0
-

Taky bych se chtěl zeptat, jak je to s podporou snippetů uvnitř bloků…

romansklenar
Člen | 655
+
0
-

To nikdo pořádně neví :) chtělo by to, aby nám to David osvětlil. Když jsem ale snippety zkoušel použít, dopracoval jsem se akorát k tomuhle.

pavel80
Člen | 9
+
0
-

Měl bych návrh:
Tahle diskuze se trochu rozrostla tak snad si toho někdo všimnete:) možná by se šiklo nové vlákno, příde mi to docela klíčové téma!

Dědění šablon je super, ale vidím tu jeden problém, kterým možná jde řešit ale nevím jak:

Když např. base.phtml bude vykreslovat menu, kde budu pro to menu zpracovávat data? ve volaném presenteru, který s base.phtml nemá nic společného?

Co kdyby každý presenter měl vlastní @layout!

Zavolám např. MyPresenter, action=myAction; k tomu příslušná šablona je v MyPresenter/myAction, následně by se mohla připojit šablona „nadřazená“ s názvem MyPresenter/@layout.phtml, ta by obsahovala {include content},…

Aby to bylo uplně univerzální mohl by mechanismus kopírovat extends presenterů, což by bylo elegantní že by se dala řešit zmíněná situace s menu a samozdřejmě řada dalších:) Zpětná kompatibilita by byla vyřešení taky neboť by tamnebylo nic jinak, jen něco navíc.

tj. mám např.:

<?php
MyBasePresenter extends BasePresenter implements IComposition {
  public function defaultRender() {
  // tady bude naplnení hodnot pro vyrenderovani menu
  }
}
?>

Tomu náleží šablona MyBase/Default.phtml, IComposition říká že se jedná jen o „obal“

<?php
MyPresenter extends MyBasePresenter implements IComposition {
  public function defaultRender() {
    parent::defaultRender();
 // vyrobit vse co souvisi s hlavni akci a nejake další věci…
  }
}
?>

Tomuhle bude odpovídat šablona My/Default.phtml – za {include content} se vlozi vysledek predchoziho renderovani MyBase
Nakonec se veme @layout.phtml

Ohledání dědičnosti presenterů umí ohlídat reflection, pak už je to jen o načtení šablon…

IComposition jsem zvolil zamerne, neboť MyBasePresenter by nemel být volatelný z url, protože obsahuje jen „obal“ stránky

Co myslíte?

Editoval pavel80 (19. 4. 2009 23:07)

Ola
Člen | 385
+
0
-

Ale vždyť presenter může mít vlastní layout :)

_Martin_
Generous Backer | 679
+
0
-

Přijde mi to zbytečně těžkopádné – pro menu může být komponenta s vlastní šablonou a fertig. Případně data vyzobá BasePresenter, ne?

pavel80
Člen | 9
+
0
-

Zkusím to ještě z druhé strany

Představte si web strukturou třeba podobný idnes.cz – má několik sekcí, každá vypadá jinak (má jiné šablony), přesto mají něco společného (hlavička, patička). Každá tahle sekce pak obsahuje řadu konkrétních stránek s vlastníma šablonama.

No a teď jak na to? …když nette umí akorát jednu šablonu k akci a jeden společný layout, nebo ne?

Ondřej Mirtes
Člen | 1536
+
0
-

pavel80 napsal(a):

Zkusím to ještě z druhé strany

Představte si web strukturou třeba podobný idnes.cz – má několik sekcí, každá vypadá jinak (má jiné šablony), přesto mají něco společného (hlavička, patička). Každá tahle sekce pak obsahuje řadu konkrétních stránek s vlastníma šablonama.

No a teď jak na to? …když nette umí akorát jednu šablonu k akci a jeden společný layout, nebo ne?

Každý Presenter může mít svůj layout a navíc ho můžeš měnit kde chceš, přes metodu setLayout.

Patrik Votoček
Člen | 2221
+
0
-

pavel80 napsal(a):

Zkusím to ještě z druhé strany

Představte si web strukturou třeba podobný idnes.cz – má několik sekcí, každá vypadá jinak (má jiné šablony), přesto mají něco společného (hlavička, patička). Každá tahle sekce pak obsahuje řadu konkrétních stránek s vlastníma šablonama.

No a teď jak na to? …když nette umí akorát jednu šablonu k akci a jeden společný layout, nebo ne?

Pokud používáš extends a block-y aneb oldLayoutMode = FALSE . Což je podle davida budoucnost templatů v nette.
Tak ti nic nebrání v tom mít třeba:

@layout.phtml
...hlavicka...
{block #content}
...content...
{/block}
...paticka...

@sekce1.layout.phtml
{extends @layout.phtml}
{block #content}
{block #menu}
...menu...
{/block}
{block #data}
...data...
{/block}
{/block}


@sekce2.layout.phtml
{extends @layout.phtml}
{block #content}
{block #data}
...data...
{/block}
{block #menu}
...menu...
{/block}
{/block}

default.phtml //defaultni akce
{extends @sekce1.layout.phtml} //pokud chces rederovat strukturu sekce2 tak zaměníš sekce1 za sekce2
{block #data}
...data...
{/block}
{block #menu}
...menu...
{/block}

Psal jsem to z hlavy… Takže nezaručuju 100% funkčnost ale jako nástřel by to mělo stačit.

_Martin_
Generous Backer | 679
+
0
-

Ve starém rendrovacím režimu by to možná šlo suplovat dobře navrženými samostatnými šablonami (pomocí include bloků v nadřazených šablonách).

xificurk
Člen | 121
+
0
-

EDIT: Problém nového dědění šablon a soušasného kešování přesunut do samostatného vlákna.

Editoval xificurk (23. 4. 2009 12:40)

Patrik Votoček
Člen | 2221
+
0
-

Pošly to jako bug-report pokud to tam jeste neni…

David Grudl
Nette Core | 8218
+
0
-

pmg napsal(a):

Moje pozorování ohledně zanořených bloků (rev. 223).

Zanořené bloky by už měly fungovat.

pmg
Člen | 372
+
0
-

Tak to asi budu muset udělat nové pozorování ohledně zanořených bloků.

xificurk
Člen | 121
+
0
-

Jen pro informaci, kdyby se někdo podivoval proč mu najednou přestali fungovat některé konstrukce:

Nyní je potřeba psát obsah šablony v tomto pořadí:

{assign $var1 'var1'}

{extends 'parent.phtml'}

{block #content}
Tento block nahradí blok #content v šabloně parent.phtml
{/block}

Důležité je uvádět {extends} až za všemi deklaracemi {assign}, které chceme mít dostupné i v rodiči, a až nazávěr všechny deklarace {block}, které mají něco překrýt.

David Grudl
Nette Core | 8218
+
0
-

Ano, alespoň v tuto chvíli tomu tak je.

V další revizi bude {extends '@layout.phtml'} automatické a nepovinné, tj. pokud bude existovat layout, automaticky se bude extendovat. Tedy jestli to uživatel nepřebije pomocí vlastní direktivy {extends neco-jineho}. Tím vlastně ztrácí na důležitosti metoda setLayout(), respektive její použití se přesune tam kam patří, do šablony.

Naopak automatické uzavírání celého obsahu do bloku {block #content} bohužel nelze implementovat, mělo by to značná úskalí. Ale abych život zjednodušil, bude koncová značka nepovinná (podobně jako je nepovinná značka ?> v PHP).

Přechod na novou podobu šablon by tak v podstatě znamenal jen

  • změnit {include $content} na {include #content} v layoutu
  • přidat na začátek každé šablony {block #content}

Uvažuju nad tím, jestli nevypustit tu mřížku, tj. {block#content}{block content}. Ale asi ne, uzavřela by se tím možnost dalšího případného rozšiřování.

Možná bych zrušil (používá to někdo?) zachytávání do proměnné přes {block $prom}...{/block}. Dá se to myslím řešit obecněji přes modifikátor, tj. {block|capture:$prom}...{/block}. Nebo přidat srozumitelnější {capture $prom}...{/capture}.

Bloky jsou totálně dynamické. Lze udělat třeba layout:

<html>
<head>
	<title>{block #title|upper}{/block} Nette example</title>
</head>

<body>
	{include #content}
</body>
</html>

a obsah ({extends} je nepovinné)

{block #content}
<h1>{block #title}Edit Album{/block}</h1>
{!$form}

Vygeneruje

<html>
<head>
	<title>EDIT ALBUM Nette example</title>
</head>

<body>
	<h1>Edit Album</h1>
	<form> ... </form>
</body>
</html>