Weitere ähnliche Inhalte Ähnlich wie Extending Magento Layered Navigation (20) Kürzlich hochgeladen (20) Extending Magento Layered Navigation3. 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
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
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