4

I am having an issue. I need to show the sub-category layered navigation on the SUBCATEGORY page of a store that I am working on. You guys already know that on the subcategory layered navigation is already shown on the MAIN Category page(s). Please understand that I want it to show on both the Category(s) and Sub-Category(s) pages. Please view the images to see what I have already.

Main Category Page! Main Category Layered navigation

Sub Category Page! with Layered Navigation (Limited sub category list) Sub Category Layered Navigation (Limited list)

But to in getting the limited sub category layered navigation I tried this: https://stackoverflow.com/questions/8795810/magento-showing-sibling-categories-in-layered-navigation

All I need is help with is editing:

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

For this line of code to show the full sub category on the sub category page and highlight the current/active category

        if(count($categoty->getChildrenCategories())){
    $categories = $categoty->getChildrenCategories();
}else{
    $categories = $categoty->getParentCategory()->getChildrenCategories();
}
4

As you already know the real category filtering is taking place in app/code/core/Mage/Catalog/Model/Layer/Filter/Category.php, more specifically in _getItemsData(). Let us inspect that method.

<?php
            $categoty   = $this->getCategory();
            $categories = $categoty->getChildrenCategories();

            $this->getLayer()->getProductCollection()
                ->addCountToCategories($categories);

            $data = array();

            foreach ($categories as $category) {
                if ($category->getIsActive() && $category->getProductCount()) {
                    $data[] = array(
                        'label' => Mage::helper('core')->escapeHtml($category->getName()),
                        'value' => $category->getId(),
                        'count' => $category->getProductCount(),
                    );
                }
            }

As you can see, the method loads child categories of $categoty in layered navigation filter. That means we need to set this variable to a parent category in level 2 (Every main categories lies in level 2), according to the current category that we stands.

We can achieve this in many ways. In my method, I dig into the codes further and find the exact position where the category is set for layered navigation.

It resides here app/code/core/Mage/Catalog/Model/Layer.php in getCurrentCategory(). The method look like this.

<?php
 public function getCurrentCategory()
{
    $category = $this->getData('current_category');
    if (is_null($category)) {
        if ($category = Mage::registry('current_category')) {
            $this->setData('current_category', $category);
        }
        else {
            $category = Mage::getModel('catalog/category')->load($this->getCurrentStore()->getRootCategoryId());
            $this->setData('current_category', $category);
        }
    }

    return $category;
}

In short, it loads the current category to the variable $categoty (variable that I mentioned in _getItemsData()) if it set, otherwise loads the root-category to variable categoty. Replace this method with this code

<?php
/**
 * Retrieve current category model
 * If no category found in registry, the root will be taken
 *
 * @return Mage_Catalog_Model_Category
 */
public function getCurrentCategory()
{
    $category = $this->getData('current_category');

    if (is_null($category)) {
        $category = Mage::registry('current_category');
        if ($category) {
            /*
             * Check whether the current category is in level 2.
             * If yes set it as current category.
             * Else check for any parent categories with level 2
             */
            if($category->getLevel() != 2) {
                //gets all parent categories
                $parentCategories = Mage::registry('current_category')->getParentCategories();
                /*
                 * If parent categories exist,search for parent categories in level 2.
                 * If exist set it as current category.
                 *else set root category as current category.
                */
                if(count($parentCategories) > 0)
                {
                    foreach ( $parentCategories as $parentCategory ) {
                        if($parentCategory->getLevel() == 2 ) {
                            $category = Mage::getModel('catalog/category')->load($parentCategory->getId());
                            $this->setData('current_category', $category);
                            break;
                        }
                    }
                }
                else {

                    $category = Mage::getModel('catalog/category')->load($this->getCurrentStore()->getRootCategoryId());
                    $this->setData('current_category', $category);
                }
            }
            else {

                $this->setData('current_category', $category);
            }
        }
        else {

            $category = Mage::getModel('catalog/category')->load($this->getCurrentStore()->getRootCategoryId());
            $this->setData('current_category', $category);
        }
    }

    return $category;
}

What we are doing here is, we get the parent category in level 2 from the current category and set it to $categoty, so that we can see all child categories in layered navigation.

As I already mentioned, you can achieve it in many ways. All you need to do is to set $categoty variable with parent category in level 2. Above I have altered the root files. It is not a good practice. You have to create a module that rewrites the model file app/code/core/Mage/Catalog/Model/Layer.php and then overwrite the method getCurrentCategory().

Hope it helps

1

One more option is to not rewrite any class, but remove the category filter from the layered navigation block at all in the category layout file. And then add a new custom block, that will show categories as you wish. This block can use custom caching and show better performance. This is more time consuming approach for sure, but it gives you more flexibility and saves from conflicts resolving in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.