Magento - 从右向左移动块

Bos*_*h99 7 magento layout-xml

不知道为什么这么难.如果我理解正确的,我应该能够迅速完成我的目标......但没有喜悦.

所以 - 我正在构建我的第一个主题,并且仍然围绕布局......

我正专门在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>
Run Code Online (Sandbox Code Playgroud)

在我的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>
Run Code Online (Sandbox Code Playgroud)

如上所述 - 插入catalog.leftnav按预期工作,所以我假设其他所有设置都正确.如果我保持模板和其他指令不变,目标块将按预期呈现,这告诉我块一旦被正确设置并插入就应该呈现...

这让我疯狂......但Magento还有什么新东西.

干杯 -

B []×

UPDATE
Run Code Online (Sandbox Code Playgroud)

因为我根本无法获得local.xml覆盖工作,所以我只是回过头来修改catalog.xml.我是一个相当聪明的人...它让我担心我不能让这个工作(而且无论如何,那个magento都默默地失败了) - 但是我不能再浪费时间来讨论这个愚蠢的问题了.

继续.

UPDATE, again. 
Run Code Online (Sandbox Code Playgroud)

花了一些时间,现在,在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>
Run Code Online (Sandbox Code Playgroud)

关键点我会为其他人处理这个问题:

布局xml指令调用magento类中的可用方法.在这种情况下,Page.xmls"Left"块是类型Mage_Core_Block_Text,其继承Mage_Core_Block_Abstract包含方法unsetChildinsert.

来自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;
    }
Run Code Online (Sandbox Code Playgroud)

  /**
     * 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;
    }
Run Code Online (Sandbox Code Playgroud)

本地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>
Run Code Online (Sandbox Code Playgroud)

最终,这使得local.xml成为操作系统的一种非常强大的方法,但是如果您不熟悉它和magento系统,请准备好几周或几个月的工作来真正了解它.

干杯


又一次更新

我现在已经多次遇到这个问题了,我想移动的一个块已被移除.这是一个问题,因为任何已从布局中删除的块都会被永久化.

但是,使用Alan Storm非常方便的Unremove插件,您可以撤消已完成的操作:

<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>
Run Code Online (Sandbox Code Playgroud)

它通过观察布局对象以及构建已删除块的列表来管理此专长,稍后可以引用它们.

太好了!

Bos*_*h99 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>
Run Code Online (Sandbox Code Playgroud)

Magento建议将此包含在您的中local.xml,并且它已被证明是一种有效的技术.