CurlyBrackets: dědění šablon {extends …} bug?
- jasir
- Člen | 746
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
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
_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
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
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)