Search code examples
magentofiltermagento-1.7categorieslayered-navigation

Subcategories in layered navigation filter


I have a category with simple two-level structure like this:

Category #1
- Subcategory
- Subcategory
- ...
Category #2
- Subcategory
- Subcategory
- ...

Currently to filter by subcategories - you have to select top-level category first.

How to show subcategories of all top-level categories in layered navigation filter?

Note: Subcategories should by effected by other selected attribute filter.


Solution

  • While experimenting with Magento files I've found the answer to my question.

    1. Copy

      app/code/core/Mage/Catalog/Model/Layer/Filter/Category.php
      to
      app/code/local/Mage/Catalog/Model/Layer/Filter/Category.php

    2. Open copied file. And replace _getItemsData with code below:

      /**
       * Get data array for building category filter items
       *
       * @return array
       */
      protected function _getItemsData()
      {
        $key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
        $data = $this->getLayer()->getAggregator()->getCacheData($key);
      
        if ($data === null) {
          // Get root category
          $root_category = Mage::getModel('catalog/category')->load(2);
      
          // Get main categories
          $data = array();
          $main_categories = $root_category->getChildrenCategories();
          foreach ($main_categories as $main_category) {
            if (!$main_category->getIsActive()) continue; // Ommit inactive
            // Get sub categories to list
            $sub_categories = $main_category->getChildrenCategories();
      
            // Add count to subcategories
            $this->getLayer()->getProductCollection()
              ->addCountToCategories($sub_categories);
      
            foreach ($sub_categories as $sub_category) {
              // Ommit inactive and zero product count sub categories
              if ($sub_category->getIsActive() || !$sub_category->getProductCount()) continue;
      
              // Output subcategories
              $data[] = array(
                'label' => Mage::helper('core')->htmlEscape($sub_category->getName()),
                'value' => $sub_category->getId(),
                'count' => $sub_category->getProductCount(),
                'parent' => $main_category->getName(), // Store parent name to group in template
              );
            }
          }
      
          $tags = $this->getLayer()->getStateTags();
          $this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
        }
        return $data;
      }
      

    You might be interested in rewriting some other functions such as getResetValue, etc. I had to rewrite template to group subcategories by main categories.

    Result (sorry cant post images directly):

    Before: https://i.sstatic.net/skZpi.png

    After: https://i.sstatic.net/QxPhq.png