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.
Firstly, you need to create your own theme and override which module you want to do.
1. you need to override module-theme in your theme: layout and template
/root/test/kingfisherflyshop-new/app/design/frontend/yournamespace/your module-name/Magento_Theme/layout/override/base/default.xml
app/design/frontend/yournamespace/your module-name/Magento_Theme/templates/html/topmenu.phtml
http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/layouts/layout-override.html
Best Answer
I would suggest using
unsetChild
andinsert
rather thanremove
and then having to create the block again. Oddly unsetChild takes the block alias set viaas
but insert takes the block name.Using insert also gives you some more power as regards to positioning of the block etc as you can pass some more parameters.
NOTE: the main functions you can use via layout xml can be found in
Mage_Core_Block_Abstract