How to add Products to Topmenu in Magento 2
Let’s say your company sells one product. This deserves the spotlight, right? Let’s say you want to give your product a prominent place in the topmenu. Since Magento 2 natively only supports adding categories to its topmenu, you’re up for a challenge! Today I’ll show you how to create a module which allows you to add products to your topmenu.
Creating a Magento 2 module to add Products to Topmenu
Like with everything in life, creating a module to add products to your topmenu is easy if you know what you’re doing. (Uh-duh…) Aren’t I great at SEO writing? To follow this tutorial you’ll need two cups of programming skills and a tea spoon of Magento (2) development skills.
For those of my loyal readers who came here hoping to find a ready-to-install module… GET OUT!
No, just kidding!
Scroll to the bottom of the page and enjoy your new fancy topmenu!
Now we separated the men/women from the boys/girls, let’s get down to business.
There are multiple ways to approach this. E.g. the Magento_Catalog
module adds its categories using a Before-plugin to hook into Magento_Theme
‘s getHtml()
-method.
In this tutorial I will hook into the page_block_html_topmenu_gethtml_before
-event using an Observer.
Why? Granted that plugins offer more freedom and flexibility and might even perform better, I feel events are a way of communicating among developers. Like one developer is whispering in another developer’s ear: ‘I’d like you to extend my code here…‘
So when an event is available, I’ll respect the effort to communicate and build an Observer instead of a Plugin. But I might update this post some time and add a plugin. Who knows!
Building the Foundation
Before we start creating the Observer (which is basically all we need to do) we need to create a basic Magento 2-module. Consisting of two files:
- a
registration.php
, - and an
etc/module.xml
.
In this example, the module is called Dan0sz/TopmenuProducts
. Which means you should create that path inside your app/code
-folder (case-sensitive) and add the following files:
registration.php
<?php | |
/** | |
* @author: Daan van den Bergh | |
* @url: https://daan.dev | |
* @package: Dan0sz/TopmenuProducts | |
* @copyright: (c) 2019 Daan van den Bergh | |
*/ | |
\Magento\Framework\Component\ComponentRegistrar::register( | |
\Magento\Framework\Component\ComponentRegistrar::MODULE, | |
'Dan0sz_TopmenuProducts', | |
__DIR__ | |
); |
etc/module.xml
<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
/** | |
* @author: Daan van den Bergh | |
* @url: https://daan.dev | |
* @package: Dan0sz/TopmenuProducts | |
* @copyright: (c) 2019 Daan van den Bergh | |
*/ | |
--> | |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> | |
<module name="Dan0sz_TopmenuProducts" setup_version="1.0.0"> | |
<sequence> | |
<module name="Magento_Catalog" /> | |
</sequence> | |
</module> | |
</config> |
Observing the Event
Before creating the Observer, we need to register our class to the event. In this case, the page_block_html_topmenu_gethtml_before
-event.
etc/events.xml
<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
/** | |
* @author: Daan van den Bergh | |
* @url: https://daan.dev | |
* @package: Dan0sz/TopmenuProducts | |
* @copyright: (c) 2019 Daan van den Bergh | |
*/ | |
--> | |
<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="dan0sz_topmenu_products_gethtml_before" instance="Dan0sz\TopmenuProducts\Observer\TopmenuGetHtmlBefore" /> | |
</event> | |
</config> |
Creating the Observer
This is the hardest part. Just remember. If you want to give up, that’s okay. No one is judging you. Except for Judgetin Timberlake over here:
The file below requires some modification from your side. Referring to line 80, read the example code and comments I’ve added.
Observer/TopmenuGetHtmlBefore.php
The simplest way to add products to your topmenu is to specify their entity ID’s in an array, the downside to this is that you’d have to hard-code it. Making it a not-so transportable module between different stores.
Download Topmenu Products for Magento 2
In Top Menu Products for Magento 2 I added a product attribute, collecting all products having the ‘Add to Top Menu?’-attribute enabled. I added a sort order, to specify the order of the menu-items and a configurable option to display products before or after the existing category topmenu items.
I know, I can be a bit of a show-off!
Download it from Github or install it using composer by running composer require dan0sz/topmenu-products-magento2
from a terminal.
Summary
Add products to topmenu in Magento 2 can have many use-cases. In this tutorial I’ve shown you how to add products to Magento 2’s topmenu using an Observer. We’ve touched upon the discussion when to choose Plugins or Observers, but went along to use an Observer and implemented it into a basic Magento 2 plugin.