Custom category menu navigation in Magento

Magento has its top menu reserved for category navigation. It’s pretty solid for displaying categories, even when there is a large number of them.

What some of the clients want is a vertical (sidebar) category menu, so they can display sibling categories of a category their customers are exploring.

In this article we’ll cover the creation of a full vertical menu. We’ll go 3 levels deep: category, subcategory, and sub-subcategory. You can always expand on this, but I believe 3 levels are more than enough for most stores.

The layout

Open app/design/frontend/base/default/layout/page.xml or your theme’s equivalent.
Place the following code under default tag:

<reference name="right">
     <block type="core/template" name="catalog.sidenav" template="page/custom.phtml" before="cart_sidebar"/>
</reference>

This will tell Magento to load our template on each page that sports a layout with a right column.

Now, let’s create our template file.

The template

What we need to do is go through all of the store’s categories, get their subcategories (2nd level), sub-subcategories (3rd level) and display them. In the process we need to look for a case when the ID of the category in our list matches the ID of a current category. When we find it – we’ll make it bold.

Create app/design/frontend/base/default/template/page/custom.phtml with the following content:

<ul>
    <?php
        $obj = new Mage_Catalog_Block_Navigation();
        $storeCategories = $obj->getStoreCategories();
        Mage::registry('current_category') ? $currentCategoryId = Mage::registry('current_category')->getId() : $currentCategoryId='';
        foreach ($storeCategories as $_category):
    ?>
            <li>
                <strong><?php echo $_category->getName(); ?></strong>
                <?php $categoryChildren = $_category->getChildren(); ?>
                <?php if($categoryChildren->count()) : ?>
                    <ul>
 
                        <?php foreach($categoryChildren as $_categoryChild) : ?>
                            <?php $_categoryChildModel = Mage::getModel('catalog/category')->load($_categoryChild->getId());?>
                            <?php $categoryGrandchildren=$_categoryChild->getChildren(); ?>
                            <li>
                                <?php
                                    $currentCategoryId===$_categoryChild->getId() ? $bold="style="font-weight:bold"" : $bold='';
                                    echo '&emsp;' . '<a href="' . $_categoryChildModel->getUrl() . '"' . $bold . '>' .  $_categoryChild->getName() . '(' . $_categoryChildModel->getProductCollection()->count() . ')</a>';
                                ?>
                            </li>
                            <?php if($categoryGrandchildren->count()) : ?>
                                <?php foreach($categoryGrandchildren as $_categoryGrandchild) : ?>
                                    <?php $_categoryGrandchildModel = Mage::getModel('catalog/category')->load($_categoryGrandchild->getId());?>
                                    <li>
                                        <?php
                                            $currentCategoryId===$_categoryChild->getId() ? $bold="style="font-weight:bold"" : $bold='';
                                            echo '&emsp;&emsp;' . '<a href="' . $_categoryGrandchildModel->getUrl() . '"' . $bold . '>' .  $_categoryGrandchild->getName() . '(' . $_categoryGrandchildModel->getProductCount() . ')</a>';
                                        ?>
                                    </li>
                                <?php endforeach; ?>
                            <?php endif; ?>
                        <?php endforeach; ?>
                    </ul>
                <?php endif; ?>
            </li>
        <?php endforeach ?>
</ul>

The result

Et voilà! You should be able to see the navigation on the right column of your page. It’s not exactly the prettiest list, but I trust you’ll be able to style it to suit your needs.

custom-category-menu-example

You can also insert this template to any other page by coding a layout update or via admin, by inserting this line as content of your CMS page:

{{block type="core/template" template="page/custom.phtml"}}

Download zipped source or take a look at it on GitHub.

Note: This is a revamp of the article originally written in January 2009.

In case all of this sounds amazing and you simply want to improve current state of your Magento shop, we can create a detailed customized report based on our Magento Technical Audit! Feel free to contact us.