Magento – Adding attributes as a dropdown in Main Category Navigation

attributesmenunavigation

I'm working on a site that has main categories and there are product attributes that appear in the layered nav such as brand, type, color.

I would like to have a dropdown when hovering on a category link in the main nav that would have links for some attributes under that category

For example the categories are "Men's Shoes" "women's shoes" and under each one would be links for "by color: white, brown, etc." by occasion: casual, dress, etc."

How would go about creating something like this?

Best Answer

Based on this question and this one. I've put up the following "module" that should do what you need.
The main idea is to get the categories menu, identify the attributes used in layered navigation and display a link to the filtered category for each option in the attribute.
The extension is called Easylife_Nav. The extension files:

app/etc/modules/Easylife_Nav.xml - the declaration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Nav>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Catalog />
            </depends>
        </Easylife_Nav>
    </modules>
</config>

app/code/local/Easylife/Nav/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Nav>
            <version>0.0.1</version>
        </Easylife_Nav>
    </modules>
    <global>
        <helpers>
            <easylife_nav>
                <class>Easylife_Nav_Helper</class>
            </easylife_nav>
        </helpers>
        <models>
            <easylife_nav>
                <class>Easylife_Nav_Model</class>
            </easylife_nav>
        </models>
    </global>
    <frontend>
        <events>
            <page_block_html_topmenu_gethtml_before> <!-- observe the menu generation event -->
                <observers>
                    <easylife_nav>
                        <class>easylife_nav/observer</class>
                        <method>addAttributes</method>
                    </easylife_nav>
                </observers>
            </page_block_html_topmenu_gethtml_before>
        </events>
    </frontend>
</config>

app/code/local/Easylife/Nav/Helper/Data.php - the module main helper

<?php
class Easylife_Nav_Helper_Data extends Mage_Core_Helper_Abstract {

}

app/code/local/Easylife/Nav/Model/Observer.php - the module observer

<?php
class Easylife_Nav_Model_Observer {
    public function addAttributes($observer){
        $menu = $observer->getMenu();
        $tree = $menu->getTree();
        //get all first level menu items
        foreach ($menu->getChildren() as $child){
            $nodeId = $child->getId();
            //check if the node id starts with `category-node-` - so it's a category
            if (substr($nodeId, 0, strlen('category-node-')) == 'category-node-') {
                //identify the category id
                $id = str_replace('category-node-', '', $nodeId);
                //remember the main category url
                $mainUrl = $child->getUrl();
                //get category filtrable attributes
                $attributes = $this->getAttributes($id);
                foreach ($attributes as $attribute) { 
                    //get the options for each attribute
                    $options = $attribute->getSource()->getAllOptions();
                    if (count($options) > 0) {
                        //add "By ..." menu item - non clickable
                        $attrNodeId = 'attribute-'.$id.'-'.$attribute->getId();
                        $data = array(
                            'name' => Mage::helper('easylife_nav')->__('By %s', $attribute->getFrontendLabel()),
                            'id' => $attrNodeId,
                            'url' => '#',
                            'is_active' => false
                        );
                        $attrNode = new Varien_Data_Tree_Node($data, 'id', $tree, $menu);
                        //for each option add a new sub menu
                        foreach ($options as $option) {
                            if ($option['value']) {
                                $optionNodeId = 'attribute-'.$id.'-'.$attribute->getId().'-'.$option['value'];
                                $data = array(
                                    'name' => $option['label'],
                                    'id' => $optionNodeId,
                                    'url' => $mainUrl.'?'.$attribute->getAttributeCode().'='.$option['value'],
                                    'is_active' => false
                                );
                                $optionNode = new Varien_Data_Tree_Node($data, 'id', $tree, $menu);
                                $attrNode->addChild($optionNode);
                            }
                        }
                        $child->addChild($attrNode);
                    }
                }
            }
        }
    }
    //get allowed attributes in that category
    public function getAttributes($categoryId) {
        $layer = Mage::getModel("catalog/layer");
        $layer->setCurrentCategory(Mage::getModel('catalog/category')->load($categoryId));
        $validAttributes = array();
        foreach ($layer->getFilterableAttributes() as $attribute) {
            //allow only select attributes - you can implement your additional filters here
            if ($attribute->getFrontendInput() == 'select'){
                $validAttributes[] = $attribute;
            }
        }
        return $validAttributes;
    }
}

Clear the cache and try it out.

Related Topic