【问题标题】:overriding a magento block in multiple modules (and how to ignore the other ones)覆盖多个模块中的magento块(以及如何忽略其他模块)
【发布时间】:2010-01-29 12:47:39
【问题描述】:

在 Magento 中,您可以覆盖另一个模块(最常见于 Magento Adminhtml 模块)中的一个模块(或助手,或模型等)。现在我有一个问题,我想覆盖一个已经被其他扩展覆盖的块。有没有办法告诉magento忽略其他模块配置中的<rewrite>标签,类似于布局更新中的<remove>标签?

这里是另一个扩展的配置:

    <blocks>
        <adminhtml>
            <rewrite>
                    <catalog_product_grid>Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
            </rewrite>
        </adminhtml>
    </blocks>

这里是我的扩展的配置:

    <blocks>
        <adminhtml>
            <rewrite>
                    <catalog_product_grid>Namespace_MyModule_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
            </rewrite>
        </adminhtml>
    </blocks>

我将 Symmetrics_DeliveryTime 中的块的功能集成到我自己的块中,现在我希望 magento 忽略从该模块覆盖的块。

是否有任何 magento 方法可以做到这一点,或者是注释掉配置(这是我现在所做的)的唯一方法,包括稍后更新该模块时的所有麻烦?

【问题讨论】:

    标签: php magento customization


    【解决方案1】:

    如果您将您的模块设置为“依赖”也进行重写的模块,您的配置将被最后读取并且重写应该坚持,在您应该拥有的 app/etc/modules 中的适当文件中:

    <config>
      <modules>
        <Your_Module>
          <active>true</active>
          <codePool>local</codePool>
          <depends>
            <Other_Module/>
          </depends>
        </Your_Module>
      <modules>
    <config>
    

    【讨论】:

    • 工作正常...但是现在对那个其他模块有一个“真正的”依赖,如果没有安装另一个模块,magento 会抱怨...在我的情况下,这没关系,但很干净在magento中多次重写的解决方案会很好......也许有一天;)
    【解决方案2】:

    我查看了类加载,似乎没有一个干净的解决方案。相关的类名加载代码是这样的:

        if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
            return $this->_classNameCache[$groupRootNode][$group][$class];
        }
    
        ...
    
        if (isset($config->rewrite->$class)) {
            $className = (string)$config->rewrite->$class;
    

    所以看起来没有重写-重写之类的东西。放入配置数组的那个就是被加载的那个,一旦被缓存,它就会按请求返回。我也没有看到破解缓存的简单方法。您可以尝试为您的模块获得优先权(我假设通过按字母顺序重命名),但这是一个完全的黑客攻击,以后可能会神秘地失败。这会扼杀配置的可能性。

    同样令人讨厌:看起来 Magento 只在两个地方请求该网格,在 Mage_Adminhtml_Block_Catalog_Product(您可以轻松覆盖)内,但也在 Mage_Adminhtml_Catalog_ProductController(天啊!)内。根据您的用例,考虑覆盖目录产品块并用您自己的函数替换 _prepareLayout() 函数。如果您还想覆盖控制器,您将需要创建自己的控制器(从 Mage_Adminhtml_Catalog_ProductController 继承)并在您的配置中定义重写以将 admin/catalog/product/grid 引导到您的操作。很痛苦,但至少完成了你的目标。

    希望对你有帮助,

    【讨论】:

      【解决方案3】:

      与其重写 catalog_product_grid,为什么不在 Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid 上进行扩展?这样,Symmetrics 模块将保留其所有功能,您可以添加自己的功能。

      所以而不是:

      <blocks>
          <adminhtml>
              <rewrite>
                      <catalog_product_grid>Symmetrics_DeliveryTime_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
              </rewrite>
          </adminhtml>
      </blocks>
      

      这样做:

      <blocks>
          <adminhtml>
              <rewrite>
                      <deliverytime_catalog_product_grid>Namespace_MyModule_Block_Adminhtml_Catalog_Product_Grid</deliverytime_catalog_product_grid>
              </rewrite>
          </adminhtml>
      </blocks>
      

      当然比你的 app/etc/modules 文件中的依赖更合适。

      【讨论】:

        【解决方案4】:

        使用观察者之后或之前的布局来解决这个问题的最佳方法。

        app/code/local/My/Module/etc/config.xml

        <config>
        <adminhtml>
            <events>
                <core_block_abstract_prepare_layout_before>
                    <observers>
                        <mymodule>
                            <!-- Add column to catalog product grid -->
                            <class>mymodule/adminhtml_observer</class>
                            <method>onBlockHtmlBefore</method>
                        </mymodule>
                    </observers>
                </core_block_abstract_prepare_layout_before>
            </events>
        </adminhtml>
        

        或者可以使用事件:core_block_abstract_prepare_layout_after

        在观察者中:

        class My_Module_Model_Adminhtml_Observer
         {
           public function onBlockHtmlBefore(Varien_Event_Observer $observer) {
            $block = $observer->getBlock();
            if (!isset($block)) return;
        
            switch ($block->getType()) {
                case 'adminhtml/catalog_product_grid':  //or here you can put any other block 
        
                    /*For example i am using Mage_Adminhtml_Block_Catalog_Product_Grid, and want  to add a column*/
        
                    $block->addColumn('COLUMN_ID', array(
                        'header' => Mage::helper('mymodule')->__('COLUMN HEADER'),
                        'index'  => 'COLUMN_ID',
                    ));
                     break;
        
                    case 'adminhtml/catalog_product_edit_tabs':
        
                     /*Or i want to add new tab to admin product edit*/
                      /* @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs */
                    $block->addTab('tab_name', array(
                                'label'     => Mage::helper('catalog')->__('Tab Tilte'),
                                'content'   => $block->getLayout()->createBlock('modulename/adminhtml_product_edit_tabname')->toHtml(),
                                'after'     => 'inventory',
                    ));
                    break;
            }
          }
        }
        

        在添加选项卡时,您可以参考产品编辑选项卡,使用您的模块将表单字段添加到其中。

        希望这对某人有所帮助:)

        【讨论】:

          猜你喜欢
          • 2017-01-20
          • 1970-01-01
          • 2016-05-18
          • 2014-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-21
          • 1970-01-01
          相关资源
          最近更新 更多