How to Render Two Root Categories in Navigation in Magento

navigationsubmenu

I have two root categories in the left navigation.
And it should be like this:

default: (root1 - doesn't appear on the view itself)
  - sub1
  - sub2
  - sub3

default1: (root2 - doesn't appear on the view itself)
  - ssub1
  - ssub2
  - ssub3

To show first root category run this code:

<?php $_menu = $this->renderCategoriesMenuHtml(0, 'level-top') ?>

What about second root category? How to make it appear in frontend?

UPDATE 1:

I tried that:

  1. Rewrite class to Mage_Catalog_Block_Navigation

    class Company_Catalog_Block_Navigation extends Mage_Catalog_Block_Navigation
    {
        //...
    }
    
  2. Add function renderOtherCategoriesMenuHtml to Company_Catalog_Block_Navigation

    public function renderOtherCategoriesMenuHtml($otherRootID, $level = 0, $outermostItemClass = '', $childrenWrapClass = '')
    {
        $activeCategories = array();
    
        $categories = Mage::helper('catalog/category')->getOtherStoreCategories(otherRootID);
    
        foreach ($categories 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;
    }
    
  3. Rewrite class Mage_Catalog_Helper_Category and add custom function:

    class Company_Catalog_Helper_Category extends Mage_Catalog_Helper_Category{
    
    public function getOtherStoreCategories($idParent, $sorted=false, $asCollection=false, $toLoad=true)
    {
    
        $cacheKey   = sprintf('%d-%d-%d-%d', $idParent, $sorted, $asCollection, $toLoad);
    
        if (isset($this->_storeCategories[$cacheKey])) {
            return $this->_storeCategories[$cacheKey];
        }
    
        /**
         * Check if parent node of the store still exists
         */
        $category = Mage::getModel('catalog/category');
        /* @var $category Mage_Catalog_Model_Category */
        if (!$category->checkId($idParent)) {
            if ($asCollection) {
                return new Varien_Data_Collection();
            }
            return array();
        }
    
        $recursionLevel  = max(0, (int) Mage::app()->getStore()->getConfig('catalog/navigation/max_depth'));
        $storeCategories = $category->getCategories($idParent, $recursionLevel, $sorted, $asCollection, $toLoad);
    
        $this->_storeCategories[$cacheKey] = $storeCategories;
        return $storeCategories;
    }
    }
    

4.Call renderOtherCategoriesMenuHtml in the view with navigation.

5.Incorrect rewrite urls:

After that you'll get navigation menu but it has incorrect rewrite rules.
I debugged it.
If we take a look at getCategories function in Mage_Catalog_Model_Resource_Category you will see this one:

$tree->addCollectionData(null, $sorted, $parent, $toLoad, true);

This method has some functionality which is set rewrite rules:

class Mage_Catalog_Model_Resource_Category_Tree extends Varien_Data_Tree_Dbp
{
      public function addCollectionData($collection = null, $sorted = false, $exclude = array(), $toLoad = true, $onlyActive = false)
      {
            //...
            if ($this->_joinUrlRewriteIntoCollection) {
                $collection->joinUrlRewrite();
                $this->_joinUrlRewriteIntoCollection = false;
            }
            //...
      }

This function get rules from core_url_rewrite where each request path attitudes to certain webstore. It means that we should create webstore and new store view to get its root category children with correct URL.

Resume:
@RickKuipers is partly right but we shouldn't change webstore while view is being generated.

Best Answer

My question would be why are you trying to use two root categories in the same store? A root category is intended to be just that, the parent of all categories which are available for use on a given store. It's a means of access control, URL construction and the list goes on. There are a vast number of places you would need to (literally) hack the core to make this work all around. Taking this route you will run into nuances which will most likely come back to bite you.

What I would suggest is to simple use one root category as intended by Magento and move all sub-categories you wish to show up to be children of it. Break down the hierarchy beneath the root. If you need to use this same structure for multiple stores which have the same product set, you can set the same root as the root of multiple stores when creating them in the admin.

Sometimes the best way to solve problems like this is not jumping into the code and changing stuff up, but rather looking at the approach being taken and finding another way to accomplish your goals without needing to make such awkward changes to the core. You will benefit now and in the long run by using this methodology. In the short-term you will benefit from less modifications and get up and running more quickly, and in the long-run you will also benefit from less modifications because when it comes time to upgrade you won't have to port intrusive changes to the way the core functions to the newer versions of Magento.

Related Topic