如何在Magento主题中进行适当的嵌套?

时间:2012-08-27 12:25:38

标签: templates magento nested

我在两个目录中复制了默认的Magento主题并重命名了它。 经过大量的调整后,我已经陷入了困境。

我有一个基本版面所在的3columns.phtml文件:

  • top(top.phtml)
  • header(header.phtml)
  • main(main.phtml)
  • footer(footer.phtml)

使用main.phtml:

  • left.phtml
  • middle.phtml
  • right.phtml

现在,当我使用getChildHtml()函数在3columns.phtml中单独引用这些块时,一切都很好。现在,将它们放入main.phtml文件后,它似乎不再起作用了。 main.phtml中的任何内容都没有显示(甚至没有simpel html标签)。认为它可能与xml布局文件有关,我查看了page.xml,但发现一些东西由catalog.xml处理

我现在在page.xml中有这些块声明:

  • 顶部(没有模板=设置)
  • 标题(无模板=设置)
  • main(template =“page / html / main.phtml”)
    • left(template =“page / html / left.phtml”)
    • middle(template =“page / html / middle.phtml”)
    • topmenu(template =“page / html / topmenu.phtml”)
    • breadcrumbs(无模板=设置)
    • right(template =“page / html / right.phtml”)
  • footer(template =“page / html / footer.phtml”)

虽然top和header没有模板设置,但他们的html在前端显示得很好。页脚显示也很好。 显示左侧输出,但不包括主输出。 右边的输出相同。 中间的输出显示,但其中的任何getChildHtml调用都没有。

关于发生了什么的任何想法? 另外,page.xml和catalog.xml如何与模板相关?是否每次调用getChildHtml都必须在page.xml文件中?页面和目录之间有什么区别。

page.xml的一部分:http://www.snipplr.com/view/66919/part-of-pagexml-not-working/

catalog.xml的一部分:http://www.snipplr.com/view/66920/default-part-of-catalogxml-not-working/

3columns.phtml:http://www.snipplr.com/view/66921/main-theme-file-3columnsphtml/

2 个答案:

答案 0 :(得分:4)

有关详细说明,您可以阅读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 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”,“知道”的块)。

如果名称为“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才能看起来很整洁。

答案 1 :(得分:1)

以下是一些可能的解释。

由于左,中,右是'main'的孩子,你需要调用getChildChildHtml(注意双子)。

由于'main'是3个列中的子(嵌套),因此它不被认为是自己的页面类型(即1列),更好的解决方案似乎是编辑3columns.phtml文件以获得所需的块。

调用getChildHtml时,传递给它的参数是xml中的name =''属性(例如,如果需要调用'right'块,那么我们需要在xml中找到name属性 - 在此case是'right'并将其用于参数)。

显示左,页脚等块,因为它们已在3columns.phtml文件中调用。

同时仔细检查“main”的模板文件是否在正确的位置。

我希望这些是一些有用的指针