0

I want to add custom links to the topmen / a submenu in the topmenu (I need the links for custom filters). To achieve this, I have created a plugin:

app/code/Vendor/Module/etc/frontend/di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <!-- Plugin to add custom topmenu links -->
    <type name="Magento\Theme\Block\Html\Topmenu">
        <plugin name="Module-topmenu" type="Vendor\Module\Plugin\Block\Topmenu" sortOrder="1"/>
    </type>
</config>

app/code/Vendor/Module/Plugin/Block/Topmenu.php:

namespace Vendor\Module\Plugin\Block;


class Topmenu
{
    /**
     * @var NodeFactory
     */
    protected $nodeFactory;

    public function __construct(
        NodeFactory $nodeFactory
    ) {
        $this->nodeFactory = $nodeFactory;
    }

    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $subject,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {

        $node = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray(),
                'idField' => 'unique-id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );

        $subject->getMenu()->addChild($node);
    }

    protected function getNodeAsArray()
    {
        return [
            'name' => 'Testlink',
            'id' => 'testlink',
            'url' => 'http://www.example.com/',
            'has_active' => false,
            'is_active' => false // (expression to determine if menu item is selected or not)
        ];
    }
}

But this does not work, the custom menu link won't appear. Is there an error in my code, or is there another way to add topmenu/submenu links that are not categories?

EDIT: The code seems to be correct. But the site uses a customized theme that did not call the Magento function to render the menu, thus the plugin never ran. Instead, the theme builds the menu "by hand". This issue is nonexistent.

2 Answers 2

0

1 – We have to create app/code/Test/TestCustomMenu/etc/di.xml file where we will define our plugin.

<?xml version="1.0"?>
<!--
/**
* @category   Webkul
* @package    Test_TestCustomMenu
* @author     Webkul Software Private Limited
* @license    https://store.webkul.com/license.html
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- Add Plugin for add custom link in navigation -->
    <type name="Magento\Theme\Block\Html\Topmenu">
        <plugin name="add_menu_item_plugin" type="Test\TestCustomMenu\Plugin\Topmenu" sortOrder="10" disabled="false"/>
    </type>
</config>

2 – Now we have to create app/code/Test/TestCustomMenu/Plugin/Topmenu.php . In this file we will modify default getHtml function.This function return list html which is call in navigation menu.We added after plugin of getHtml function for adding our custom link at the end of pre-generated list of html.

<?php
/**
* @category   Webkul
* @package    Test_TestCustomMenu
* @author     Webkul Software Private Limited
* @license    https://store.webkul.com/license.html
*/

namespace Test\TestCustomMenu\Plugin;

class Topmenu
{
    /**
    * @param Context                                   $context
    * @param array                                     $data
    */
    public function __construct(
        \Magento\Customer\Model\Session $session
    ) {
        $this->Session = $session;
    }


    public function afterGetHtml(\Magento\Theme\Block\Html\Topmenu $topmenu, $html)
    {
        $swappartyUrl = $topmenu->getUrl('testCustomMenu/custommenu');//here you can set link
        $magentoCurrentUrl = $topmenu->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true]);
        if (strpos($magentoCurrentUrl,'testCustomMenu/custommenu') !== false) {
            $html .= "<li class=\"level0 nav-5 active level-top parent ui-menu-item\">";
        } else {
            $html .= "<li class=\"level0 nav-4 level-top parent ui-menu-item\">";
        }
        $html .= "<a href=\"" . $swappartyUrl . "\" class=\"level-top ui-corner-all\"><span class=\"ui-menu-icon ui-icon ui-icon-carat-1-e\"></span><span>" . __("Custom Menu") . "</span></a>";
        $html .= "</li>";
        return $html;
    }
}

After adding above files please run following command :-
php bin/magento setup:di:compile
php bin/magento cache:flush

Now you can check your custom link in navigation menu.

enter image description here

6
  • Thank you for the help, but this won't allow me to add links to existing submenus of categories. I'd need to add custom links to an already existing submenu which contains categories.
    – Dorni
    Commented Jan 17, 2019 at 7:00
  • please check my code now i have updated my code you can add now your custom link easily Commented Jan 17, 2019 at 7:03
  • Thank you for the updated code. I tried it, but unfortunately, no new menu entry appears in the topmenu. It doesn't matter, whether I put the plugin xml tag in the etc/di.xml or the etc/frontend/di.xml file.
    – Dorni
    Commented Jan 17, 2019 at 7:18
  • @Dorni above code working for you ? Commented Jan 17, 2019 at 9:18
  • The code was not working for me. But this is because the customized theme the site uses did not call the regular Magento functions to render the menu. Instead, they built it themselves.
    – Dorni
    Commented Jan 17, 2019 at 9:26
0

You also need to add Preference: <preference for="Magento\Theme\Block\Html\Topmenu" type="Vendor\Module\Block\Html\Topmenu" />

This is the only way the works for me to overwrite the html!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.