Extending Magento Layered Navigation
-
Upload
nadia-sala -
Category
Software
-
view
596 -
download
2
Transcript of Extending Magento Layered Navigation
![Page 1: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/1.jpg)
EXTENDING MAGENTOLAYERED NAVIGATIONMAGE TITANS ITALIA - MILAN, FEBRUARY 5TH 2016
Nadia Sala
Extending Magento layered navigation by Nadia Sala
![Page 3: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/3.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/4.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/5.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/6.jpg)
COMMON APPROACHSome information is useful for browsing catalog
I can create categories and include them in the navigationmenu
![Page 7: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/7.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/8.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/9.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/10.jpg)
![Page 11: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/11.jpg)
![Page 12: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/12.jpg)
THE SOLUTIONExtending Magento layered navigation
to use category branches such as filters!
![Page 13: Extending Magento Layered Navigation](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/13.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/14.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/15.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/16.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/17.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/18.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/20.jpg)
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](https://reader034.fdocuments.net/reader034/viewer/2022042610/589af5e91a28ab3e288b59f5/html5/thumbnails/21.jpg)
THANK YOU !NAMASTÉ
ANY QUESTION ?
@nadiasala [email protected]
https://github.com/bitbull-team/magento-module-category-layered