Magento – magento2.2 override topmenu.php: _addSubMenu()

magento2.2override-blocktopmenu

I am trying to override the Topmenu Module Block but I can not understand why it fails.
I am trying to override the following method:

magento/module-theme/Block/Html/Topmenu.php:_addSubMenu(…)

I have created the following folders/files:
app/code/Custom/Theme/Block/Html/Topmenu.php (If it works, "lala" should be appeared at the menu):

Topmenu.php
<?php

namespace Custom\Theme\Block\Html;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
    $html = '';
    if (!$child->hasChildren()) {
        return $html;
    }

    $colStops = null;
    if ($childLevel == 0 && $limit) {
        $colStops = $this->_columnBrake($child->getChildren(), $limit);
    }

    $html .= '<ul class="level' . $childLevel . ' ' . $childrenWrapClass . '">';
    $html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
    $html .= '<li>lala</li></ul>';

    return $html;
}

protected function _toHtml()
{
    $this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Topmenu'));
    return parent::_toHtml();
}

}

app/code/Custom/Theme/etc/ has two files:

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="Magento\Theme\Block\Html\Topmenu" type="Custom\Theme\Block\Html\Topmenu" />
</config>

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="Custom_Theme" setup_version="0.0.1" />
</config>

And the registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Custom_Theme',
__DIR__
);

Is this approach correct? What do I miss?

Best Answer

You need to specify the usage of the new block via XML. Add the following to your theme's default_head_blocks.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <referenceContainer name="page.top">
      <block class=“Vendor\Module\Block\Html\Topmenu" name="catalog.topnav" template="Magento_Theme::html/topmenu.phtml" ttl="3600" before="-"/>
    </referenceContainer>
  </body>
</page>
Related Topic