Sometimes you want to add menu item to main menu bar of magento to redirect to the page you added in extension . This article will show you two ways to add a menu item.
1 : Add menu item via plugin
please create plugin folder in your module and add file Topmenu.php and below code
<?php
namespace Vendor\Module\Plugin;
use Magento\Framework\Data\Tree\Node;
class Topmenu
{
/**
* @var \Vendor\Module\Helper\Data
*/
protected $helper;
/**
* @var \Magento\Framework\Data\TreeFactory
*/
protected $treeFactory;
/**
* @var \Magento\Framework\App\RequestInterface
*/
protected $request;
/**
* Topmenu constructor.
*
* @param \Vendor\Module\Helper\Data $helper
* @param \Magento\Framework\Data\TreeFactory $treeFactory
* @param \Magento\Framework\App\RequestInterface $request
*/
public function __construct(
\Magento\Framework\Data\TreeFactory $treeFactory,
\Magento\Framework\App\RequestInterface $request,
\Vendor\Module\Helper\Data $helper
) {
$this->treeFactory = $treeFactory;
$this->request = $request;
$this->helper = $helper;
}
/**
* @param \Magento\Theme\Block\Html\Topmenu $subject
* @param string $outermostClass
* @param string $childrenWrapClass
* @param int $limit
*
* @return array
*/
public function beforeGetHtml(
\Magento\Theme\Block\Html\Topmenu $subject,
$outermostClass = '',
$childrenWrapClass = '',
$limit = 0
)
{
$subject->getMenu()->addChild(
new Node(
$this->getMenuNewItem(),
'id',
$this->treeFactory->create()
)
);
return [$outermostClass, $childrenWrapClass, $limit];
}
/**
* @return array
*/
private function getMenuNewItem()
{
return [
'name' => __("New Menu item"),
'id' => 'menuitem-node',
'url' => $this->helper->getUrlRouter()
];
}
}
Because in the file Topmenu.php we call the file helper Data.php let’s add the file Data.php and add the line of code.
<?php
namespace Vendor\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
public $_storeManager;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager
)
{
parent::__construct($context);
$this->_storeManager = $storeManager;
}
public function getUrlRouter()
{
return $this->_storeManager->getStore()->getBaseUrl()."new_menuitem";
}
}
remember that new_menuitem is the route that you created in the routes.xml file and created new through the controller
Next we call to add the menu created through the file Vendor/Module/etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!--Plugin List-->
<type name="Magento\Theme\Block\Html\Topmenu">
<plugin name="new_itemmenu_topmenu" type="Vendor\Module\Plugin\Topmenu"/>
</type>
</config>
2 . Add menu item via default.xml
if add this way magento will add through catalog.topnav you need to add this code in file Vendor/Module/view/frontend/layout/default.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="catalog.topnav">
<block class="Vendor\Module\Block\Topmenu" name="link-menuitem" template="Vendor_Module::topmenu.phtml" after="-" />
</referenceBlock>
</body>
</page>
Next, create the topmenu file in the Vendor/Module/view/frontend/templates/topmenu.phtml directory
<li class="level0 category-item level-top"><a class="level-top" href="<?php echo $this->getUrl('new_menuitem') ?>"><span><?= __(New Menu Item)?></span></a></li>
Next is the block file Vendor\Module\Block\Topmenu.php
<?php
namespace Vendor\Module\Block;
class Topmenu extends \Magento\Framework\View\Element\Template
{
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
}
Please leave your comments for any questions or modifications below.