I need to have the categories list display alphabetically by default. I have a large number of categories/sub-categories and list them in various ways around the site. How can I always have the categories list alphabetically?
Thank you
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 method
<?php $_filters = $this->getFilters() ?>
to show the layered navigation content. This method is defined in Mage_Catalog_Block_Layer_View
class and the file is in the location app/code/core/Mage/Catalog/Block/Layer/View.php
. Let us analyze this method.
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;
}
I called $filters
as layered navigation filter array. From above code you can see that category filtering
and attribute 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.
<?php
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;
}
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>
<modules>
<Programmerrkt_Layerednav>
<version>0.1.0</version>
</Programmerrkt_Layerednav>
</modules>
<global>
<models>
<catalog>
<rewrite>
<!-- Model rewrite-->
<layer_filter_category>Programmerrkt_Layerednav_Model_Layer_Filter_Category</layer_filter_category>
</rewrite>
</catalog>
</models>
</global>
</config>
config.xml
tells to magento that I am going to overwrite the core model Mage_Catalog_Model_Layer_Filter_Category
.
Location :app/etc/modules/Programmerrkt_Layerednav.xml
<config>
<modules>
<Programmerrkt_Layerednav>
<active>true</active>
<codePool>local</codePool>
</Programmerrkt_Layerednav>
</modules>
</config>
This file activates our module.
Location :app/etc/code/local/Programmerrkt/Layerednav/Model/Layer/Filter/Category.php
<?php
class Programmerrkt_Layerednav_Model_Layer_Filter_Category extends Mage_Catalog_Model_Layer_Filter_Category {
/**
* 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) {
$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;
}
}
Section that sorts $data
array is
function cmp($a, $b)
{
return strcmp($a["label"], $b["label"]);
}
usort($data, "cmp");
Thats it. Clear cache and then load your pages.
Note: This is for sorting category listing in layered navigation
Thanks
sort($array)
and then foreach item in the array display the category