We sacrifice by not doing any other technology, so that you get the best of Magento.

We sacrifice by not doing any other technology, so that you get the best of Magento.

    Let’s say I have to show category images to navigation menu.

    Magento doesn’t take a use of any kind of template to draw the whole menu, but a function which will retrieve all the categories & create li/ul tree.

    In Magento 2.1.X you can easily perform this task by rewriting the _getHtml() function from the class located at MagentoThemeBlockHtmlTopmenu. It’s kind of function which will call to itself again-n-again. We will make an observer which will add our programmed code in the navigation menu.

    1. Create your module

    Let’s start by creating one folder in app/code/Vendor/ModuleName.
    Here, ‘vendor’ is the namespace for your modules.
    app/code/Vendor/ModuleName/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="Vendor_ModuleName" setup_version="0.0.1"/></config>

    Now the module registration:

    <?php
    /**
     * Registration file
     *
     * @category  Vendor
     * @package   VendorModuleName
     * @author    Your Name <your@name.com>
     * @copyright 2017 Vendor
     * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     */
    MagentoFrameworkComponentComponentRegistrar::register(
        MagentoFrameworkComponentComponentRegistrar::MODULE,
        'Vendor_ModuleName',
        __DIR__
    );

    2. Rewrite this class MagentoThemeBlockHtmlTopMenu

    Create a file called di.xml to declare the rewriting of the class where the _getHtml() method is going to get called:
    app/code/Vendor/NavigationMenu/etc/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">
        <preference for="MagentoThemeBlockHtmlTopmenu" type="VendorNavigationMenuRewriteBlockHtmlTopmenu" />
    </config>

    After this you are allowed to create the class which will allow to rewrite the method. Now the following points:

    app/code/Vendor/NavigationMenu/Rewrite/Block/Html/Topmenu.php

    <?php
    /**
     * Vendor Project
     * Module Vendor/ModuleName
     *
     * @category  Vendor
     * @package   VendorModuleName
     * @author    Your Name <your.name@email.com>
     * @copyright 2017 Vendor
     * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     */
    namespace VendorModuleNameRewriteBlockHtml;
     
    use MagentoFrameworkDataTreeNode;
    use MagentoFrameworkDataObject;
    use MagentoFrameworkViewElementTemplate;
     
    /**
     * Plugin ModuleName
     *
     * @author    Your Name <your.name@email.com>
     * @copyright 2017 Vendor
     */
    class Topmenu extends MagentoThemeBlockHtmlTopmenu
    {
        /**
         * Recursively generates top menu html from data that is specified in $menuTree
         *
         * @param Node   $menuTree          menu tree
         * @param string $childrenWrapClass children wrap class
         * @param int    $limit             limit
         * @param array  $colBrakes         column brakes
         * @return string
         *
         * @SuppressWarnings(PHPMD)
         */
        protected function _getHtml(
            Node $menuTree,
            $childrenWrapClass,
            $limit,
            $colBrakes = []
        ) {
            $html = parent::_getHtml($menuTree, $childrenWrapClass, $limit, $colBrakes = []);
     
            $transportObject = new DataObject(['html' => $html, 'menu_tree' => $menuTree]);
            $this->_eventManager->dispatch(
                'vendor_topmenu_node_gethtml_after',
                ['menu' => $this->_menu, 'transport' => $transportObject]
            );
     
            $html = $transportObject->getHtml();
     
            return $html;
        }
    }

    3. Make observer which will triggered by the event

    To perform it we have to create the events.xml configuration file and assign the class which will handle the event:

    app/code/Vendor/NavigationMenu/etc/frontend/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="vendor_topmenu_node_gethtml_after">
            <observer name="vendor_modulename_topmenu" instance="VendorModuleNameObserverAddContentToCategoryTopmenu" />
        </event>
    </config>

    app/code/Vendor/NavigationMenu/Observer/AddContentToCategoryTopmenu.php

    <?php
    /**
     * Topmenu catalog observer to add custom additional elements
     *
     * @category  Vendor
     * @package   VendorModuleName
     * @author    Your Name <your.name@email.com>
     * @copyright 2017 Vendor
     * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     */
    namespace VendorModuleNameObserver;
     
    use MagentoFrameworkEventObserver;
    use MagentoFrameworkEventObserverInterface;
    use MagentoCatalogApiCategoryRepositoryInterface;
     
    /**
     * Class AddFirstCategoryImageToTopmenu
     * @package VendorModuleName
     */
    class AddContentToCategoryTopmenu implements ObserverInterface
    {
        /**
         * @var CategoryRepositoryInterface $categoryRepository
         */
        protected $categoryRepository;
     
        /**
         * AddFirstCategoryImageToTopmenu constructor.
         *
         * @param CategoryRepositoryInterface $categoryRepository repository
         */
        public function __construct(
            CategoryRepositoryInterface $categoryRepository
        ) {
            $this->categoryRepository = $categoryRepository;
        }
     
        /**
         * @param Observer $observer Observer object
         */
        public function execute(Observer $observer)
        {
            $transport = $observer->getTransport();
            $html      = $transport->getHtml();
            $menuTree  = $transport->getMenuTree();
     
            $parentLevel = $menuTree->getLevel();
            $childLevel = $parentLevel === null ? 0 : $parentLevel + 1;
     
            $menuId = $menuTree->getId();
     
            if ($childLevel == 1 && $this->isCategory($menuId)) {
                $html .= '<li class="category_image" style=""><img src="'.$this->getCategoryImage($menuId).'"/></li>';
            }
     
            $transport->setHtml($html);
        }
     
        /**
         * Retrieves the category image for the corresponding child
         *
         * @param string $categoryId Category composed ID
         *
         * @return string
         */
        protected function getCategoryImage($categoryId)
        {
            $categoryIdElements = explode('-', $categoryId);
            $category           = $this->categoryRepository->get(end($categoryIdElements));
            $categoryName       = $category->getImageUrl();
     
            return $categoryName;
        }
     
        /**
         * Check if current menu element corresponds to a category
         *
         * @param string $menuId Menu element composed ID
         *
         * @return string
         */
        protected function isCategory($menuId)
        {
            $menuId = explode('-', $menuId);
     
            return 'category' == array_shift($menuId);
        }
    }

     

    Fill the below form if you need any Magento relate help/advise/consulting.

    With Only Agency that provides a 24/7 emergency support.

      Get a Free Quote