Magento 2 – Adding Dynamic Elements to Admin Menu

adminhtmladminmenumagento2

I need to add some elements in the admin menu based on some conditions (custom logic) so I cannot use adminhtml/menu.xml for that. (or can I?)

For example, I need to add inside the products main menu the next structure

  • Accessories
    • Accessories type 1
    • Accessories type 2.
    • Accessories type N.

Numbers 1 to N are dynamic and may come from different extensions that link to the same class.
Is there an event I can hook on? Or some class I can pluginize?

Best Answer

The solution for Magento 1 mentioned by @avesh in the comments above also applies to Magento 2. You can still listen to event adminhtml_block_html_before. The sample code below adds a "Test Menu" under "Catalog".

app/code/Vendor/Module/etc/adminhtml/events.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="adminhtml_block_html_before">
        <observer name="Vendor_Module_Custom_Menu" instance="Vendor\Module\Observer\AdminhtmlBlockHtmlBefore" />
    </event>    
</config>

app/code/Vendor/Module/Observer/AdminhtmlBlockHtmlBefore.php:

<?php
namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;

class AdminhtmlBlockHtmlBefore implements ObserverInterface
{        
    protected $menuItemFactory;

    public function __construct(
        \Magento\Backend\Model\Menu\Item\Factory $menuItemFactory
    ) {
        $this->menuItemFactory = $menuItemFactory;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $block = $observer->getBlock();

        if($block instanceof \Magento\Backend\Block\Menu){
            $menuModel = $block->getMenuModel();

            $itemData = array(
                'id'          => 'testMenuId',
                'title'       => 'Test Menu',
                'resource'    => 'Magento_Catalog::products',               
                'action'      => 'module/action/'
            );

            $item = $this->menuItemFactory->create($itemData);
            $menuModel->add($item, 'Magento_Catalog::inventory', 100); //$menuModel->add($item, $parentId, $index)
        }
    }
}
Related Topic