CurlyBrackets: dědění šablon {extends …} bug?

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

Hraju si s {extends} a mám následující:

base.phtml

{block #maincontent}
	main content default
{/block}

2col.phtml:

{extends base.phtml}

{block #maincontent}

	{block #col1}
		default col1
	{/block}

	{block #col2}
		default col2
	{/block}

{/block}

default.phtml:

{extends 2col.phtml}

{block #col1}
	prepsany col1
{/block}

{block #col2}
	prepsany col2
{/block}

Na výstupu se mi neobjeví nic. Je to bug nebo jsem špatně pochopil chování nette?

Revize: 207

_Martin_
Generous Backer | 679
+
0
-

Ahoj, podívej se na Davidův příspěvek, vyplývá mi z něj, že musíš presenteru nastavit, aby nepoužíval starý režim layoutu.

jasir
Člen | 746
+
0
-

_Martin_ napsal(a):

Ahoj, podívej se na Davidův příspěvek, vyplývá mi z něj, že musíš presenteru nastavit, aby nepoužíval starý režim layoutu.

Ale jó, to tam mám ( přesněji, mám tam $this->oldLayoutModule = FALSE; $this->changeLayout(FALSE); ). Dědění normálně funguje, ale nedaří se mi rozchodit konstrukci vnořených bloků. Mám blok (#maincontent), v další šabloně jsou v rámci tohoto bloku další dva bloky (#col1,#col2) a pak je ve definuji ve třetí šabloně. (viz příklad) nahoře.

Editoval jasir (6. 2. 2009 10:27)

kravčo
Člen | 721
+
0
-

jasir napsal(a):

_Martin_ napsal(a):

Ahoj, podívej se na Davidův příspěvek, vyplývá mi z něj, že musíš presenteru nastavit, aby nepoužíval starý režim layoutu.

Ale jó, to tam mám ( přesněji, mám tam $this->oldLayoutModule = FALSE; $this->changeLayout(FALSE); ). Dědění normálně funguje, ale nedaří se mi rozchodit konstrukci vnořených bloků. Mám blok (#maincontent), v další šabloně jsou v rámci tohoto bloku další dva bloky (#col1,#col2) a pak je ve definuji ve třetí šabloně. (viz příklad) nahoře.

Trochu som skúmal implementáciu dedičnosti v šablónach a zistil som nasledovné: Momentálne sa všetky bloky renderujú v rodičovskej šablóne, ktorá je najvyššie v „rodokmeni“:

base.phtml
  |
  --2col.phtml
      |
      --default.phtml

Pri tvojom príklade je to teda base.phtml. A problém je na svete, pretože v base.phtml žiadne bloky #col1 a #col2 nie sú a preto sa ani nevyrenderujú (ostatok sa renderuje správne).

Riešením, ktoré by zisťovalo, či je na aktuálne spracúvanej šablóne blok definovaný po prvý raz (a teda teraz je čas ho vyrenderovať) mi teraz v noci pripadá príliš náročné a neviem si ho celkom predstaviť… To, čo mi napadlo je označovanie blokov, ktoré sa v hierarchii dedenia objavujú po prvýraz, napríklad:

{extends base.phtml}

{block #maincontent}
    {block new #col1}
        ...
    {/block}

    {block new #col2}
        ...
    {/block}
{/block}

Samozrejme takéto riešenie nie je ideálne, pretože sa bude zle udržovať po prípadných zmenách v hierarchii.

Mne sa tento príklad podarilo rozbehať po tomto jednoduchom patchi:

Index: Nette/Nette/Templates/Filters/CurlyBracketsFilter.php
===================================================================
--- Nette/Nette/Templates/Filters/CurlyBracketsFilter.php	(revision 207)
+++ Nette/Nette/Templates/Filters/CurlyBracketsFilter.php	(working copy)
@@ -259,10 +259,17 @@
 	 */
 	private static function macroBlock($var, $modifiers)
 	{
+		$isInherited = TRUE;
+
+		if (substr($var, 0, 4) === 'new ') {
+			$isInherited = FALSE;
+			$var = trim(substr($var, 4));
+		}
+
 		if (substr($var, 0, 1) === '#') {
 			$var = var_export(substr($var, 1), TRUE);
 			$func = '_cbb' . substr(md5(self::$file . "\00" . $var), 0, 15);
-			$call = self::$extends ? '' : "\n\$_cb->cs = \$_cb->f[$var]; call_user_func(\$_cb->cs[0], \$template->getParams())"; // get_defined_vars()
+			$call = $isInherited ? '' : "\n\$_cb->cs = \$_cb->f[$var]; call_user_func(\$_cb->cs[0], \$template->getParams())"; // get_defined_vars()
 			self::$blocks[] = "\n}\n\$_cb->f[$var][] = '$func';$call";
 			return "\nfunction $func() { extract(func_get_arg(0))\n";
 		}

Predpokladám, že toto správanie sa v blízkej dobe zmení, patch preto považujte skôr za ukážku, ako tento konkrétny problém vyriešiť veľmi rýchlo a bez ohľadu na ďalšie jeho dôsledky a iné prípady.

jasir
Člen | 746
+
0
-

Ahoj, moc děkuji za reakci a vysvětlení. Mám další problémek, už se s tím mořím pěkně dlouho :(
Moje šablona, kterou používám pomocí extends jako layout:

<?php
/**
* @param $title - title and h1 of the page
* @param $showNavigation - can we show navigation???
* @param #crumbmenu - content of crumbmenu
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="cs">
<head>
   <title>{$title}</title>

   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <script src="{$baseUri}/js/nette.js" type="text/javascript"></script>

   <link rel="stylesheet" href="css/reset-fonts-grids.css" type="text/css">
   <link rel="stylesheet" href="css/style.css" type="text/css">
   <link rel="shortcut icon" href="{$baseUri}favicon.ico" type="image/x-icon">

   <style>
     ...css styles
   </style>


   <!-- Special head content from template  -->
   {block #head}
	<!-- Nothing from template...-->
   {/block}
   <!-- Special head content from template end -->
</head>

<body>
<div id="custom-doc" {if $showNavigation} class="yui-t1" {/if}>
   <!--  HEADER -->
   <div id="hd">
	<div id="box-layoutheader">TITLE</div>
   </div>

   {block #logininfo}{/block}

   {block #flashmessages}
		{foreach $flashes as $flash}
			<div id="flashmessages">{$flash->message}</div>
		{/foreach}
   {/block}

   <!--   MAINCONTENT  -->

   <div id="bd">
	 <div id="yui-main">
		<div id = 'maincontent' class="yui-b">
			<h1>{$title}</h1>
			{include #maincontent}
		</div>
	</div>


	{if $showNavigation}
	<!--    NAVIGATION  -->
	<div class="yui-b" id="navigation">
		{block #navigation}navigation not defined in template...{/block}
	</div>
	{/if}
   </div>
</div>

{block #endofcontent}
<!--Block #endofcontent is empty-->
{/block}

<div class="ui-helper-hidden">
	{block #hidden}
	<!--Block #hidden is empty-->
	{/block}
</div>

</body>
</html>

a dále konkrétní šablonu stránky:

{assign $title "Přehled otázek"}
{assign $showNavigation false}

{extends "../../@layouts/2col.yui.phtml"}

{block #maincontent}
<div class="yui-gc">
{snippet}
  {foreach ...}
    echo ...
  {/foreach}
{/snippet}
<a href="{link delete!}" class="ajaxlink">Smaž příspěvek</a>
</div>
{/block}


{block #head}
	<script src="{$baseUri}/js/jquery/jquery.js" type="text/javascript"></script>
	<script src="{$baseUri}/js/jquery/jquery-ui.min.js" type="text/javascript"></script>
	<script src="{$baseUri}/js/nette.jquery.js" type="text/javascript"></script>

	<script type="text/javascript">

	$("a.ajaxlink").live("click", function () {
			$.netteAjax(this.href);
			return false;
	});
	</script>

{/block}

Použil jsem script z fóra (děkuji!).
Ajax funguje, ale již při prvním zobrazení stránky se nezobrazí obsah {snippet}…{/snippet} – a ani se neupdatuje snippet při volání. Předpokládám, že problém bude právě v použítí snippet ale opravdu už nevím co mám dál zkoušet… V presenteru mám mimo jiné:

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

Chtěl bych bloky používat, líbí se mi že mohu snadno v šablonách přidávat na různá místa definovaná v 2col.yui.phtml lauyoutu (do #head rozsireni <head> – javascripty apod.) ale nemůžu to nějak rozchodit. Netušíte někdo? … moc děkuji

Editoval jasir (12. 2. 2009 1:44)

jasir
Člen | 746
+
0
-

dokonce i když v {block #maincontent}{/block} použiji {snippet}{/snippet} od prvního {snippet} až do konce bloku už se nic nezobrazí (stále mluvím o prvním načtení).

Zřejmě jsem úplně vedle :-(

Editoval jasir (13. 2. 2009 15:27)