Magento在小部件中使用自己的句柄不起作用

时间:2010-08-11 21:34:01

标签: magento widget

我发现我可以使用此脚本添加自己的布局句柄:

$this->getLayout()->getUpdate()->addHandle('myhandle');

然后我检查了Alan Storm Layout查看器:http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz

?showLayout =手柄

  

处理此请求

     
      
  1. 默认
  2.   
  3. cms_page
  4.   
  5. STORE_default
  6.   
  7. THEME_frontend_default_default
  8.   
  9. cms_index_index
  10.   
  11. page_two_columns_left
  12.   
  13. customer_logged_out
  14.   
  15. myhandle
  16.   

有我的句柄,但我的自定义布局xml没有使用。

这是我的xml:

<?xml version="1.0"?>
<layout version="0.1.0">

    <myhandle>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </myhandle>
</layout>

这样可以正常工作,因此加载了xml文件:

<?xml version="1.0"?>
<layout version="0.1.0">

    <default>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </default>
</layout>

怎么了? 为什么不能使用这个解决方案?

如果不是正确的方式,如何为小部件使用的页面添加自定义css和javascript?

更新: 以下是可能接近解决方案的内容:

如果我在向页面添加新句柄后添加此代码:

$this->getLayout()->getUpdate()->fetchPackageLayoutUpdates('myhandle');
$this->getLayout()->generateXml();

在此之后,“index.php?showLayout = page”调用会在xml中写入句柄代码,但页面不会使用它。

2 个答案:

答案 0 :(得分:7)

这方面的长期和短期是你真的不想以这种方式注入布局句柄。它变得非常复杂(复杂到足以让我无法一直快速地关注Stack Overflow答案),但是

  1. 如果在从控制器调用$ this-&gt; loadLayout()之前添加句柄,那就太快了。

  2. 如果在调用$ this-&gt; loadLayout()后添加句柄,则为时已晚。

  3. 这是一个实验,尝试修改基本动作控制器

    中的loadLayout方法
    File: app/code/core/Mage/Core/Controller/Varien/Action.php
    public function loadLayout($handles=null, $generateBlocks=true, $generateXml=true)
    {    
        // if handles were specified in arguments load them first
        if (false!==$handles && ''!==$handles) {
            $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
        }
    
        //YOUR NEW CALL HERE
        $this->getLayout()->getUpdate()->addHandle('myhandle');         
    
        ...
    

    这应该可以使用并应用你的布局。现在,在生产中执行此操作将是一个坏主意,我只提到它,以显示需要在非常特定的时间布局渲染过程中添加句柄。作为最终程序员,插入布局句柄并不是你的工作。

    布局系统旨在成为设计者和原始PHP系统代码之间的层。既然你显然能够编写PHP代码,我会考虑直接将你的javascript注入head block pre-render。

        //from a controller, but could be modified to be used elsewhere
        //also pseudo code
    $this->getLayout()->getBlock('header')->append(
        $this->getLayout()
        ->createBlock('core/text', 'some-unique-name')
        ->setText('<script type="text/javascript" src="/foo/baz/bar.js"></script>')
    );
    

答案 1 :(得分:2)

如果你想添加一个全新的句柄,最好的解决方案可能是用观察者添加句柄。如果你有一个拥有自己URL的模块,那么它已经有了它独特的句柄。

创建一个调用正确句柄的模块。

创建您的etc / config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Ho_AttributeSetHandle>
            <version>0.1.0</version>
        </Ho_AttributeSetHandle>
    </modules>
    <global>
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <attributesethandle>
                        <class>Ho_AttributeSetHandle_Model_Observer</class>
                        <method>addAttributeSetHandle</method>
                    </attributesethandle>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </global>
</config>

在我的例子中,Model / Observer.php的代码:

<?php
class Ho_AttributeSetHandle_Model_Observer
{
    /**
     * Converts attribute set name of current product to nice name ([a-z0-9_]+).
     * Adds layout handle PRODUCT_ATTRIBUTE_SET_<attribute_set_nicename> after
     * PRODUCT_TYPE_<product_type_id> handle
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer)
    {
        $product = Mage::registry('current_product');

        /**
         * Return if it is not product page
         */
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $attributeSet = Mage::getModel('eav/entity_attribute_set')->load($product->getAttributeSetId());

        /* Convert attribute set name to alphanumeric + underscore string */
        $niceName = strpos($product->formatUrlKey($attributeSet->getAttributeSetName()), '-') !== FALSE
                    ? str_replace('-', '_', $product->formatUrlKey($attributeSet->getAttributeSetName()))
                    : $product->formatUrlKey($attributeSet->getAttributeSetName());
        $niceName = strpos($niceName, ' ') !== FALSE ? str_replace(' ', '_', $product->formatUrlKey($niceName)) : $niceName;

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer->getEvent()->getLayout()->getUpdate();
        $handles = $update->getHandles(); // Store all handles in a variable
        $update->resetHandles(); // Remove all handles

        /**
         * Rearrange layout handles to ensure PRODUCT_ATTRIBUTE_SET_<attribute_set>
         * handle is added last
         */
        foreach ($handles as $handle) {
            $update->addHandle($handle);
            if ($handle == 'PRODUCT_TYPE_' . $product->getTypeId()) {
                $update->addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName);
            }
        }
    }
}

别忘了创建app / etc / modules / Ho_AttributeSetHandle.xml:

<config>
    <modules>
        <Ho_AttributeSetHandle>
            <active>true</active>
            <codePool>local</codePool>
        </Ho_AttributeSetHandle>
    </modules>
</config>