有关详细说明,您可以阅读 Alanstorm 的书“No Frills Magento Layout”。我给你“简要”的解释一下,让你有点开悟。
在我们的控制器中,当我们调用 时$this->loadLayout();
,它会自动“调用”<default>
句柄。
稍后,所有布局xml中的所有句柄都会被合并。
假设您<default>
在 page.xml 中有,那么您<default>
在 catalog.xml 中也有。$this->loadLayout()
page.xml<default>
和catalog.xml的调用之后会被合并。
这就是他们之间的关系。
可以说<default>
是万事万物之主。它是主要结构。任何其他布局通常从中“引用”。
假设您想在主体(内容)中添加一些内容,我们将调用:
<reference name="content">
<block type="core/template" name="testing" template="some/test/template.phtml"></block>
</reference>
那些标签的意思是:放在<block type="core/template" name="testing" template="some/test/template.phtml"></block>
带有名称内容的块下。
如果您看到带有名称内容的块定义:
<block type="core/text_list" name="content" as="content" translate="label">
<label>Main Content Area</label>
</block>
可以看到类型是core/text_list
。这种类型的块将呈现它下面的每个孩子,它不需要模板。如您所见,没有 template="blabla/blibli.phtml" 的定义。
具有模板的块类型是core/block_template
. 在这种类型的块中,如果你想渲染它的孩子,你必须“有意识地”调用echo $this->getChildHtml('mykid')
.
你明白吗?
这就是您的定义不正确的原因:<block type="core/text_list" name="main" as="main" translate="label" template="page/html/main.phtml">
.
core/text_list
不需要也没有模板。你可以想象如果“内容”是一个core/block_template
:每次你要在“内容”下创建一个孩子,你必须“有意识地”调用echo $this->getChildHtml('mykid')
。假设您有 100 个孩子,您需要调用echo $this->getChildHtml('mykid1')
, echo $this->getChildHtml('mykid2')
, ..., echo $this->getChildHtml('mykid100')
。
然后让我们看看你的catalog.xml:
<default>
<!-- Mage_Catalog -->
<block type="core/template" name="top" template="page/html/top.phtml"></block>
<block type="core/template" name="header" template="page/html/header.phtml"></block>
<block type="core/template" name="main" template="page/html/main.phtml">
<block type="core/template" name="left" template="page/html/left.phtml"></block>
<block type="core/template" name="middle" template="page/html/middle.phtml"></block>
<block type="core/template" name="right" template="page/html/right.phtml"></block>
</block>
<reference name="footer_links">
<action method="addLink" translate="label title" module="catalog" ifconfig="catalog/seo/site_map">
<label>Site Map</label>
<url helper="catalog/map/getCategoryUrl" />
<title>Site Map</title>
</action>
</reference>
<block type="catalog/product_price_template" name="catalog_product_price_template" />
</default>
我不明白你将从这个catalog.xml 中实现什么。没有参考:<block type="core/template" name="top" template="page/html/top.phtml"></block>
,<block type="core/template" name="header" template="page/html/header.phtml"></block>
等。
如果您要添加一些布局(子),您需要从现有布局中“引用”。假设您要在名为“main”的块下添加子项,并将代码放在您的 catalog.xml 中:
然后你的 catalog.xml 将是这样的:
<default>
<reference name="main">
<block type="core/template" name="i" template="my/new/template1.phtml"></block>
<block type="core/template" name="dont" template="my/new/template2.phtml"></block>
<block type="core/template" name="know" template="my/new/template3.phtml"></block>
</reference>
</default>
现在它取决于名称为“main”的块的定义。
如果您的名称为“main”的块是:
<block type="core/text_list" name="main" as="main" translate="label">
...
</block>
然后这些块(名称为“i”、“dont”、“know”的块)将被自动调用(渲染)。
如果您的名称为“main”的块是:
<block type="core/template" name="main" as="main" translate="label" template="page/html/main.phtml">
...
</block>
然后你需要在你的page/html/main.phtml
:
echo $this->getChildHtml('i');
echo $this->getChildHtml('dont');
echo $this->getChildHtml('know');
这就是我所能解释的,因为它在你的布局中几乎是不正确的,如果你明白了,你可以通过阅读我的解释来解决它。
几个小贴士:
要查看加载了哪些句柄,请将此代码放在您的控制器中$this->loadLayout();
:
$layout = Mage::getSingleton('core/layout');
$updates = $layout->getUpdate();
$handles = $updates->getHandles();
var_dump($handles);
要查看从加载布局生成的 xml,请将此代码放在您的控制器中$this->loadLayout();
:
$layout = Mage::getSingleton('core/layout');
$updates = $layout->getUpdate();
$xml = $updates->asString();
var_dump($xml);
也许你需要echo "<pre>" / wrap using htmlentities / Mage::log
整洁的目的。