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
Best Answer
You need to make sure that Is Anchor is set to Yes for the categories where you want to display the layered navigation. You can edit this for each category under the Display Settings tab in admin.
The layered navigation block is included in the layout only for the
catalog_category_layered
handle:and this handle is loaded only for the categories that have Is Anchor is set to Yes.