不确定为什么这么难。如果我理解正确THIS,我应该能够迅速实现我的目标......但没有快乐。
所以 - 我正在构建我的第一个主题,并且仍然围绕布局......
我专门在Catalog Product View
页面上工作,并且正在将此页面从右列布局转换为左列布局。我只是想把块从右边移到左边。
在默认catalog.xml中,定义了product_list_related
:
</catalog_product_view>
//...
<reference name="right">
<block type="catalog/product_list_related" name="catalog.product.related" before="-" template="catalog/product/list/related.phtml"/>
</reference>
</catalog_product_view>
在我的local.xml中,我只是想移动这个块:
<layout>
// bunch other page directives
<catalog_product_view>
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="right">
<action method="unsetChild"><name>catalog.product.related</name></action>
</reference>
<reference name="left">
<action method="insert"><blockName>catalog.product.related</blockName></action>
// note that that "catalog.leftnav" gets inserted as expected
<block type="catalog/layer_view" name="catalog.leftnav" after="-" template="catalog/layer/view.phtml"/>
</reference>
</catalog_product_view>
</layout>
如上所述 - 插入catalog.leftnav
按预期工作,所以我假设其他所有内容都已正确设置。如果我让模板和其他指令保持不变,目标块会按预期呈现,这告诉我块一旦被正确设置并插入就应该呈现...
这让我疯狂......但Magento还有什么新东西。
干杯 -
B []×
UPDATE
因为我无法让local.xml
覆盖工作,所以我只是回到修改后的catalog.xml
。我是一个相当聪明的人...它让我担心我不能让这个工作(而且无论如何,那个magento都默默地失败了) - 但是我不能再浪费时间来讨论这个愚蠢的问题了。
继续前进。
UPDATE, again.
花了一些时间,现在,在magento工作,并更熟悉其复杂性。我今天回到了这个问题,因为我需要让我的local.xml正常工作。
我真的不知道自己错了什么,但这套指令终于奏效了。
<reference name="right">
<action method="unsetChild">
<alias>catalog.product.related</alias>
</action>
</reference>
<reference name="left">
<action method="insert">
<block>catalog.product.related</block>
</action>
</reference>
关键点我会留意其他处理此问题的人:
布局xml指令调用magento类中的可用方法。在这种情况下,Page.xmls“Left”块的类型为Mage_Core_Block_Text
,它继承自Mage_Core_Block_Abstract
,其中包含方法unsetChild
和insert
。
来自Mage_Core_Block_Abstract
:
/**
* Unset child block
*
* @param string $alias
* @return Mage_Core_Block_Abstract
*/
public function unsetChild($alias)
{
if (isset($this->_children[$alias])) {
unset($this->_children[$alias]);
}
if (!empty($this->_sortedChildren)) {
$key = array_search($alias, $this->_sortedChildren);
if ($key !== false) {
unset($this->_sortedChildren[$key]);
}
}
return $this;
}
和
/**
* Insert child block
*
* @param Mage_Core_Block_Abstract|string $block
* @param string $siblingName
* @param boolean $after
* @param string $alias
* @return object $this
*/
public function insert($block, $siblingName = '', $after = false, $alias = '')
{
if (is_string($block)) {
$block = $this->getLayout()->getBlock($block);
}
if (!$block) {
/*
* if we don't have block - don't throw exception because
* block can simply removed using layout method remove
*/
//Mage::throwException(Mage::helper('core')->__('Invalid block name to set child %s: %s', $alias, $block));
return $this;
}
if ($block->getIsAnonymous()) {
$this->setChild('', $block);
$name = $block->getNameInLayout();
} elseif ('' != $alias) {
$this->setChild($alias, $block);
$name = $block->getNameInLayout();
} else {
$name = $block->getNameInLayout();
$this->setChild($name, $block);
}
if ($siblingName === '') {
if ($after) {
array_push($this->_sortedChildren, $name);
} else {
array_unshift($this->_sortedChildren, $name);
}
} else {
$key = array_search($siblingName, $this->_sortedChildren);
if (false !== $key) {
if ($after) {
$key++;
}
array_splice($this->_sortedChildren, $key, 0, $name);
} else {
if ($after) {
array_push($this->_sortedChildren, $name);
} else {
array_unshift($this->_sortedChildren, $name);
}
}
$this->_sortInstructions[$name] = array($siblingName, (bool)$after, false !== $key);
}
return $this;
}
本地xml参数很重要,然后,不是名称(特定),而是按顺序:
<reference name="left">
<action method="insert">
<block>catalog.product.related</block>
<siblingName>catalog.leftnav</siblingName>
<after>1</after>
<alias>catalog_product_related</alias>
</action>
</reference>
最终,这使local.xml成为操作系统的一种非常强大的方法,但是如果你不熟悉它和magento系统,那么就要准备好几周或几个月的工作来真正了解它。
干杯
我现在已经多次遇到这个问题了,我想移动的一个块已被移除。这是一个问题,因为任何已从布局中删除的块都会被永久化。
但是,Alan Storm非常方便Unremove Plugin你可以撤消已经完成的事情:
<checkout_onepage_index>
<x-unremove name="left" />
<reference name="right">
<action method="unsetChild">
<alias>checkout.progress.wrapper</alias>
</action>
</reference>
<reference name="left">
<action method="insert">
<block>checkout.progress.wrapper</block>
</action>
</reference>
</checkout_onepage_index>
它通过观察布局对象并构建已删除块的列表来管理此专长,这些块可以在以后引用。
尼斯!
答案 0 :(得分:19)
现在这是一个尘封的线索,但是为了记录,这是我最后的答案。
<reference name="right">
<action method="unsetChild">
<alias>checkout.progress.wrapper</alias>
</action>
</reference>
<reference name="left">
<action method="insert">
<block>checkout.progress.wrapper</block>
</action>
</reference>
Magento建议在local.xml
中加入此内容,并证明这是一种有效的技巧。
答案 1 :(得分:2)
如果您只是希望将输出从2col-right更改为2col-left,那么改变它会更容易,
<reference name="right" ...
到
<reference name="left" ...
无需取消设置或插入任何子项或重新声明任何内容。你不必要地复杂化和复制代码。
如果您也在制作自己的besoke设计,我建议您开始将整个./app/design/frontend/base
目录复制到./app/design/frontend/mypackage
- 然后从mypackage/default
目录开始重新设置您的网站。它更干净,更容易。如果您复制每个文件(而不仅仅是您想要修改的文件),其他人可能会评论升级能力的潜在问题,但这是一个更好的做法,更不容易出错,困难和一般维护。
修改:要详细跟进此内容,请查看https://magento.stackexchange.com/a/3794/361
答案 2 :(得分:2)
另一种方法是将“右”块重命名为“左”,而不是从右向左移动块。但是,如果首先删除“正确”的块,这将无效,正如我在其他答案中所提出的那样。
<remove name="left" />
<reference name="right">
<action method="setNameInLayout"><name>left</name></action>
</reference>
<reference name="root">
<action method="setChild"><alias>left</alias><name>left</name></action>
<action method="unsetChild"><alias>right</alias></action>
</reference>
<!-- make sure nothing referencing "right" comes after this! -->
答案 3 :(得分:1)
可能会在布局中的某个位置使用<remove name="right" />
删除“右侧”块。如果是这样,这将导致“catalog.product.related”块永远不会首先添加到布局中,因此没有块可以插入“左”块。
我很确定这是问题,但要确认,添加一个Mage :: log(“Removed $ blockName”);在for循环中的Mage_Core_Model_Layout-&gt; generateXml()中,并在加载页面后检查日志。
如果我是对的,只需将<block..>
复制到local.xml中,然后删除“unsetChild”和“insert”操作。
答案 4 :(得分:1)
我会这样做:在例如
下的local.xml中<reference name="right"></reference>
删除块,例如:
<remove name="right.poll">
然后在
中添加块<reference name="left"></reference>
答案 5 :(得分:0)
将base / default复制到本地主题是一个可怕的想法。在Magento版本升级上对核心主题文件的每次更新都会导致修改应用程序/代码/核心文件的相同漏洞 - 需要您在升级时将文件区分开来。
您正确的做法是使用您的添加或覆盖修改单个local.xml。如果这还不够,请使用正确的语法在app / code / community中创建具有布局定义和自定义布局XML文件的模块。
答案 6 :(得分:0)
我认为修改Magento布局的最佳答案在Classyllama.com上给出
http://www.classyllama.com/development/magento-development/the-better-way-to-modify-magento-layout
使用remove标记时,无论上下文如何,它都会从整个布局中删除具有指定名称的所有块。因此,如果我在上下文中删除right.newsletter并且在上下文中使用该名称,则将删除这两个块。由于remove在全局上下文中运行,因此您只能删除一次元素。由于在catalogsearch.xml中调用,我们必须取消它,否则我们会收到错误。
<action method="unsetChild"><name>right.newsletter</name></action>;