Wednesday, January 18, 2012

Add sorting attribute in product list page in Magento

You can see the top pager in product list page in which there is sort by dropdown.










Magento by default provides following sort by attributes for any category -
1.  Position
2.  Name
3. Price
4. Brand

Lets say I want to add an extra attribute net discount for sorting. We have to create an attribute in magento admin panel (Catalog->Manage Attributes) , lets name it discount and set sorting in product listing in frontend properties as yes as shown in following image.















Now go to Catalog->Manage Categories in Magento Admin Panel. Click on Any Category->Display Settings tab and you can see your new attribute under Available Product Listing sorting by -

Now when you have added this attribute it would be available on all product list pages but what would happen when one clicks on it??
 Do we have to write action, controller, model for that , luckily we have better option. We just need to modify catalog product collection (app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php) You can create a local copy in (app/code/local/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php)

Inside function addAttributeToSort we have to add an following code -
    if ($attribute == 'discount' && $storeId != 0) {
      $this->getSelect()->joinLeft(
            array('price_index_new' => $this->getTable('catalog_product_index_price')),
                "price_index_new.entity_id = e.entity_id AND price_index_new.website_id =1 AND price_index_new.customer_group_id =0",
                array("((price_index_new.price-price_index_new.final_price)/(price_index_new.price)) as netdiscount")
                );
         $this->getSelect()->order("netdiscount {$dir}");

      return $this;
    }

That is easy :)

Now I think when I click sort by discount I should by default get the results in desc order rather than ascending order, what should be done for that?
We just need to modify a template file. (app/design/fronend/base/default/template/catalog/product/list/toolbar.phtml) create a copy - (app/design/fronend/default/default/template/catalog/product/list/toolbar.phtml)

around line 8- you can find
<?php foreach($this->getAvailableOrders() as $_key=>$_order): ?>
add if/else here as following -
            <?php foreach($this->getAvailableOrders() as $_key=>$_order): ?>
                <option value="<?php if ($_key=='discount') echo $this->getOrderUrl($_key, 'desc'); else echo $this->getOrderUrl($_key, 'asc'); ?>"<?php if($this->isOrderCurrent($_key)): ?> selected="selected"<?php endif; ?>>
                    <?php echo $this->__($_order) ?>
                </option>
            <?php endforeach; ?>

That is it. Happy Sorting :)













3 comments:

  1. Thanks! Very neat implementation :)

    ReplyDelete
  2. Thank you! I'm new to Magento and don't know much about sorting. I'm using an extension now - https://amasty.com/improved-sorting.html - to add more sorting options.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete