Let's create a new module. We'll call it StackExchange_Topmenu
.
you will need the following files.
app/code/StackExchange/Topmenu/registration.php
- the registration file
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'StackExchange_Topmenu',
__DIR__
);
app/code/StackExchange/Topmenu/etc/module.xml
- the module declaration file
<?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="StackExchange_Topmenu" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>
app/code/StackExchange/Topmenu/etc/frontend/di.xml
- di file to declare a plugin
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Theme\Block\Html\Topmenu">
<plugin name="stackexchange-topmenu" type="StackExchange\Topmenu\Plugin\Topmenu" />
</type>
</config>
app/code/StackExchange/Topmenu/Plugin/Topmenu.php
- the actual plugin
<?php
namespace StackExchange\Topmenu\Plugin;
class Topmenu
{
protected $storeManager;
public function __construct(
\Magento\Store\Model\StoreManagerInterface $storeManager
)
{
$this->storeManager = $storeManager;
}
public function beforeGetHtml(
\Magento\Theme\Block\Html\Topmenu $subject,
$outermostClass = '',
$childrenWrapClass = '',
$limit = 0
) {
$storeIds = [4, 5];//replace with the id of your store.
$currentStoreId = $this->storeManager->getStore()->getId();
if (in_array($currentStoreId, $storeIds)) {
$menu = $subject->getMenu();
$newMenuItems = [];
$firstLevel = $menu->getChildren();
foreach ($firstLevel as $menuItem) {
/** @var \Magento\Framework\Data\Tree\Node $menuItem */
//check if menu is a category
if (substr($menuItem->getId(), 0, strlen('category-node-')) == 'category-node-') {
//get all child nodes (second level) and save them in an array
$subItems = $menuItem->getChildren();
foreach ($subItems as $subItem) {
$newMenuItems[] = $subItem;
}
} else { //if menu item is not a category, leave it in place
$newMenuItems[] = $menuItem;
}
}
//remove all menu items
foreach ($firstLevel as $childNode) {
$menu->removeChild($childNode);
}
//put new menu items back;
foreach ($newMenuItems as $newMenuItem) {
$menu->addChild($newMenuItem);
}
}
}
}
now run in the console bin/magento setup:upgrade
to install your module.
Notice: This will remove any top level categories from the menu. If you only have one as you describe it will remove that one. If you have 2 or more, it will remove all top level categories and add the second level categories in the menu.
If you have other menu links that are not categories they will remain unchanged.
Edit
I added an if
statement inside the plugin to make it apply for a single store. Check the id of the store and replace the 1
in $storeId = 1;
with what you need.
If you want to do this in a prettier way, you can add a yes/no config setting that will determine if the store should use only second level categories, and read that value in the plugin.
If not, you can leave it like this and just change the store id.