SlideShare a Scribd company logo
EXTENDING MAGENTO
LAYERED NAVIGATION
MAGE TITANS ITALIA - MILAN, FEBRUARY 5TH 2016
Nadia Sala
Extending Magento layered navigation by Nadia Sala
ABOUT ME
PHP DEVELOPER
MAGENTO BACKEND DEVELOPER
@nadiasala
nadia.sala@bitbull.it
THE STORY
"Once upon a time there was an e-commerce website that
exposed a catalog with many descriptive information."
You can imagine a fashion catalog, so you mind about:
Product type, Occasion, Color,
Gender, Designer, Price, Size,
...and more
SCENARIO
Some information is useful for browsing catalog
Some information is useful for filtering catalog
Some information is useful for both
COMMON APPROACH
Some information is useful for browsing catalog
I can create  categories and include them in the navigation
menu
COMMON APPROACH
Some information is useful for filtering catalog
I can configure some attributes to be used as filters in
layered navigation
COMMON APPROACH
Some information is useful for both
I have to create attributes in addition to categories and
duplicate the same data
DRAWBACKS
I have to keep attribute options in sync with category
children
I have to maintain proper correspondence between
product attribute values and category assignment
Filter redundancy
Extending Magento Layered Navigation
Extending Magento Layered Navigation
THE SOLUTION
Extending Magento layered navigation
to use category branches such as filters!
LET'S CODE !
Create custom module
Add system configuration
Create new catalog layer filter
block
Create new catalog layer filter
model
Extend catalog layer view
block
Define module layout update
ADD SYSTEM CONFIGURATION
<!--?xml version="1.0"?-->
<config>
<tabs>
<bitbulltab translate="label" module="bitbull_categorylayered">
<label>BITBULL</label>
<sort_order>999</sort_order>
</bitbulltab>
</tabs>
<sections>
<bitbull_categorylayered translate="label" module="bitbull_categorylayered">
<label>Category Layered Navigation</label>
<tab>bitbulltab</tab>
<frontend_type>text</frontend_type>
<sort_order>100</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<configuration translate="label" module="bitbull_categorylayered">
<label>Configuration</label>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<categories translate="label">
<label>Category List</label>
<comment>List of categories to use in layered navigation</comment>
<frontend_model>bitbull_categorylayered/config_categories</frontend_model>
<backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
<sort_order>20</sort_order>
<show_in_default>1</show_in_default>
EXTEND MAGE_CATALOG_BLOCK_LAYER_VIEW / 1
Child blocks initialization, one for each configured category
class Bitbull_CategoryLayered_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View{
/**
* Prepare child blocks
* @return Mage_Catalog_Block_Layer_View
*/
protected function _prepareLayout()
{
/** @var Mage_Catalog_Model_Category $current_category */
$current_category = Mage::helper('catalog')->getCategory();
foreach ($this->_layeredCategories as $layeredCatConfig) {
$categoryId = $layeredCatConfig['category'];
// check if current category navigation is in path of categorylayered
if ($current_category->getId() && in_array($categoryId, $current_category->getPathIds())) {
continue;
}
// create categoryLayered filter block
$blockAttributes = array(
'categoryId' => $layeredCatConfig['category'],
'requestParam' => $layeredCatConfig['filter']
);
$blockName = 'categorylayered_'.$categoryId;
$categoryBlock = $this->getLayout()
->createBlock($this->_categoryLayeredBlockName, $blockName, $blockAttributes)
->setLayer($this->getLayer())
EXTEND MAGE_CATALOG_BLOCK_LAYER_VIEW / 2
For each configured category, add block to filters list
managing position
class Bitbull_CategoryLayered_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View
{
/**
* Get all layer filters
* @return array
*/
public function getFilters()
{
$filters = parent::getFilters();
foreach ($this->_layeredCategories as $layeredCatConfig) {
$categoryId = $layeredCatConfig['category'];
$position = $layeredCatConfig['position'];
if (($categoryFilter = $this->_getLayeredCategoryFilter($categoryId))) {
$filters = array_merge(
array_slice(
$filters,
0,
$position
),
array($categoryFilter),
array_slice(
$filters,
$position,
count($filters)
)
);
}
CREATE NEW CATALOG LAYER FILTER MODEL / 1
Retrieve subcategories as filter items.
class Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered extends Mage_Catalog_Model_Layer_Filter_Abstract
{
/**
* Get data array for building filter items
* @return array
*/
protected function _getItemsData()
{
$key = $this->getLayer()->getStateKey().'_'.$this->_requestVar;
$data = $this->getLayer()->getAggregator()->getCacheData($key);
if ($data === null) {
// load children for root category or current selected category for this filter
$categories = $this->_appliedCategory instanceof Mage_Catalog_Model_Category ?
$this->_appliedCategory->getChildrenCategories() :
$this->_rootCategory->getChildrenCategories();
$this->getLayer()->getProductCollection()
->addCountToCategories($categories);
$data = array();
foreach ($categories as $category) {
/** @var $category Mage_Catalog_Model_Categeory */
if ($category->getIsActive() && $category->getProductCount()) {
$data[] = array(
'label' => Mage::helper('core')->escapeHtml($category->getName()),
'value' => $category->getId(),
'count' => $category->getProductCount(),
CREATE NEW CATALOG LAYER FILTER MODEL / 2
Apply filter logic adding a join on
catalog/category_product_index table
class Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered extends Mage_Catalog_Model_Layer_Filter_Abstract
/**
* Apply category filter to layer
* @param Zend_Controller_Request_Abstract $request
* @param Mage_Core_Block_Abstract $filterBlock
* @return Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered
*/
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
{
$filter = (int) $request->getParam($this->getRequestVar());
if (!$filter) {
return $this;
}
// load data for applied category
$this->_appliedCategory = Mage::getModel('catalog/category')
->setStoreId(Mage::app()->getStore()->getId())
->load($filter);
if ($this->_appliedCategory->getId()) {
// create join and conditions for additional category filter
$tableAlias = 'category_layered_'.$this->_rootCategory->getId();
$conditions = array();
$conditions['category_id'] = $filter;
$conditions['store_id'] = Mage::app()->getStore()->getId();
if (!$this->_appliedCategory->getIsAnchor()) {
$conditions['is_parent'] = 1;
     Frontend Demo Backend Demo
CONCLUSION
By extending Magento layered navigation as shown we can:
avoid data replication and maintenance
filter deeply until selected category has subcategories
avoid filter redundancy
Without touching the core
THANK YOU !
NAMASTÉ
ANY QUESTION ?
@nadiasala
nadia.sala@bitbull.it
https://github.com/bitbull-team/magento-module-category-layered

More Related Content

PDF
Magento Layered Navigation Pro user manual by Aitoc
PDF
Improved Navigation: Magento Extension by Amasty. User guide.
PDF
Improved Layered Navigation: Magento Extension by Amasty. User Guide.
PDF
Special Promotions Pro: Magento Extension by Amasty. User Guide.
PDF
Custom Stock Status: Magento Extension by Amasty. User Guide.
PDF
Promo Banners: Magento extension by Amasty. User Guide
PDF
Promo Banners User Guide
PDF
Review Booster User Manual by Aitoc
Magento Layered Navigation Pro user manual by Aitoc
Improved Navigation: Magento Extension by Amasty. User guide.
Improved Layered Navigation: Magento Extension by Amasty. User Guide.
Special Promotions Pro: Magento Extension by Amasty. User Guide.
Custom Stock Status: Magento Extension by Amasty. User Guide.
Promo Banners: Magento extension by Amasty. User Guide
Promo Banners User Guide
Review Booster User Manual by Aitoc

What's hot (20)

PDF
A/B Testing Magento Extension by Amasty | User Guide
PDF
Special Promotions: Magento Extension by Amasty. user Guide.
PDF
User Guide for Product Labels Magento extension by Amasty
PDF
The Ultimate Guide to Magento SEO
PDF
Follow up email_for_magento_2_user_guide
PDF
Color Swatches Pro: Magento Extension by Amasty. User Guide.
PDF
Product Label: Magento Extension by Amasty. User Guide.
PDF
Order Memos and Attachments: Magento Extension by Amasty. User Guide
PDF
Customer Group Catalog: Magento Extension by Amasty. User Guide
PDF
Magento RMA System by Amasty. User Guide.
PDF
Advanced Customer Segments Magento Extension by Amasty | User Guide
PDF
Customer Activity Log: Magento Extension by Amasty. User Guide.
PDF
User Guide: Advanced product options Magento extension
PDF
Efficient Order Export: Magento Extension by Amasty. User Guide.
PDF
Cloud Backup by Amasty. User Guide/
PDF
Flexible Menu: Magento Extension by Amasty. User Guide.
PDF
Google Rich Snippets: Magento Extension by Amasty
PPTX
Shipping Table Rates for Magento 2 by Amasty | User Guide
PDF
Advanced Reports Magento Extension by Amasty | User Guide
PPT
Photo Gallery Pro Magento Extension by Amasty | User Guide
A/B Testing Magento Extension by Amasty | User Guide
Special Promotions: Magento Extension by Amasty. user Guide.
User Guide for Product Labels Magento extension by Amasty
The Ultimate Guide to Magento SEO
Follow up email_for_magento_2_user_guide
Color Swatches Pro: Magento Extension by Amasty. User Guide.
Product Label: Magento Extension by Amasty. User Guide.
Order Memos and Attachments: Magento Extension by Amasty. User Guide
Customer Group Catalog: Magento Extension by Amasty. User Guide
Magento RMA System by Amasty. User Guide.
Advanced Customer Segments Magento Extension by Amasty | User Guide
Customer Activity Log: Magento Extension by Amasty. User Guide.
User Guide: Advanced product options Magento extension
Efficient Order Export: Magento Extension by Amasty. User Guide.
Cloud Backup by Amasty. User Guide/
Flexible Menu: Magento Extension by Amasty. User Guide.
Google Rich Snippets: Magento Extension by Amasty
Shipping Table Rates for Magento 2 by Amasty | User Guide
Advanced Reports Magento Extension by Amasty | User Guide
Photo Gallery Pro Magento Extension by Amasty | User Guide
Ad

Viewers also liked (19)

ODT
Resume2016-a
PDF
THE RISE OF AN ALTROISTIC SOCIETY
PDF
Power point vs prezi
PDF
Accomplishments
PPTX
Infografía personal
PPTX
什麼是人類學?
PDF
The Taiwanese Turtle And The Betel Nuts
PPTX
Character profiles
PPT
Twmba 2
PPTX
Bim vs openbim pecha kucha
PDF
Smartphone intrinsecamente seguro: modelo Innovation 2.0
PPTX
buildingSMART-konf-2014-tønsbergprosjektet-konseptmodell-140424
PPT
學生憂鬱與自殺之防治931116
PDF
Caw 2 2 experience and skills inventory
PDF
為什麼醫師需要納入勞基法?
PPTX
抄,是最好的獲利模式
PDF
Find Your Inner Superhero
PPTX
Tipos de Luminarias
PPTX
淺談測試Part2
Resume2016-a
THE RISE OF AN ALTROISTIC SOCIETY
Power point vs prezi
Accomplishments
Infografía personal
什麼是人類學?
The Taiwanese Turtle And The Betel Nuts
Character profiles
Twmba 2
Bim vs openbim pecha kucha
Smartphone intrinsecamente seguro: modelo Innovation 2.0
buildingSMART-konf-2014-tønsbergprosjektet-konseptmodell-140424
學生憂鬱與自殺之防治931116
Caw 2 2 experience and skills inventory
為什麼醫師需要納入勞基法?
抄,是最好的獲利模式
Find Your Inner Superhero
Tipos de Luminarias
淺談測試Part2
Ad

Similar to Extending Magento Layered Navigation (20)

PPTX
Magento advanced layered navigation
PPTX
Steps to Setup Magento Multi-Stores
PPTX
Speed up the buying process using Advanced Layered Navigation for Magento 2 E...
PPTX
Magento 2 Layered Navigation - LandOfCoder
PPTX
Fixing Magento Core for Better Performance - Ivan Chepurnyi
PPTX
Making Magento flying like a rocket! (A set of valuable tips for developers)
PDF
Alex Ursa: ERP Integrations with Magento: How to do it fast, good and affordable
DOCX
TSuper menu magento extension standard
PDF
Layered navigation magento 2-extension
DOCX
Super menu magento extension
PDF
A true story about Magento best practices
PPTX
Magento performance feat. core Hacks
PDF
Magento 2 Layered Navigation Extension by ITORIS INC
PDF
Zones Manager Magento Module Manual 1.0.0.0
PDF
Magento Community User Guide
PPTX
Zendcon zray
PDF
Magento2dbschema1 180607144053
PPTX
Magento 2 Database Tables, Schema, Main tables for main features of Magento 2...
ODP
Edmonds Commerce Magento Presentation
PDF
Optimizing Magento Performance with Zend Server
Magento advanced layered navigation
Steps to Setup Magento Multi-Stores
Speed up the buying process using Advanced Layered Navigation for Magento 2 E...
Magento 2 Layered Navigation - LandOfCoder
Fixing Magento Core for Better Performance - Ivan Chepurnyi
Making Magento flying like a rocket! (A set of valuable tips for developers)
Alex Ursa: ERP Integrations with Magento: How to do it fast, good and affordable
TSuper menu magento extension standard
Layered navigation magento 2-extension
Super menu magento extension
A true story about Magento best practices
Magento performance feat. core Hacks
Magento 2 Layered Navigation Extension by ITORIS INC
Zones Manager Magento Module Manual 1.0.0.0
Magento Community User Guide
Zendcon zray
Magento2dbschema1 180607144053
Magento 2 Database Tables, Schema, Main tables for main features of Magento 2...
Edmonds Commerce Magento Presentation
Optimizing Magento Performance with Zend Server

Recently uploaded (20)

PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
System and Network Administraation Chapter 3
PPTX
Introduction to Artificial Intelligence
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
medical staffing services at VALiNTRY
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
ai tools demonstartion for schools and inter college
PPTX
Transform Your Business with a Software ERP System
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
top salesforce developer skills in 2025.pdf
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
System and Network Administraation Chapter 3
Introduction to Artificial Intelligence
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PTS Company Brochure 2025 (1).pdf.......
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
medical staffing services at VALiNTRY
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Computer Software and OS of computer science of grade 11.pptx
Wondershare Filmora 15 Crack With Activation Key [2025
wealthsignaloriginal-com-DS-text-... (1).pdf
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
ai tools demonstartion for schools and inter college
Transform Your Business with a Software ERP System
Which alternative to Crystal Reports is best for small or large businesses.pdf
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
top salesforce developer skills in 2025.pdf
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Navsoft: AI-Powered Business Solutions & Custom Software Development

Extending Magento Layered Navigation

  • 1. EXTENDING MAGENTO LAYERED NAVIGATION MAGE TITANS ITALIA - MILAN, FEBRUARY 5TH 2016 Nadia Sala Extending Magento layered navigation by Nadia Sala
  • 2. ABOUT ME PHP DEVELOPER MAGENTO BACKEND DEVELOPER @nadiasala nadia.sala@bitbull.it
  • 3. THE STORY "Once upon a time there was an e-commerce website that exposed a catalog with many descriptive information."
  • 4. You can imagine a fashion catalog, so you mind about: Product type, Occasion, Color, Gender, Designer, Price, Size, ...and more
  • 5. SCENARIO Some information is useful for browsing catalog Some information is useful for filtering catalog Some information is useful for both
  • 6. COMMON APPROACH Some information is useful for browsing catalog I can create  categories and include them in the navigation menu
  • 7. COMMON APPROACH Some information is useful for filtering catalog I can configure some attributes to be used as filters in layered navigation
  • 8. COMMON APPROACH Some information is useful for both I have to create attributes in addition to categories and duplicate the same data
  • 9. DRAWBACKS I have to keep attribute options in sync with category children I have to maintain proper correspondence between product attribute values and category assignment Filter redundancy
  • 12. THE SOLUTION Extending Magento layered navigation to use category branches such as filters!
  • 13. LET'S CODE ! Create custom module Add system configuration Create new catalog layer filter block Create new catalog layer filter model Extend catalog layer view block Define module layout update
  • 14. ADD SYSTEM CONFIGURATION <!--?xml version="1.0"?--> <config> <tabs> <bitbulltab translate="label" module="bitbull_categorylayered"> <label>BITBULL</label> <sort_order>999</sort_order> </bitbulltab> </tabs> <sections> <bitbull_categorylayered translate="label" module="bitbull_categorylayered"> <label>Category Layered Navigation</label> <tab>bitbulltab</tab> <frontend_type>text</frontend_type> <sort_order>100</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> <groups> <configuration translate="label" module="bitbull_categorylayered"> <label>Configuration</label> <sort_order>10</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> <fields> <categories translate="label"> <label>Category List</label> <comment>List of categories to use in layered navigation</comment> <frontend_model>bitbull_categorylayered/config_categories</frontend_model> <backend_model>adminhtml/system_config_backend_serialized_array</backend_model> <sort_order>20</sort_order> <show_in_default>1</show_in_default>
  • 15. EXTEND MAGE_CATALOG_BLOCK_LAYER_VIEW / 1 Child blocks initialization, one for each configured category class Bitbull_CategoryLayered_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View{ /** * Prepare child blocks * @return Mage_Catalog_Block_Layer_View */ protected function _prepareLayout() { /** @var Mage_Catalog_Model_Category $current_category */ $current_category = Mage::helper('catalog')->getCategory(); foreach ($this->_layeredCategories as $layeredCatConfig) { $categoryId = $layeredCatConfig['category']; // check if current category navigation is in path of categorylayered if ($current_category->getId() && in_array($categoryId, $current_category->getPathIds())) { continue; } // create categoryLayered filter block $blockAttributes = array( 'categoryId' => $layeredCatConfig['category'], 'requestParam' => $layeredCatConfig['filter'] ); $blockName = 'categorylayered_'.$categoryId; $categoryBlock = $this->getLayout() ->createBlock($this->_categoryLayeredBlockName, $blockName, $blockAttributes) ->setLayer($this->getLayer())
  • 16. EXTEND MAGE_CATALOG_BLOCK_LAYER_VIEW / 2 For each configured category, add block to filters list managing position class Bitbull_CategoryLayered_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View { /** * Get all layer filters * @return array */ public function getFilters() { $filters = parent::getFilters(); foreach ($this->_layeredCategories as $layeredCatConfig) { $categoryId = $layeredCatConfig['category']; $position = $layeredCatConfig['position']; if (($categoryFilter = $this->_getLayeredCategoryFilter($categoryId))) { $filters = array_merge( array_slice( $filters, 0, $position ), array($categoryFilter), array_slice( $filters, $position, count($filters) ) ); }
  • 17. CREATE NEW CATALOG LAYER FILTER MODEL / 1 Retrieve subcategories as filter items. class Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered extends Mage_Catalog_Model_Layer_Filter_Abstract { /** * Get data array for building filter items * @return array */ protected function _getItemsData() { $key = $this->getLayer()->getStateKey().'_'.$this->_requestVar; $data = $this->getLayer()->getAggregator()->getCacheData($key); if ($data === null) { // load children for root category or current selected category for this filter $categories = $this->_appliedCategory instanceof Mage_Catalog_Model_Category ? $this->_appliedCategory->getChildrenCategories() : $this->_rootCategory->getChildrenCategories(); $this->getLayer()->getProductCollection() ->addCountToCategories($categories); $data = array(); foreach ($categories as $category) { /** @var $category Mage_Catalog_Model_Categeory */ if ($category->getIsActive() && $category->getProductCount()) { $data[] = array( 'label' => Mage::helper('core')->escapeHtml($category->getName()), 'value' => $category->getId(), 'count' => $category->getProductCount(),
  • 18. CREATE NEW CATALOG LAYER FILTER MODEL / 2 Apply filter logic adding a join on catalog/category_product_index table class Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered extends Mage_Catalog_Model_Layer_Filter_Abstract /** * Apply category filter to layer * @param Zend_Controller_Request_Abstract $request * @param Mage_Core_Block_Abstract $filterBlock * @return Bitbull_CategoryLayered_Model_Catalog_Layer_Filter_CategoryLayered */ public function apply(Zend_Controller_Request_Abstract $request, $filterBlock) { $filter = (int) $request->getParam($this->getRequestVar()); if (!$filter) { return $this; } // load data for applied category $this->_appliedCategory = Mage::getModel('catalog/category') ->setStoreId(Mage::app()->getStore()->getId()) ->load($filter); if ($this->_appliedCategory->getId()) { // create join and conditions for additional category filter $tableAlias = 'category_layered_'.$this->_rootCategory->getId(); $conditions = array(); $conditions['category_id'] = $filter; $conditions['store_id'] = Mage::app()->getStore()->getId(); if (!$this->_appliedCategory->getIsAnchor()) { $conditions['is_parent'] = 1;
  • 20. CONCLUSION By extending Magento layered navigation as shown we can: avoid data replication and maintenance filter deeply until selected category has subcategories avoid filter redundancy Without touching the core
  • 21. THANK YOU ! NAMASTÉ ANY QUESTION ? @nadiasala nadia.sala@bitbull.it https://github.com/bitbull-team/magento-module-category-layered