动态改变 Magento 的 adminhtml 菜单选项

Posted

技术标签:

【中文标题】动态改变 Magento 的 adminhtml 菜单选项【英文标题】:Dynamically changing Magento's adminhtml menu option 【发布时间】:2012-04-03 01:09:37 【问题描述】:

我正在开发一个“为了好玩”的项目,我希望将它作为一个“为了好玩”的开源项目发布。我已经构建了一个 Arduino 网络连接订单通知器,并且正在构建它的 Magento adminhtml 界面端。对于我正在做的事情来说,这可能看起来过于复杂,但它还有其他对我有用的应用程序,我正在尝试学习新的东西。

话虽如此,我在 Magento 后端的“报告”旁边创建了一个新的“Arduino”adminhtml 菜单项。在某些时候,来自 Arduino 的特定反馈可能会自动禁用模块,在这种情况下,我的目标是从页面中删除菜单项,除非还有其他子菜单项,在这种情况下,我只删除模块特定的菜单项.同样,这对于这个项目来说似乎不太现实,但为了尽可能“正确”地做到这一点,这是我的目标,让其他人可能添加“Arduino”菜单项的可能性保持开放。

现在,如果缓存已关闭,我可以正常工作,没有问题。这是另一种说法,“这不起作用,因为显然每个人都会打开缓存。”也就是说,这是我开始使用的代码:

/**
 * Used to disable the Arduino menu option dynamically.
 *
 * @param Varient_Event_Observer $observer
 */
public function controllerActionLayoutGenerateBlocksBefore(Varien_Event_Observer $observer)

    //We only want to disable the arduino menu if our module was specifically disabled in backend
    if(Mage::helper('mynamespace_myarduinomodule')->isDisabled())
    
        /* @var $arduinoItems Varien_Simplexml_Element */
        /* @var $parent Varien_Simplexml_Element */
        $arduinoItems = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode('menu/arduinomenu/children');
        $parent = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode('menu');

        //If there are other menu options in the arduino menu option we only want to hide
        //the menu items related to our specific module, leaving the top level menu item alone
        if($arduinoItems->children()->count() > 1)
        
            $parent->setNode("arduino/children/myarduinomodule", "", true);
        
        //But, if not, then we want to hide the entire arduino tab
        else
        
            $parent->setNode("arduino", "", true);
        
    

    return $this;


这显然会增加一些开销,但它只是在 adminhtml 部分。现在,我的目标是有一个“好的”解决方案,但我不确定是否有一个。我读过this very good blog post,虽然我认为这样的事情可能对我的目的有用(相反),但我更愿意创建一个不使用类重写的模块,这样我就不需要关心其他模块重写同一个类。

有人对我如何解决这个问题有任何建议吗?如果我要将自定义菜单项添加到现有的“父”菜单项(例如,如果我要在“系统”下方添加我的 Arduino 选项),同样的缓存问题吗?

感谢您的宝贵时间和宝贵的资源!

编辑:

登录/退出似乎可以“修复”我现有的问题并正确更新菜单。我当然不想强迫用户注销,但也许某处可能有解决方案?

【问题讨论】:

我开始认为我的解决方案对于我的特定情况可能是可以接受的,如果他们尝试访问我的自定义后端之一,我可以简单地将用户重定向回仪表板或显示适当的消息页面/控制器。我仍然希望在用户退出后端之前自动删除我的菜单选项。 如果我没记错的话,你会这样做:假设你有很多扩展,你想在一个可用的菜单下收集取决于扩展。如果客户购买了扩展并安装了系统,扩展选项应该出现在菜单中。正确的?另外,你的问题到底是什么? 如果你需要隐藏东西,我会使用一些 jQuery 或 Prototype 来动态隐藏元素。让页面在数据库(或某处)中查找一个字段并从那里开始 你需要在你的缓存中打一个洞,这是一个很好的阅读:***.com/questions/8126548/… 请记住,您安装的大多数插件都会要求您注销并重新登录,因此它们的所有更改都会反映出来,所以我想请用户这样做是可以的也是。 【参考方案1】:

似乎使它工作的唯一方法是每次进行更改时清理菜单缓存。您可以使用下一个代码:

Mage::app()->getCache()->clean(
    Zend_Cache::CLEANING_MODE_MATCHING_TAG, array(Mage_Adminhtml_Block_Page_Menu::CACHE_TAGS)
);

【讨论】:

【参考方案2】:

关于如何删除项目而不在菜单上留下空文本的代码示例:

/**
 * Used to disable the Arduino menu option dynamically.
 *
 * @param Varient_Event_Observer $observer
 */
public function controller_action_layout_render_before(Varien_Event_Observer $observer)

    //We only want to disable the arduino menu if our module was specifically disabled in backend
    if(Mage::helper('mynamespace_myarduinomodule')->isDisabled())
    
    $_config = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode();


    if($_config->menu->arduino->children)
        unset($_config->menu->arduino->children->myarduinomodule);
    else
        // hide the tab altogether
        unset($_config->menu->arduino);
    
    Mage::getSingleton('admin/config')->getAdminhtmlConfig()->setXml($_config);

    return $this;


【讨论】:

以上是关于动态改变 Magento 的 adminhtml 菜单选项的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Magento 中更改 adminhtml 目录产品编辑中的选项卡顺序

Magento2自定义模块新型控制器发行

如何在Magento(麦进斗)导入CSV文件中的产品价格的变化?

将配置保存为非管理员用户时,Magento 付款方式访问被拒绝

无效的配置字段后端模型:adminhtml/system_config_backend_web_secure_offloaderheader

magento 翻译使用实例