if you take a look on the template file for layered navigation (catalog\layer\view.phtml
), you can see that, layered navigation filtering is carried out by this call
<?php $_filters = $this->getFilters() ?>
So take a look on getFilters()
method in Mage_Catalog_Block_Layer_View
block class.
public function getFilters()
{
$filters = array();
if ($categoryFilter = $this->_getCategoryFilter()) {
$filters[] = $categoryFilter;
}
$filterableAttributes = $this->_getFilterableAttributes();
foreach ($filterableAttributes as $attribute) {
$filters[] = $this->getChild($attribute->getAttributeCode() . '_filter');
}
return $filters;
}
Here you can see that, the method returns an array $filters
, which is get filled in two sections. First the array get filled by category filters then it is filled by custom attribute filters. This means that, category filters are available in layered navigation by default
If we dig more and more, we will reach in the model class Mage_Catalog_Model_Layer_Filter_Category
, where the actual category filters for layered navigations are carried out. The method that we interested here is _getItemsData()
protected function _getItemsData()
{
$key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
$data = $this->getLayer()->getAggregator()->getCacheData($key);
if ($data === null) {
$categoty = $this->getCategory();
/** @var $categoty Mage_Catalog_Model_Categeory */
$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(),
);
}
}
$tags = $this->getLayer()->getStateTags();
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
}
return $data;
}
This is where category filters are preparing. The heart of this function is foreach
. It uses that loop to load the $data
variable(holds an array) which is then return to layered navigation filter. You can again see that, $data
holds only 3 parameter of a specific category. They are label
,value
and children count
. So the category section that present in layered navigation actually built up with these three values.
So this is the place that we need to work. By default categories are loading in random, means no filtering is applying there. What we need to do is, we need to sort the $data
variable in ascending order.
So rewrite this model as like this.
protected function _getItemsData()
{
$key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
$data = $this->getLayer()->getAggregator()->getCacheData($key);
if ($data === null) {
$categoty = $this->getCategory();
/** @var $categoty Mage_Catalog_Model_Categeory */
$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(),
);
}
}
function cmp($a, $b)
{
return strcmp($a["label"], $b["label"]);
}
usort($data, "cmp");
$tags = $this->getLayer()->getStateTags();
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
}
return $data;
}
This is the additional part that do the job for us
function cmp($a, $b)
{
return strcmp($a["label"], $b["label"]);
}
usort($data, "cmp");
This will filter categories in ascending order for layered navigation.
Note:: You are lucky, I have this in extension format. You can use it. This is the github page that holds that extension. Feel free to use it
Best Answer
There may be lot of ways to achieve this. In my method I am going to
rewrite
a core model file, so that it will set the layered navigation filter array with sorted category array.What is layered navigation filter array ? Sounds confusing. Then I will explain it little bit.
app/design/frontend/<your_package>/<your_theme>/template/catalog/layer/view.phtml
is the starting point of layered navigation blocks. In that file you can see that, it invokes below methodto show the layered navigation content. This method is defined in
Mage_Catalog_Block_Layer_View
class and the file is in the locationapp/code/core/Mage/Catalog/Block/Layer/View.php
. Let us analyze this method.I called
$filters
as layered navigation filter array. From above code you can see thatcategory filtering
andattribute filtering
are storing into this array seperately.We are interested in category filtering. The main actions of category filtering happens in Model file. The model file that we interested in is
app/code/core/Mage/Catalog/Model/Layer/Filter/Category.php
. Take a look on_getItemsData()
in that file.From the above code, you can see that
$data
is a multidimensional array that holds an UNSORTED arrays as its sub-arrays. We need to sort them in order to achieve our goal. In order to do that, I am gonna create a small module that overwrite this model and sort$data
array.Location :
app/etc/code/local/Programmerrkt/Layerednav/etc/config.xml
config.xml
tells to magento that I am going to overwrite the core modelMage_Catalog_Model_Layer_Filter_Category
.Location :
app/etc/modules/Programmerrkt_Layerednav.xml
This file activates our module.
Location :
app/etc/code/local/Programmerrkt/Layerednav/Model/Layer/Filter/Category.php
Section that sorts
$data
array isThats it. Clear cache and then load your pages.
Note: This is for sorting category listing in
layered navigation
Thanks