Adding links to the Top menu in Magento


One of the things that may sound easy to set are the top menu items, or the main menu items if you prefer.
But we’re talking about Magento here and it isn’t as easy as it sounds. A specific way of creating menu items out of categories makes this fairly easy task a nightmare. Fortunately for us, Magento has a secret up its sleeve.
Magento’s logic allows only categories to appear in the top navigation. When creating a new category a simple Include in Navigation Menu setting will add the category in the navigation. Magento already explained how to add a custom link by creating a fake category and redirecting it to a specific page, but they also gave us an event to hook on to do more versatile things with the top menu.

Config

First things first. A hook has to be defined by adding the code below to the config.xml. By this we’re simply adding an event that will be fired by a dispatch event where a hook, model and method names 
<config>
    <frontend>
        <events>
            <page_block_html_topmenu_gethtml_before>
                <observers>
                    <my_module>
                        <class>my_module/observer</class>
                        <method>addToTopmenu</method>
                    </my_module>
                </observers>
            </page_block_html_topmenu_gethtml_before>
        </events>
   </frontend>
</config>

Observer

Now, inside the observer file defined in the config.xml a method named addToTopmenu has to be placed. The code below is just an example that adds a top menu item named “Categories” together with its children menu items, category names. That’s right, with this we’re able to create nested menu items!
public function addToTopmenu(Varien_Event_Observer $observer)
{
    $menu = $observer->getMenu();
    $tree = $menu->getTree();
    $node = new Varien_Data_Tree_Node(array(
            'name'   => 'Categories',
            'id'     => 'categories',
            'url'    => Mage::getUrl(), // point somewhere
    ), 'id', $tree, $menu);
    $menu->addChild($node);
    // Children menu items
    $collection = Mage::getResourceModel('catalog/category_collection')
            ->setStore(Mage::app()->getStore())
            ->addIsActiveFilter()
            ->addNameToResult()
            ->setPageSize(3);
    foreach ($collection as $category) {
        $tree = $node->getTree();
        $data = array(
            'name'   => $category->getName(),
            'id'     => 'category-node-'.$category->getId(),
            'url'    => $category->getUrl(),
        );
        $subNode = new Varien_Data_Tree_Node($data, 'id', $tree, $node);
        $node->addChild($subNode);
    }
}

Conclusion

This way of adding new top menu links is easy to implement into Magento and gives us a greater flexibility as opposed to other methods. No fake categories are made and no templates are edited. This method requires some code, but with this programmatic way we’re able to create more than just static menu links.


1 comment: