2

Does anyone have advice on how to debug why the main navigation wouldn't be rendering on my site? It's definitely caused by my custom module (which extends Nav's Topmenu.php), but everything's working locally so I'm having difficulties determining why.

Any tips would be appreciated!

Edit: Are there any logs I could check / ways of determining where exactly in the process that this fails?

Here's my code for Topmenu.php:

namespace Ibex\Nav\Block\Html;

use Magento\Framework\Data\Tree\Node;
use Magento\Framework\DataObject;
use Magento\Framework\View\Element\Template;

class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
    /**
     * Get top menu html
     *
     * @param string $outermostClass
     * @param string $childrenWrapClass
     * @param int $limit
     * @return string
     */
     protected function _getHtml(
         \Magento\Framework\Data\Tree\Node $menuTree,
         $childrenWrapClass,
         $limit,
         $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 . '" ';
                 $child->setClass($outermostClass);
             }

             if (count($colBrakes) && $colBrakes[$counter]['colbrake']) {
                 $html .= '</ul></li><li class="column"><ul>';
             }

             $href = 'href="' . $child->getUrl() . '"';
             $html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>';
             $html .= '<a ' . $href . $outermostClassCode . '><span>' . $this->escapeHtml(
                 $child->getName()
             ) . '</span></a>' . $this->_addSubMenu(
                 $child,
                 $childLevel,
                 $childrenWrapClass,
                 $limit
             ) . '</li>';
             $itemPosition++;
             $counter++;
         }

         if (count($colBrakes) && $limit) {
             $html = '<li class="column"><ul>' . $html . '</ul></li>';
         }

         if($childLevel == 2){
           $html .= '<li><a href="#" class="shop-all">Shop All</a></li>';
         }
         return $html;
     }

     /**
      * Add sub menu HTML code for current menu item
      *
      * @param \Magento\Framework\Data\Tree\Node $child
      * @param string $childLevel
      * @param string $childrenWrapClass
      * @param int $limit
      * @return string HTML code
      */
     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);
        }

        $extraclass = 'isactive';

        if ($childLevel == 0) {
          $html .= '<div class="megamenu-wrapper"><div class="megamenu">';
          $html .= '<ul class="level' . $childLevel . ' ' . $childrenWrapClass . ' ' . $extraclass . '">';
          $html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
          $html .= '<li class="level1"><a href="shop.html"><span>Shop All Categories</span></a></li>';
          $html .= '</ul>';
          $html .= $this->getChildHtml();
          $html .= '</div></div>';
        } else {
          $html .= '<ul class="level' . $childLevel . ' ' . $childrenWrapClass . '">';
          $html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
          $html .= '</ul>';
        }

        return $html;
    }

}

Aside from this, there's just CSS -- no layout/template files that could be interfering. Very odd. Any assistance in pinpointing the error would be greatly appreciated.

15
  • 2
    Please share the layout module content, we will try to debug this
    – PЯINCƎ
    Commented Aug 27, 2018 at 20:06
  • Thanks! Edited into the above. Apologies if your eyes roll out of your sockets while looking into what I'm doing here. Again, it's working great locally, so I'm having a difficult time troubleshooting it.
    – brackfost
    Commented Aug 27, 2018 at 20:49
  • So you tell me, your code works fine and not with your custom theme right ?
    – PЯINCƎ
    Commented Aug 27, 2018 at 21:52
  • Right, works fine on a local copy of the custom theme, which is pretty basic / extended from Blank.
    – brackfost
    Commented Aug 27, 2018 at 23:39
  • Can you share me the layout.xml app/code/Vendor/module/view/frontend/layout/some_name_here.xml
    – PЯINCƎ
    Commented Aug 28, 2018 at 7:59

2 Answers 2

2

Welp, I would've never thought that this would be the solution, but it turns out that removing the block and re-adding it without the TTL parameter was the fix:

<referenceBlock name="catalog.topnav" remove="true"/>

<referenceBlock name="store.menu">
    <block class="Magento\Theme\Block\Html\Topmenu" name="catalog.topnav.fix" template="Magento_Theme::html/topmenu.phtml" before="-"/>
</referenceBlock>

Thanks to Gabriel in this thread: Magento 2 https ssl missing navigation menu

2
  • 1
    The TTL is an issue if you have "Varnish" enabled in your config but don't have the Varnish in your local. Just switch from Varnish to Built-in (remove the http_cache_host in the env.php too). What is the point of enable Varnish in configuration but not using it? Commented Sep 3, 2018 at 6:52
  • Hi brackfost, i have issue in hamburger menu, any help thanks, magento.stackexchange.com/q/328503/57334
    – zus
    Commented Jan 2, 2021 at 18:15
0

There can be several reasons, but based on the approved answer, seems it is based on Full Page Cache Configurations

./vendor/magento/module-theme/view/frontend/layout/default.xml:69

<block class="Magento\Theme\Block\Html\Topmenu" name="catalog.topnav" template="Magento_Theme::html/topmenu.phtml" ttl="3600" before="-"/>

This has the ttl=3600 which instructs the caching mechanism to refresh the menu cache entry every 1 hour.

Store > Configuration > Advanced > System Varnish cache is recommended and shipped with Magento 2 out of the box. Make sure if you have enabled Varnish cache instead of Built-in Cache (File based) in your local environment without configuring Varnish service properly.

If yes then main menu will disappear. (Because Magento will replace the menu block with a Varnish compatible ESI block but varnish is not there to decode it!)

<esi:include src="http://test.loc.com/rb-ee/page_cache/block/esi/blocks/%5B%22catalog.topnav%22%5D/handles/XXXXX/"></esi:include>

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.