I want to display a vertical menu instead of the default horizontal menu for category and subcategory
-
if you have HTML design then you will override the topmenu.php class and use your css classes– WaqarCommented Mar 12, 2019 at 10:14
-
@Waqar can you please explain in more detail– Harsh JayswalCommented Mar 12, 2019 at 10:16
-
Just an idea, You are using Magento basic theme, you have to purchase the free or paid theme with your own ideas.– zusCommented May 29, 2020 at 7:49
2 Answers
create a di.xml file in your module etc folder and add the folowing code
<?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="Magento\Theme\Block\Html\Topmenu" type="Vendor\ModuleName\Block\Topmenu" />
</config>
and create a block file in vendor/modulename/Block/Topmenu.php and override function that is creating the menu by using following code;
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Vendor\ModuleName\Block;
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
$html = '';
if (!$child->hasChildren()) {
return $html;
}
$colStops = [];
if ($childLevel == 0 && $limit) {
$colStops = $this->_columnBrake($child->getChildren(), $limit);
}
$html .= '<ul class="level' . $childLevel . ' ' . $childrenWrapClass . '">';
$html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
$html .= '</ul>';
return $html;
}
protected function _getHtml(
\Magento\Framework\Data\Tree\Node $menuTree,
$childrenWrapClass,
$limit,
array $colBrakes = []
) {
$html = '';
$children = $menuTree->getChildren();
$parentLevel = $menuTree->getLevel();
$childLevel = $parentLevel === null ? 0 : $parentLevel + 1;
$counter = 1;
$itemPosition = 1;
$childrenCount = $children->count();
$parentPositionClass = $menuTree->getPositionClass();
$itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-';
/** @var \Magento\Framework\Data\Tree\Node $child */
foreach ($children as $child) {
if ($childLevel === 0 && $child->getData('is_parent_active') === false) {
continue;
}
$child->setLevel($childLevel);
$child->setIsFirst($counter == 1);
$child->setIsLast($counter == $childrenCount);
$child->setPositionClass($itemPositionClassPrefix . $counter);
$outermostClassCode = '';
$outermostClass = $menuTree->getOutermostClass();
if ($childLevel == 0 && $outermostClass) {
$outermostClassCode = ' class="' . $outermostClass . '" ';
$currentClass = $child->getClass();
if (empty($currentClass)) {
$child->setClass($outermostClass);
} else {
$child->setClass($currentClass . ' ' . $outermostClass);
}
}
if (is_array($colBrakes) && count($colBrakes) && $colBrakes[$counter]['colbrake']) {
$html .= '</ul></li><li class="column"><ul>';
}
$html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>';
$html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>' . $this->escapeHtml(
$child->getName()
) . '</span></a>' . $this->_addSubMenu(
$child,
$childLevel,
$childrenWrapClass,
$limit
) . '</li>';
$itemPosition++;
$counter++;
}
if (is_array($colBrakes) && count($colBrakes) && $limit) {
$html = '<li class="column"><ul>' . $html . '</ul></li>';
}
return $html;
}
protected function _getMenuItemClasses(\Magento\Framework\Data\Tree\Node $item)
{
$classes = [];
$classes[] = 'level' . $item->getLevel();
$classes[] = $item->getPositionClass();
if ($item->getIsCategory()) {
$classes[] = 'category-item';
}
if ($item->getIsFirst()) {
$classes[] = 'first';
}
if ($item->getIsActive()) {
$classes[] = 'active';
} elseif ($item->getHasActive()) {
$classes[] = 'has-active';
}
if ($item->getIsLast()) {
$classes[] = 'last';
}
if ($item->getClass()) {
$classes[] = $item->getClass();
}
if ($item->hasChildren()) {
$classes[] = 'parent';
}
return $classes;
}
}
Use your vendor and module name
-
-
You may need to change template file according to your theme.– WaqarCommented Mar 12, 2019 at 10:34
-
-
yourt_heme/Magento_Theme/templates/html/topmenu.phtm is the file where where you can start the menu– WaqarCommented Mar 12, 2019 at 10:35
-
should I copy that entire file in my template and call that file using layout it will work or not ?? I am not having any idea of how to display menu vertically I have used your code there are no changes Commented Mar 12, 2019 at 10:41
I have the same question. Can you please help me?
Best: Top navigation only CMS Pages and Main Category and vertical menu all categories with all subcategories.
OK: Same Menu, that I tweak only with CSS that it looks like in {Best}.
I have a own Template (copy of Luma) but I cant find in Magento_Theme/ a folder templates, only layout and web. Where are the files? In blank theme there are also missing.