Extending Magento Layered Navigation

21
EXTENDING MAGENTO LAYERED NAVIGATION MAGE TITANS ITALIA - MILAN, FEBRUARY 5TH 2016 Nadia Sala Extending Magento layered navigation by Nadia Sala

Transcript of Extending Magento Layered Navigation

Page 1: Extending Magento Layered Navigation

EXTENDING MAGENTOLAYERED NAVIGATIONMAGE TITANS ITALIA - MILAN, FEBRUARY 5TH 2016

Nadia Sala

Extending Magento layered navigation by Nadia Sala

Page 2: Extending Magento Layered Navigation

ABOUT MEPHP DEVELOPER

MAGENTO BACKEND DEVELOPER

@nadiasala [email protected]

Page 3: Extending Magento Layered Navigation

THE STORY"Once upon a time there was an e-commerce website that

exposed a catalog with many descriptive information."

Page 4: Extending Magento Layered Navigation

You can imagine a fashion catalog, so you mind about:

Product type, Occasion, Color,

Gender, Designer, Price, Size,

...and more

Page 5: Extending Magento Layered Navigation

SCENARIOSome information is useful for browsing catalog

Some information is useful for filtering catalog

Some information is useful for both

Page 6: Extending Magento Layered Navigation

COMMON APPROACHSome information is useful for browsing catalog

I can create  categories and include them in the navigationmenu

Page 7: Extending Magento Layered Navigation

COMMON APPROACHSome information is useful for filtering catalog

I can configure some attributes to be used as filters inlayered navigation

Page 8: Extending Magento Layered Navigation

COMMON APPROACHSome information is useful for both

I have to create attributes in addition to categories andduplicate the same data

Page 9: Extending Magento Layered Navigation

DRAWBACKSI have to keep attribute options in sync with categorychildrenI have to maintain proper correspondence betweenproduct attribute values and category assignmentFilter redundancy

Page 10: Extending Magento Layered Navigation
Page 11: Extending Magento Layered Navigation
Page 12: Extending Magento Layered Navigation

THE SOLUTIONExtending Magento layered navigation

to use category branches such as filters!

Page 13: Extending Magento Layered Navigation

LET'S CODE !Create custom moduleAdd system configurationCreate new catalog layer filterblockCreate new catalog layer filtermodelExtend catalog layer viewblockDefine module layout update

Page 14: Extending Magento Layered Navigation

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>

Page 15: Extending Magento Layered Navigation

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())

Page 16: Extending Magento Layered Navigation

EXTEND MAGE_CATALOG_BLOCK_LAYER_VIEW / 2

For each configured category, add block to filters listmanaging 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)

)

);

}

Page 17: Extending Magento Layered Navigation

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(),

Page 18: Extending Magento Layered Navigation

CREATE NEW CATALOG LAYER FILTER MODEL / 2

Apply filter logic adding a join oncatalog/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;

Page 20: Extending Magento Layered Navigation

CONCLUSION By extending Magento layered navigation as shown we can:

avoid data replication and maintenancefilter deeply until selected category has subcategoriesavoid filter redundancy

Without touching the core

Page 21: Extending Magento Layered Navigation

THANK YOU !NAMASTÉ

ANY QUESTION ?

@nadiasala [email protected]

https://github.com/bitbull-team/magento-module-category-layered