Show products on sale in Magento
By default Magento (up to 1.1.6 version) does not have item on sale list view. If you were to open the http://demo.magentocommerce.com link and go to Furniture > Living Room you would get a grid (or a list) view of all the products inside the category Living Room as displayed on the picture below.
As you can see, you have three filters available by default (Best Value, Name and Price). So what if we want to add another one here?
Easiest way that i found is to simply copy
app/code/core/Mage/Catalog/Block/Product/List/Toolbar.php
to
app/code/local/Mage/Catalog/Block/Product/List/Toolbar.php
Then open it and modify the _construct() function. Look for the following part of the code
$this->_availableOrder = array( …
You need to insert the following into the array, ’special_price’ =>$this->__(’Special Price’). Final code should look like
$this->_availableOrder = array(
‘position’ => $this->__(’Best Value’),
‘name’ => $this->__(’Name’),
‘price’ => $this->__(’Price’),
’special_price’ =>$this->__(’Special Price’)
);
Now if you refresh your Furniture > Living Room page you should see special price on the dropdown list among previous default filters like on the image below. I used Special Price above as a fancy title for items on sale. You can put any string here you prefer.
Now we have added special price (product on sale) on the dropdown. If we click on it, it wont work. Why doesn’t it work? Well, we haven’t really added any logic to it for work and we haven’t put any of our products on sale.
First let’s put some product on sale. Since this demo is focused on Living Room category I will login to my Magento admin and look for, let’s say, Couch. Then we set up some special price to mark the product as being on sale. See the image below.
Now if we refresh the Furniture > Living Room page we would see this special price next to the Couch product. So far, so good. Now if we click the dropdown and select Special price, nothing happens. Products are show just as we would selected Price from dropdown. Obviously we are missing something here.
If you were to click on the Price your URL link would change to include something like “?order=price&dir=asc“, clicking on Special Price changes link to something like “?order=special_price&dir=asc” so we are on the right path. So why don’t we see only products we marked as having special price, like Couch in our example.
First let’s get back to the Toolbar.php file I mentioned above. Notice the ’special_price’ =>$this->__(’Special Price’). Where does this special_price come from? To find out where does ’special_price’ come from, we need to open
app/design/frontend/default/mycustom/template/catalog/product/list.phtml.
If you have a default version of 1.1.6 file, then scroll down to line 101, and under it, on line 102 insert the following
<?php echo(’<pre>’); print_r($_product->debug()); echo(’<pre>’); ?>
Look at the image below to see my example.
Now refresh your Furniture > Living Room page. You should be able to see individual product properties now like in the image below.
What we need to do now is tu use the fact that only products that have been assigned Special price have the property special_price. We already have the mechanism of changing URL to make the order=special price like “?order=special_price” so now we need to modify the grid that is displaying our products, that’s list,phtml file. We need to say the following to the grid: If the order is special price then show only the items that have the special_price property assigned to them.
Lastly, open your app/design/frontend/default/mycustom/template/catalog/product/list.phtml file. If you look closer at the file and the frontend page grid you will see you have two states Grid view and List view. We’ll do this the faster way and duplicate some of the code:
Put this at the very top of the list.phtml file,
<?php $orderFilterType = $this->getRequest()->getParam(’order’); ?>
Go to line 91 (deafault file), line that starts with
<?php $i=0; foreach ($_productCollection as $_product): ?>
you need to put the following into it
<?php if(isset($orderFilterType) && $orderFilterType === ’special_price’): ?>
<?php if($_product->getData(’special_price’) !== null): ?>
<?php echo(’<!– product ‘. $_product->getName() .’ has been sold in qty: ‘.$_product->ordered_qty.’ –>’); ?>
(Not complete code, look into the attachec list.phtml file)
Important thing is to wrap the entire Grid View and List view outputting part with this, and in the else statement you put the original Grid View and List view. That way if this is not special_price view, out template works as it would by default.
Bellow I attached the working list.phtml file from my example for you to see and examine. This is not most best solution since some code in list.phtml is duplicated. I leave it up to you to clean it up.
Remember to make modifications to Toolbar.php as described above. These are the only two files needed to make this work.
If you manage to implement all of the above, you should now see only the Couch product (in my example) on the list when you select Special Price from dropdown.
Hope some of you find this tutorial usefull.












Good to know.
This must be a backend feature!
This is a great post. This will come in handy with most shop fronts with magento. Thank you. Have bookmarked this page for future reference.
I find it odd that you would choose to not show the items that don’t have a special price, when all you are doing is a sort. The sort should not change the number of items viewable. It messes up the navigation concepts.
Hi Joy… I appreciate the comment.
Just to throw in my thoughts
… My full version, the one I made for client, of this “sort by special price” is somewhat different. However what’s odd about hiding items that do not have special price in “sort by special price” functionality?
“sort should not change the number of items viewable”… I disagree with you on this one. What I did is that I used already written functionality of Magento grid-list view and simply throw in additional filter with if statement. Layered navigation does the same thing.
To be more precise I had the case where client wanted this functionality on a special page without any layered navigation and sort by filters… This is just an example of how it can be done.
Thank you for this. Is there a way to modify this procedure to allow a sort by Rating?
PS - The List file link you have included above does not work. Error message is Fatal error: Using $this when not in object context in /home/activec/public_html/wp-content/uploads/2008/11/list.phtml on line 35
Just right click and Save as… Seems like Wordpress tries to execute the file
thanks for sharing this tip, I needed it
This post is so informative me and assisted me to understand the entire subject. I am waiting for your up coming post.
Best of luck!