有关详细说明,您可以阅读 Alanstorm 的书“No Frills Magento Layout”。
我给你“简要”的解释,让你有点开悟。
在我们的控制器中,当我们调用$this->loadLayout();时,它会自动“调用”<default>句柄。
稍后,所有布局xml中的所有句柄都会被合并。
假设您的 page.xml 中有 <default>,那么您的 catalog.xml 中也有 <default>。
调用$this->loadLayout()后,page.xml和catalog.xml中的<default>会被合并。
这就是他们之间的关系。
我们可以说<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的定义:
<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 来保持整洁。