3

Im trying to display the category image in the top navigation,

If I use the following snippet in the core class, images are displayed, but not using my \app\code\Ibnab\MegaMenu\Block\Html\Topmega.php

Below is the code i m using to get the category images in the top menu in my overridden class

protected function _getHtml2(
    \Magento\Framework\Data\Tree\Node $menuTree,
    $childrenWrapClass,
    $limit,
    $colBrakes = []
) {
  .....
$html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>';

        // Custom -Use sub category image instead of name if available
        $html .= ($child->getDataByKey('image_url')!='') ? '<img src="' . $child->getDataByKey('image_url') . '">' : '';
        $html .=$child->getDataByKey('name');
        $html .= '</span></a>' . $this->_addSubMenu2(
            $child,
            $childLevel,
            $childrenWrapClass,
            $limit
        ) . '</li>';
        }
        $itemPosition++;
        $counter++;
   .....

\app\code\Ibnab\MegaMenu\etc\di.xml

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
      <preference for="Magento\Theme\Block\Html\Topmenu" type="Ibnab\MegaMenu\Block\Html\Topmega" />
      <preference for="Magento\Catalog\Plugin\Block\Topmenu" type="Ibnab\MegaMenu\Plugin\Block\Topmenu" /> 
   </config>

\app\code\Ibnab\MegaMenu\Block\Html\Topmega.php

<?php

namespace Ibnab\MegaMenu\Block\Html;

use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\View\Element\Template;
use Magento\Framework\Data\TreeFactory;
use Magento\Framework\Data\Tree\Node;
use Magento\Framework\Data\Tree\NodeFactory;
use Magento\Theme\Block\Html\Topmenu;
use Magento\Cms\Model\BlockRepository;
use Magento\Catalog\Model\CategoryFactory;
use Magento\Framework\Registry;
/**
* Html page top menu block
*/
class Topmega extends Topmenu 
{
/**
 * Cache identities
 *
 * @var array
 */
protected $identities = [];

/**
 * Top menu data tree
 *
 * @var \Magento\Framework\Data\Tree\Node
 */
protected $_menu;

/**
 * Core registry
 *
 * @var Registry
 */
protected $registry;
/**
 * @var \Magento\Catalog\Model\CategoryFactory
 */
protected $categoryFactory;
/**
 * @var \Magento\Cms\Model\Template\FilterProvider
 */
protected $_filterProvider;

/**
 * Store manager
 *
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $_storeManager;

/**
 * Block factory
 *
 * @var \Magento\Cms\Model\BlockFactory
 */
protected $_blockFactory;
/**
 * Core registry
 *
 * @var \Magento\Framework\Registry
 */
protected $coreRegistry = null;
/**
 * @var \Ibnab\CategoriesUrl\Helper\Data
 */
protected $dataHelper;
/**
 * @param Template\Context $context
 * @param NodeFactory $nodeFactory
 * @param TreeFactory $treeFactory
 * @param array $data
 */
public function __construct(
    Template\Context $context,
    NodeFactory $nodeFactory,
    TreeFactory $treeFactory,
    CategoryFactory $categoryFactory,
    \Magento\Cms\Model\Template\FilterProvider $filterProvider,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Cms\Model\BlockFactory $blockFactory,
    Registry $registry,
    \Ibnab\MegaMenu\Helper\Data $dataHelper,
    array $data = []
) {
    parent::__construct($context,$nodeFactory,$treeFactory, $data);
    $this->categoryFactory = $categoryFactory;
    $this->_filterProvider = $filterProvider;
    $this->_storeManager = $storeManager;
    $this->_blockFactory = $blockFactory;
    $this->coreRegistry = $registry;
    $this->dataHelper = $dataHelper;
    $this->_menu = $this->getMenu();
}
/**
 * Prepare Content HTML
 *
 * @return string
 */
public function getBlockHtml($id)
{
    $blockId = $id;
    $html = '';
    if ($blockId) {
        $storeId = $this->_storeManager->getStore()->getId();
        /** @var \Magento\Cms\Model\Block $block */
        $block = $this->_blockFactory->create();
        $block->setStoreId($storeId)->load($blockId);
        if ($block->isActive()) {
            $html = $this->_filterProvider->getBlockFilter()->setStoreId($storeId)->filter($block->getContent());
        }
    }
    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 _addSubMenu2($child, $childLevel, $childrenWrapClass, $limit)
{

    if($this->dataHelper->allowExtension())
    {
    $html = '';
    if (!$child->hasChildren()) {
        return $html;
    }

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


    $category = "";
    if ($childLevel == 0) {
    $html .= '<ul>';
    $category = $this->coreRegistry->registry('current_categry_top_level');
    if($category != null)
    {
    if($category->getUseStaticBlock())
    {

      if($category->getUseStaticBlockTop() && $category->getStaticBlockTopValue() != "")
      {
      $html .= '<div class="topstatic" >';
      $html .= $this->getBlockHtml($category->getStaticBlockTopValue());
      $html .= '</div>';
      }
      if($category->getUseStaticBlockLeft() && $category->getStaticBlockLeftValue() != "")
      {
      $html .= '<div class="leftstatic" >';
      $html .= $this->getBlockHtml($category->getStaticBlockLeftValue());
      $html .= '</div>';
      }
    }
      if($category->getUseLabel())
      {
       if($category->getLabelValue() != "" )
        {
          $child->setData('name',$category->getLabelValue());
        }
      }
    }
      if(!$category->getDisabledChildren() && $childLevel == 0)
      {
        $html .= $this->_getHtml2($child, $childrenWrapClass, $limit, $colStops);   //_getHtml() changed to _getHtml2
      }

    if($category != null)
    {
    if($category->getUseStaticBlock())
    {
      if($category->getUseStaticBlockRight() && $category->getStaticBlockRightValue() != "")
      {
      $html .= '<div class="rightstatic" >';
      $html .= $this->getBlockHtml($category->getStaticBlockRightValue());
      $html .= '</div>';
      }

      if($category->getUseStaticBlockBottom() && $category->getStaticBlockBottomValue() != "")
      {
      $html .= '<div class="bottomstatic" >';
      $html .= $this->getBlockHtml($category->getStaticBlockBottomValue());
      $html .= '</div>';
      }

    }
    }
    $html .= '<div class="bottomstatic" ></div>';
     $html .= '</ul>';
    }
    else
    {
        $html .= '<ul>';
        $html .= $this->_getHtml2($child, $childrenWrapClass, $limit, $colStops);  //_getHtml() changed to _getHtml2
        $html .= '</ul>';
     }
    return $html;
    }
    else
    {
     return parent::_addSubMenu($child, $childLevel, $childrenWrapClass, $limit);
    }
}

/**
 * Recursively generates top menu html from data that is specified in $menuTree
 *
 * @param \Magento\Framework\Data\Tree\Node $menuTree
 * @param string $childrenWrapClass
 * @param int $limit
 * @param array $colBrakes
 * @return string
 *
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 * @SuppressWarnings(PHPMD.NPathComplexity)
 */
protected function _getHtml2(
    \Magento\Framework\Data\Tree\Node $menuTree,
    $childrenWrapClass,
    $limit,
    $colBrakes = []
) {
    if($this->dataHelper->allowExtension())
    {
    $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-';

    foreach ($children as $child) {
        $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 ($childLevel == 0) {
         $arrayId = explode('-',$child->_getData('id'));
         $category = null;
         if(isset($arrayId[2]))
         {
             $id = $arrayId[2];
             $category = $this->categoryFactory->create();
             $category->load($id);
             $this->coreRegistry->unregister('current_categry_top_level');
             $this->coreRegistry->register('current_categry_top_level',$category);
          }
        }
        if (count($colBrakes) && $colBrakes[$counter]['colbrake']) {
            $html .= '</ul></li><li><ul>';
        }

        $html .= '<li>';

        if ($childLevel == 0) {
           $name = $child->getName();;
           $category = $this->coreRegistry->registry('current_categry_top_level');
         if($category != null )
         {
           if($category->getUseLabel())
           {
            if($category->getLabelValue() != "" )
             {
              $name = $category->getLabelValue();
             }
             else
             {
              $name = $child->getName();
             }
            }
            else
            {
              $name = $child->getName();
            }
          }
        $html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>' . $this->escapeHtml(
            $name
        ) . '</span></a>' . $this->_addSubMenu2(
            $child,
            $childLevel,
            $childrenWrapClass,
            $limit
        ) . '</li>';
        }
        else
        {

         /*To display the category image --*/
         $html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>';
   $html .= $child->getDataByKey('image_url') ? '<img src="' . $child->getDataByKey('image_url') . '">' : '';
        $html .=$child->getDataByKey('name');
        $html .= '</span></a>' . $this->_addSubMenu2(
            $child,
            $childLevel,
            $childrenWrapClass,
            $limit
        ) . '</li>';
        $itemPosition++;
        $counter++;             
    }

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

    return $html;
    }
    else
    {
    return parent::_getHtml(
    $menuTree,
    $childrenWrapClass,
    $limit,
    $colBrakes
    );
    }
}
/**
 * Get top menu html
 *
 * @param string $outermostClass
 * @param string $childrenWrapClass
 * @param int $limit
 * @return string
 */
  public function getHtml($outermostClass = '', $childrenWrapClass = '', $limit = 0)
 {
   if($childrenWrapClass=="mega"){
    $childrenWrapClass = "submenu";
    $this->_eventManager->dispatch(
        'page_block_html_topmenu_gethtml_before',
        ['menu' => $this->_menu, 'block' => $this]
    );

    $this->_menu->setOutermostClass($outermostClass);
    $this->_menu->setChildrenWrapClass($childrenWrapClass);

    $html = $this->_getHtml2($this->_menu, $childrenWrapClass, $limit);

    $transportObject = new \Magento\Framework\DataObject(['html' => $html]);
    $this->_eventManager->dispatch(
        'page_block_html_topmenu_gethtml_after',
        ['menu' => $this->_menu, 'transportObject' => $transportObject]
    );
    $html = $transportObject->getHtml();
    return $html;
   }else
   {
      return parent::getHtml($outermostClass, $childrenWrapClass , $limit); 
   }
 }


 public function allowExtension()
 {
   return $this->dataHelper->allowExtension();
 }
}
8
  • Magento\Theme\Block\Html\Topmenu is this type of class avilable in your magento 2? Feb 21, 2017 at 11:37
  • Yes in magento 2 we have that class in : vendor\magento\module-theme\Block\Html\Topmenu.php
    – Sushivam
    Feb 21, 2017 at 11:44
  • Any idea @Dhiren where im going wrong, cause my overriden class seems to be called, only issue with the image display
    – Sushivam
    Feb 21, 2017 at 12:06
  • debug image code, which execute to show category image. I think it not able to get value after override. Feb 21, 2017 at 12:09
  • yes when i debug, i get image url value from core class, but the same value im not able to get in my overridden class, where seems to be the problem?
    – Sushivam
    Feb 21, 2017 at 14:14

2 Answers 2

1

You need to get Category Id from the tree node. And then get the Image url.

protected function _getHtml2(
    \Magento\Framework\Data\Tree\Node $menuTree,
    $childrenWrapClass,
    $limit,
    $colBrakes = []
) {

.....

 $objectManager =  \Magento\Framework\App\ObjectManager::getInstance();
  $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory');

           foreach ($children as $child) {
            $categoryId = substr($child->getId(), -1);  // Get CATEGORY ID
            $category = $categoryFactory->create()->load($categoryId);  

.....

$html .= .'<img src="' . $category->getImageUrl() . ' " width="100px;" height="100px;" />';
1

Use the below code :

In this file \Ibnab\MegaMenu\Block\Html\Topmega.php

 use \Magento\Catalog\Model\CategoryRepository;
 class Topmega extends Topmenu 
  {
  protected $_categoryRepository;
    .....
   public function __construct(
    Template\Context $context,
    NodeFactory $nodeFactory,
    TreeFactory $treeFactory,
    CategoryFactory $categoryFactory,
    .....
    ) {
    parent::__construct($context,$nodeFactory,$treeFactory, $data);
    $this->_categoryRepository = $categoryRepository;
    .....
    }
   protected function _addSubMenu2($child, $childLevel,    $childrenWrapClass, $limit)
{

    if($this->dataHelper->allowExtension())
    {
    $html = '';
    if (!$child->hasChildren()) {
        return $html;
    }

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


    $category = "";
    if ($childLevel == 0) {
    $html .= '<ul>';
    $category = $this->coreRegistry->registry('current_categry_top_level');
    if($category != null)
    {
/** Show top level category image in mega menu **/
        $categoryIdElements = explode('-', $child->getId());        
        $category           = $this->_categoryRepository->get(end($categoryIdElements));
        $html .= ($category->getImageUrl()!='') ? '<img src="' . $category->getImageUrl() . '">' : '';
/** end **/
    if($category->getUseStaticBlock())
    {
  ..........

I hope it will working..

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.