Create Admin Menu Item in Magento 2

Create Admin Menu Item in Magento 2

When it comes to Magento customization, every now and then, there’s a need for a custom configuration option that needs to be placed somewhere in the administration menu. Magento 2 comes with well organized admin menu, but what if newly created configuration option doesn’t fit anywhere?

In that case, a new menu item can be created to accommodate that option. Here’s a tutorial on how to do it in Magento 2.

Unlike Magento 1, the admin menu in Magento 2 is located on the left side of the screen. Reason for that is to simplify access to a menu from a tablet or smartphone.

What is a menu item?

Basically, menu item is a link that leads to another admin configuration page. An example of that would be something like this:

href="http://m2.loc/admin/sales/order/index/key/9f8n6825d41694450594r4efc3c779f6df8a8191ffca03f2113ece65436h076e/"

Part of this URL is a sales/order/index, which is an area of interest here. It consists of three parts that need to be defined in menu item XML configuration.

Front Name:		sales
Controller Name:	order
Action Name:		index

There is also a key variable in the link, which serves as a protection from cross site script attacks. This is actually a real reason for menu item to be created the “Magento way”. Any admin request without this variable will be invalidated. Other link parts are created automatically by the Magento.

Create new basic module

In order to demonstrate how menu item is created, a new basic module structure is needed. There’s a nice article on how to create a basic module in Magento 2.

Inchoo/MenuItem/registration.php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Inchoo_MenuItem',
    __DIR__
);

Inchoo/MenuItem/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Inchoo_MenuItem" setup_version="1.0.0" />
</config>

 

Create new menu item

Menus are configured by the file menu.xml which is located in module’s etc/adminhtml folder. It consists of config and menu nodes and add directives. Menu node may consist of multiple add directives.

Inchoo/MenuItem/etc/adminhtml/menu.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <add id="Inchoo_MenuItem::first_level_demo"
             title="Inchoo First Level"
             module="Inchoo_MenuItem"
             sortOrder="9999"
             resource="Magento_Backend::content" />
    </menu>
</config>

As it can be seen from the menu.xml structure, new menu item is typically added using an add directive with it’s parameters. It is wrapped up in a menu tag.

Explanation of the directive’s attributes is as follows:

  • id – unique node identifier, should follow the format: Vendor_Module::menu_item_description
  • title – text that is shown in menu
  • module – current module
  • sortOrder – where to place menu item
  • resource – defines the ACL rule which the admin user must have in order to see and access this menu, it is defined in acl.xml. Otherwise, menu item won’t be rendered. For simplicity, Magento_Backend::content is used.

After running Magento’s CLI command cache:clean, new menu item should be visible. But for now, it leads to nowhere, it is not a hyperlink. It’s not usual for a first level menu items to be hyperlinks, but only to be containers of a second or third levels.

All it takes for a menu item to become an actual link is an action attribute. For menu item that is located on a second level for example, a parent attribute must also be used. It defines on which first level it depends. It can be current module or any other from the menu (e.g. system module Magento_Backend::system). Same logic applies to third level menu item.

Additional attributes:

  • action – defined above, tells Magento to generate link to certain admin controller
  • parent – defines on which first level a menu item depends

Example for a second level menu item with an action:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <add id="Inchoo_MenuItem::first_level_demo"
             title="Inchoo First Level Item"
             module="Inchoo_MenuItem"
             sortOrder="9999"
             resource="Magento_Backend::content" />
 
        <add id="Inchoo_MenuItem::second_level_demo"
             title="Inchoo Second Level Item"
             module="Inchoo_MenuItem"
             sortOrder="0"
             action="menuitem/index/index"
             parent="Inchoo_MenuItem::first_level_demo"
             resource="Magento_Backend::content" />
    </menu>
</config>

 

Flushing the magento cache

After everything is defined, the magento cache should be cleaned with the following CLI command:

php -f bin/magento cache:clean

 

Result

That’s it. The menu item should now be visible in admin menu under the first level “Inchoo First Level Item” at the end and it should lead to a defined action. In this example, for simplicity, action leads to nowhere because module’s controller should be created.

Here’s how it looks like at the end:

Admin Menu Items

In case you feel you could use some extra help with your Magento 2 project, feel free to reach out. We’ve been a trained Magento 2 partner for quite a while now and we’d like to help you make your shop extraordinary! 🙂

You made it all the way down here so you must have enjoyed this post! You may also like:

How to set up taxes in Magento 2 Toni Anicic
Toni Anicic, | 1

How to set up taxes in Magento 2

Magento 2 Customer Groups Configuration Josip Kovacevic
Josip Kovacevic, | 2

Magento 2 Customer Groups Configuration

How did we standardize Magento 2 frontend development? Ljiljana Milkovic
Ljiljana Milkovic, | 8

How did we standardize Magento 2 frontend development?

12 comments

  1. great explanation ..

    how can i add a sub menu (third level item ) to the second level, that will be in a separated menu (not under the parent
    )

  2. Hello im getting a 404 error when click on it…any ideas? I can see the menu item but when click on it i get 404.

    1. In the above example action="menuitem/index/index" is not working because it has no controller associated with it. you have to create it then it will work

    1. Firstly you check your module was installed or not !
      if installed success then clear your catch ..

  3. I have my Index.php in ‘Magento\Grid\Controllers\Adminhtml\Grid\Index.php’, so what should be the action in the second level menu?? please, help.. I’m stuck very badly at this point.

  4. Hi man thanks for the great post

    could you help me guide for creating the custom admin html
    i’ve tried some blog but still having trouble to create a custom admin html page
    will be nice if you create some posts regarding that matter.
    thanks a lot man.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.