Dva stejné bloky v @layout

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

Ahoj,

snažím se trochu víc proniknout do Nette, vlastně u toho sedím se vším všudy prvních 12 hodin (8 ráno, čas jít spát, zjevně) a mastím presentery, komponenty, hraju si se službami v configu, zkouším možnosti routování a všechno funguje naprosto báječně a poměrně intuitivně. Líbí se mi, jak Nette navádí ke konzistentnímu a minimalistickému kódu (fakticky potřebuju nadefinovat jen pár komponent a nějaké šablony a zbytek – to jak se to poskládá dohromady – pořeší Nette za mě).

Ovšem na šablonách jsem se trochu zadrhl.
Momentálně mám projekt (zjednodušeně) v tomto (funkčním) stavu:

@layout.latte:

<!DOCTYPE html>
<html>
	<head>
		<title>{block #title}{/block} | Název webu</title>
	</head>
	<body>
		{control menu}

		<div id="mid">
			{snippet flashMessages}
				<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
			{/snippet}

			{block #content}{/block}

		</div>
	</body>
</html>

Jednotlivé šablony pak vypadají zhruba takto:

{layout '@layout.latte'}

{block #content}
	<h2>{block #title}Titulek stránky{/block}</h2>

	<p>lorem ipsum</p>
{/block}

Nadpis <h2> je zobrazován v rámci presenteru na každé stránce, proto bych jej chtěl přesunout ze všech těch podšablon, na jediné místo do @layout. Navíc mi nevyhovují flash messages zobrazené nad nadpisem. Když flash message vrátí třeba formulář umístěný pod nadpisem, vůbec nevypadá, že k tomu formuláři patří. Proto bych chtěl mít už přímo v @layout nadefinovaný h2, pod tím flashmessages a až pod tím content.

Zkoušel jsem:
@layout.latte:

<!DOCTYPE html>
<html>
	<head>
		<title>{block #title}{/block} | Název webu</title>
	</head>
	<body>
		{control menu}

		<div id="mid">

			<h2>{block #title}{/block}</h2>

			{snippet flashMessages}
				<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
			{/snippet}

			{block #content}{/block}

		</div>
	</body>
</html>

Jednotlivé šablony:

{layout '@layout.latte'}

{block #title}Titulek stránky{/block}

{block #content}
	<p>lorem ipsum</p>
{/block}

Ale vyskakuje výjimka „Nette\Latte\CompileException Cannot redeclare static block ‚title‘ in ..\Homepage\@layout.latte"
Z toho jsem pochopil, že stejně pojmenovaný "block“ nemůže existovat dvakrát v jedné šabloně, ani když je oba hodlám plnit stejnými daty. Škoda.

Jsem noob a určitě jsem akorát něco přehlédl/nepochopil v dokumentaci, ale už se s tím mořím pěkně dlouho a nemůžu přijít na funkční řešení svého problému. Proto bych si rád nechal poradit od zkušenějších uživatelů (Ne/La)tte ;-)

Tharos
Člen | 1030
+
+1
-

V layoutu můžeš použít namísto {block #title}{/block} konstrukci {include #title}. To vyřeší Tvůj problém. :)

Doplnění: No a pokud by Ti vadilo, že pak Nette křičí, když není block #title v konkrétní šabloně přítomen, můžeš kamkoliv do layoutu vložit ještě prázdné {define #title}{/define}.

<!DOCTYPE html>
<html>
    <head>
        {define #title}{/define}
        <title>{include #title} | Název webu</title>
    </head>
    <body>
        {control menu}
        <div id="mid">

            <h2>{include #title}</h2>

            {snippet flashMessages}
                <div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
            {/snippet}

            {block #content}{/block}
        </div>
    </body>
</html>

První šablona:

{* makro layout typicky není nutné vůbec psát *}
{block #title}Titulek stránky{/block}

{block #content}
<p>lorem ipsum</p>

Nějaká jiná šablona:

{* makro layout typicky není nutné vůbec psát *}
{block #content}
<p>dolor sit amet</p>

Editoval Tharos (23. 5. 2013 8:40)

Zax
Člen | 370
+
0
-

Parádní, funguje! A k tomu prakticky okamžitá odpověď. Díky moc!

Tharos
Člen | 1030
+
0
-

Rádo se stalo. :) Po odeslání mě napadlo, že by ten layout mělo jít (už jsem to netestoval) zapsat ještě jednodušeji:

<!DOCTYPE html>
<html>
    <head>
        <title>{block #title}{/block} | Název webu</title>
    </head>
    <body>
        {control menu}
        <div id="mid">

            <h2>{include #title}</h2>

            {snippet flashMessages}
                <div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
            {/snippet}

            {block #content}{/block}
        </div>
    </body>
</html>
Zax
Člen | 370
+
0
-

Jo, k něčemu takovému už jsem se taky dobral :-) původní problém byl jenom v nepochopení maker a po probdělé noci mi dokumentace příliš nepomohla (možná kdyby tam místo „vloží blok“ bylo napsáno „vloží a vykreslí blok“, tak by mě to trklo hned napoprvé). Teď už mi to dává smysl. A kdyby mi vadilo, že Nette křičí, že blok není definován, asi bych na to šel spíš přes {ifset #block} – podmínka mi přijde výřečnější než prázdný blok definovaný na náhodném místě (po letech bych se ke zdrojákům vrátil a mohl si říct „k čemu to tady sakra je?“). Nicméně v tom posledním řešení to ani není potřeba a šablona zůstává pefektně čitelná.

Moc pěkný, je vidět, že má cenu obětovat svůj čas a učit se Nette, ono se to brzy vrátí :-)

Ještě jednou díky!