2

So I've already hooked the "page_block_html_topmenu_gethtml_before" event with the observer class, I can add items to the menu tree, and it works fine, but I can't prepend items to the menu tree object. here is my code:

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="page_block_html_topmenu_gethtml_before">
        <observer name="topmenu_load_pre" instance="<VENDOR>\<MODULE>\Observer\TopmenuLoadPre" />
    </event>
</config>

TopmenuLoadPre.php:

<?php

namespace <VENDOR>\<MODULE>\Observer;

class TopmenuLoadPre implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @var \Magento\Framework\UrlInterface
     */
    private $_urlInterface;
    /**
     * @var \Magento\Framework\App\Request\Http
     */
    private $_request;

    /**
     * TopmenuLoadPre constructor.
     * @param \Magento\Framework\UrlInterface $urlInterface
     * @param \Magento\Framework\App\Request\Http $request
     */
    public function __construct(
        \Magento\Framework\UrlInterface $urlInterface,
        \Magento\Framework\App\Request\Http $request
    )
    {
        $this->_urlInterface = $urlInterface;
        $this->_request = $request;
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Framework\Data\Tree\Node $menu */
        $menu = $observer->getData('menu');

        // we don't have the option to prepend menu item, so...
        // TODO: clone menu tree

        // remove all menu items
        foreach ($menu->getChildren() as $node) {
            $menu->removeChild($node);
        }

        // add item that I want to be first
        $this->addItem($menu, 'First One', 'very-left-one');

        // TODO: add the system default menu items here.

    }

    /**
     * @param \Magento\Framework\Data\Tree\Node $parentNode
     * @param string $name
     * @param string $slug
     * @return \Magento\Framework\Data\Tree\Node
     */
    private function addItem($parentNode, $name, $slug) {
        $data = [
            'name' => __($name),
            'url' => $this->_urlInterface->getUrl($slug),
            'id' => 'uid-' . $slug,
            'is_active' => ( $this->_request->getFrontName() == $slug ),
        ];
        $newNode = new \Magento\Framework\Data\Tree\Node($data, 'id', $parentNode->getTree());
        $parentNode->addChild($newNode);
        return $newNode;
    }

}

The only reason I'm not getting rid of the default menu is that it already has mobile menu support and automatically adds these items in the mobile sections-navigation.

Any help is greatly appreciated. Thanks.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.