Product count of category in Magento default navigation

To display number of product that is associated to the particular category I have overrided a magento Navigation Block. for that I have create a very small extension code. please check it down.

create a xml file at app/etc/modules/Prakash_All.xml and copy/paste following code

<config>
  <modules>
    <Prakash_Catalog>
      <active>true</active>
      <codePool>local</codePool>
    </Prakash_Catalog>
  </modules>
</config>

Then create another xml file in exact following path and name
app/code/local/Prakash/Catelog/Block/etc/config.xml and copy/paste following code in this file

<config>
  <modules>
    <Prakash_Catalog>
      <version>0.1.0</version>
    </Prakash_Catalog>
  </modules>
  <global>
    <blocks>
      <catalog>
        <rewrite>
          <navigation>Prakash_Catalog_Block_Navigation</navigation>
        </rewrite>
      </catalog>
    </blocks>
  </global>
</config>

This code rewrite the existing Navigation Block with our custom navigation. Even though we have to change just a few code it is always better to to write in our own custom rewrite module.

and then create another files with name and location as app/code/local/Prakash/Catelog/Block/Navigation.php

and copy/paste following code


class Prakash_Catalog_Block_Navigation extends Mage_Catalog_Block_Navigation
{

	protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false,
			$isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)
	{
		if (!$category->getIsActive()) {
			return '';
		}
		$html = array();

		// get all children
		if (Mage::helper('catalog/category_flat')->isEnabled()) {
			$children = (array)$category->getChildrenNodes();
			$childrenCount = count($children);
		} else {
			$children = $category->getChildren();
			$childrenCount = $children->count();
		}
		$hasChildren = ($children && $childrenCount);

		// select active children
		$activeChildren = array();
		foreach ($children as $child) {
			if ($child->getIsActive()) {
				$activeChildren[] = $child;
			}
		}
		$activeChildrenCount = count($activeChildren);
		$hasActiveChildren = ($activeChildrenCount > 0);

		// prepare list item html classes
		$classes = array();
		$classes[] = 'level' . $level;
		$classes[] = 'nav-' . $this->_getItemPosition($level);
		if ($this->isCategoryActive($category)) {
			$classes[] = 'active';
		}
		$linkClass = '';
		if ($isOutermost && $outermostItemClass) {
			$classes[] = $outermostItemClass;
			$linkClass = ' class="'.$outermostItemClass.'"';
		}
		if ($isFirst) {
			$classes[] = 'first';
		}
		if ($isLast) {
			$classes[] = 'last';
		}
		if ($hasActiveChildren) {
			$classes[] = 'parent';
		}

		// prepare list item attributes
		$attributes = array();
		if (count($classes) > 0) {
			$attributes['class'] = implode(' ', $classes);
		}
		if ($hasActiveChildren && !$noEventAttributes) {
			$attributes['onmouseover'] = 'toggleMenu(this,1)';
			$attributes['onmouseout'] = 'toggleMenu(this,0)';
		}

		// assemble list item with attributes
		$htmlLi = '<li';
		foreach ($attributes as $attrName => $attrValue) {
			$htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
		}
		//count product for first category
		$productCount = '';
		$catRef = Mage::getModel('catalog/category')->load($category->getId());
		$productCount = ' '.$catRef->getProductCount().' ';
		$htmlLi .= '>';
		$html[] = $htmlLi;
		$html[] = '<a href="'.$this->getCategoryUrl($category).'"'.$linkClass.'>';
		$html[] = '<span>' . $this->escapeHtml($category->getName()).$productCount . '</span>';
		$html[] = '</a>';

		// render children
		$htmlChildren = '';
		$j = 0;
		foreach ($activeChildren as $child) {
			$htmlChildren .= $this->_renderCategoryMenuItemHtml(
					$child,
					($level + 1),
					($j == $activeChildrenCount - 1),
					($j == 0),
					false,
					$outermostItemClass,
					$childrenWrapClass,
					$noEventAttributes
			);
			$j++;
		}
		if (!empty($htmlChildren)) {
			if ($childrenWrapClass) {
				$html[] = '<div class="' . $childrenWrapClass . '">';
			}
			$html[] = '<ul class="level' . $level . '">';
			$html[] = $htmlChildren;
			$html[] = '</ul>';
			if ($childrenWrapClass) {
				$html[] = '</div>';
			}
		}

		$html[] = '</li>';

		$html = implode("\n", $html);
		return $html;
	}
	public function renderCategoriesMenuHtml($level = 0, $outermostItemClass = '', $childrenWrapClass = '')
	{
		$activeCategories = array();
		foreach ($this->getStoreCategories() as $child) {
			if ($child->getIsActive()) {
				$activeCategories[] = $child;
			}
		}
		$activeCategoriesCount = count($activeCategories);
		$hasActiveCategoriesCount = ($activeCategoriesCount > 0);

		if (!$hasActiveCategoriesCount) {
			return '';
		}

		$html = '';
		$j = 0;
		foreach ($activeCategories as $category) {
			$html .= $this->_renderCategoryMenuItemHtml(
					$category,
					$level,
					($j == $activeCategoriesCount - 1),
					($j == 0),
					true,
					$outermostItemClass,
					$childrenWrapClass,
					true
			);
			$j++;
		}

		return $html;
	}
}

Here we have just added one line of code from existing Navigation.php block of Magento code but I hope that it will be helpful to all of you.
Please download full code from following location

Navigation

Download from github repository:

https://github.com/phpprakash/navigation

5 thoughts on “Product count of category in Magento default navigation

  1. Denis

    Work nice, but I need to not show product count on main category in main menu, I wnat show product count only on subcategories.
    Any suggestion?

    Reply
  2. prakash Post author

    replace the following code

            $html[] = '<span>' . $this->escapeHtml($category->getName()).$productCount . '</span>';
    

    with

    if($level!=0)
            $html[] = '<span>' . $this->escapeHtml($category->getName()).$productCount . '</span>';
    
    Reply
  3. Loek

    This doesn’t take status, visibilty or stock into account so it’s not very usefull. I only managed to do this with collection, but this makes the navigation incredibly slow.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.