Magento – Magento layered navigation attribute option sort by name not position

layered-navigationmagento-1.9

Basically Magento attribute option takes database order by default if we provide position it will shows based on that order. Like below

 color:  blue
            green
            black

    size:   s
            xl
            M
    housing: 9
             5
             99
             10
             bold
             ancle
             raise
             home

Like this I created Option same way it will in front end layered navigation

But my requirement is need to show in front end like below

color: black
       blue
       green
size:  m
       s
       xl


housing:     5
                 9
                 10
                 99
                 ancle
                 bold
                 home
                 raise

like this I need I don't want to provide position for every attribute option because I have lot of options having some attributes, so I am planing to display alphabetically, how admin created I don't care.

If anyone knows please help me where to change this order

Best Answer

Sorting can be done at the template level, but my preference would be to handle this in the block level.

To get to the right place, start at the template, like here:

File: app/design/frontend/base/default/template/catalog/layer/filter.phtml

<?php foreach ($this->getItems() as $_item): ?>

The call chain looks like this:

1. (36): app/design/frontend/base/default/template/catalog/layer/filter.phtml
2. (122): Mage_Catalog_Model_Layer_Filter_Abstract->getItems()
3. (120): Mage_Catalog_Model_Layer_Filter_Abstract->_initItems()

So from the template we end up in Mage_Catalog_Model_Layer_Filter_Abstract::_initItems:

protected function _initItems()
{
    $data = $this->_getItemsData();
    $items=array();
    foreach ($data as $itemData) {
        $items[] = $this->_createItem(
            $itemData['label'],
            $itemData['value'],
            $itemData['count']
        );
    }
    $this->_items = $items;
    return $this;
}

We can see how they are generated, using method $this->_createItem. This is the perfect point to inject our override. But on an abstract class, we can't quite get to it without a core/local pool replacement (not ideal).

Suggested Solution

  1. Create a block rewrite on catalog/block_layer_filter_attribute
  2. Implement overriding method getItems on your rewrite class
  3. Implement sorting in your rewrite class on items

So my class might look like this:

class Namespace_Module_Block_Catalog_Layer_Filter_Attribute
    extends Mage_Catalog_Block_Layer_Filter_Attribute
{

    protected function _sortItems(
        Mage_Catalog_Model_Layer_Filter_Item $a,
        Mage_Catalog_Model_Layer_Filter_Item $b
    ) {
        return strnatcmp($a->getLabel(), $b->getLabel());
    }

    public function getItems()
    {
        $result = parent::getItems();

        usort($result, array($this, '_sortItems'));

        return $result;
    }

}

I should note that this only applies to the generic attribute filter. Magento implements custom filters also for price, decimal, and category types. If you need to sort options on those, too, then create additional block rewrites to sort in a similar way.

Related Topic