More Flexible Approach for Listing Sale Products in Magento

Featured Image

One of my recent articles was on the subject of sorting “On Sale” product in Magento. The following is a cleaner and more advanced look at how—with few tricks and smart moves—you can reuse existing Magento code and modify it to suit your needs.

Product can be “on sale” in two ways:

1. when an item has a special price assigned to it on the individual level, or

2. when a special promotion “covers” the item

It is important to remember that you don’t have to set up the special price on each product to get it to be on sale; you can simply create a promotion rule and say something like “Set all the products in Category X to be on sale.”

I provided few screenshots at the bottom of this article to provide a closer look at what I’m talking about. I will not go into too much details here since this is a bit more advanced HOW TO, but here is the process in a nutshell:

First, create a copy of /catalog/product/list.phtml file and name it onsale_list.phtml. Here is my version of onsale_list.phtml file.

Second,  “activate” this new file. There are few ways you can do this. Let’s say you wish to assign this onsale_list.phtml on one of our categories, named “On Sale,” for instance.

We then go to Categories > Manage Categories > On Sale… select Custom design and under Custom layout update, place the following:

product_list_toolbar

If you now go to your category On Sale, it should only show products you have assigned to category “On sale” that have a special price set to them.

If you now wish to apply Promotion rules to entire “On sale” category, then you simply assign a rule to one item, and all the items assigned to the same “On sale” category (covered by promotion rules) will be automatically listed in the grid.

Basically, the magic is in one simple IF statement

< ?php if(($_product->special_price !== null) or ($_product->_rule_price !== null)): ?>

for each block that lists products.

Check out the screenshots, they explain a lot.

On Sale 3

On Sale

Hope you find a way to try this out.  Feel free to provide some feedback or additional suggestions.

20
Top

Enjoyed this post?

Subscribe to our RSS Feed, Follow us on Twitter and spread it to your friends!

Author

CTO / Magento Certified Developer Plus @inchoo. Father, husband!

Other posts from this author

Discussion 20 Comments

Add Comment
  1. Tony

    Hi, thanks for the article. I don’t understand how adding:

    product_list_toolbar

    to the custom layout calls up the file onsale_list.phtml. Could you please help?

  2. Julien

    Hi,

    Good article but is it possible to have same behavior without create an “On Sale” category, just to put a block in a CMS page which is listing all products with a special price ?

    Thanks.

  3. Martin

    I’ve tried to follow your instructions and am running into the same problem of assigning the new onsale_list.phtml file to the category. I changed the code in the page to see if the page is called, but it still displays the list.phtml file.

    Please elaborate. Thanks.

  4. Hi. It is possible to put it just to CMS page like this:
    {{block type=”catalog/product_list” name=”specials” as=”specials” template=”templatename.phtml”}}

    but how can I handle number of products per page?
    When I normally have 30 products pre page and 20 has no special price the result will show only 10 products. The worse thing is that the number of products is on every page different.

  5. @Marting and @Tony:

    You have to tell Magento to use your new template, so what you want to place in the Custom Layout field is:

    catalog/product/onsale_list.phtml

  6. Oops, the comment system didn’t like my code snippet. 2nd try:

    catalog/product/list_sale.phtml

  7. Still no luck. Every line – except the path/to/template.phtml – should be enclosed in xml tags:
    reference name=”product_list”
    action method=”setTemplate”
    template
    catalog/product/list_sale.phtml
    /template
    /action
    /reference

  8. PS: @Branko:

    Thanks for sharing your knowledge.

    It would be very helpful if you indicated which characters/tags are allowed in your comments or how to post code.

  9. kris gale

    didn’t realize you were allowed to access ‘protected’ data members of the product object within template code… i was previously parsing the result of $this->getPriceHtml($_product,true) for instances of class=”price”, “Special Price”, and “As Low As”… $_product->sale_price, $_product->min_price is so much easier!

  10. Roger How

    I can only get this to display products with a special price and not those with a catalog price rule.

    ie this part of the statement: $_product->_rule_price !== null isn’t working. If I use it on it’s own I get no products returned even though I have a whole category discounted with a rule.

    I’m using Magneto 1.4.1.1 Could that be the problem?

    Any idea how I can get this to work?

  11. Aydin

    I am having the same problem as previous post by Roger. I am using the phtml file provided by Branko. It only shows the products that have a special price set individually, but not the ones covered by catalog price rules.

    Also running on 1.4.1.1. Any help would be appreciated.

  12. shailesh thapa

    Hi, i want to make paging on bestselling products without refreshing the pages with help of jquery.Can anyone help me.

    Thanks

  13. This is really very helpful to all magento developer.
    I feel satisfied after radeing that one.

  14. Surely you have to assign something to the toolbar to keep it in step with the displayed results?

  15. serks

    This doesn’t work for catalog price rule specials.
    I dont understand what you mean by this…

    “If you now wish to apply Promotion rules to entire “On sale” category, then you simply assign a rule to one item, and all the items assigned to the same “On sale” category (covered by promotion rules) will be automatically listed in the grid.”

    Please elaborate on this if you can Branko

    Thanks

  16. carl

    I too have tried to use catalog price rules, but with no luck. it just will not work work. v1.6

    As serks said, please elaborate Branko.

    Thanks

  17. rob

    ok guys this is what you can do.

    create the file as he suggested but place it inside ‘page/html/’ (preferable in your custom layout folder not the default one)

    on your CMS page you can put:

     {{block type="page/html" template="page/html/onsale_list.phtml"}}
    

    in his file. instead of using

    <?php $_productCollection=$this->getLoadedProductCollection() ?>
    

    which gets every single product and puts it inside $_productCollection

    you could do this:

    <?php
    $_productCollection = Mage::getResourceModel('catalog/product_collection')
        ->addAttributeToSelect('*') // select all attributes
        ->addAttributeToFilter('special_price', array('notnull' => 1)) // only products where special_price is not empty
        ->setOrder('special_price', 'ASC'); // sort products by attribute special_price  in ascending order
    // Directly under the
    <?php foreach ($_productCollection as $_product): ?>
    // you would put
    $_product->load();
    ?>
    

    this will only retrieve products with special price set.

    you can then edit his HTML to display these results.
    you will have to update his HTML accordingly places where you see things like if ($_product->special_price .. etc.etc. will have to be removed as my code will already filter that stuff out

    you can even get smart with this and do something like this inside your CMS page

     <h1>Special Priced Products</h1>
    {{block type="page/html" template="page/html/onsale_list.phtml"}}
    <h1>Normally Priced Products</h1>
    // then all of your normal product stuff here
    

    and bingo no special stuff has to be created no new categories simple isn’t it?

  18. rob

    i should note that in my previous post. using this method renders things like ->getToolbarHtml() and ->getMode()
    useless because calling the phtml directly from a CMS page would be setting $this. to the CMS handler not the catalog handler. but!! in using my suggested method you can customize the product list using all the same product manipulation functions(ie. getName getProductUrl etc.) you can create your own stylings to display this data as you wish. you can create a custom CMS page such as Special_Offers.html(CMS page) using the {{block}} to display the contents of onsale_list.phtml .

    i should also note that it seems in order to properly add the {{block}} on a CMS page it may require you to do it in the “Html mode” in the CMS editer

    below is a simple example of a onsale_list.phtml

    &lt;?php
    $_productCollection = Mage::getResourceModel('catalog/product_collection')
        -&gt;addAttributeToSelect('*') // select all attributes
        -&gt;addAttributeToFilter('special_price', array('notnull' =&gt; 1)) // only products where special_price is not empty
        -&gt;setOrder('special_price', 'ASC'); // sort products by attribute special_price  in ascending order
    ?&gt;
     &lt;style type=&quot;text/css&quot;&gt;
       div.special-price-list { border-bottom:black 1px solid; margin-bottom:5px; padding-bottom:10px; }
       h5.special-price-title { text-align:center; font-size:15px; }
       div.special-price-desc {  position:absolute; margin-left:200px; margin-top:-125px; border:red 1px solid;  height:auto; width:300px; overflow:none; padding:10px 10px 10px 10px; }
       p.special-price-desc { position:absolute; margin-top:-20px; margin-left:10px; background:white; }
       div.special-price-control { position:absolute;  margin-top:-175px; margin-left:550px; }
     &lt;/style&gt;
    &lt;?php
    if ($_productCollection &lt; 1):
     echo 'There currently is no special offer products available';
    else:
     foreach($_productCollection as $_product):
      $_product-&gt;load();
      ?&gt;
            &lt;div class=&quot;special-price-list&quot; id=&quot;product-special-&lt;?php echo $_product-&gt;getId()?&gt;&quot;&gt;
                &lt;h5 class=&quot;special-price-title&quot;&gt;&lt;a href=&quot;&lt;?php echo $_product-&gt;getProductUrl() ?&gt;&quot; title=&quot;&lt;?php echo $this-&gt;htmlEscape($_product-&gt;getName()) ?&gt;&quot;&gt;&lt;?php echo $this-&gt;htmlEscape($_product-&gt;getName()) ?&gt;&lt;/a&gt;&lt;/h5&gt;
                &lt;p class=&quot;special-price-image&quot;&gt;
                    &lt;a href=&quot;&lt;?php echo $_product-&gt;getProductUrl() ?&gt;&quot; title=&quot;&lt;?php echo $this-&gt;htmlEscape($_product-&gt;getName()) ?&gt;&quot;&gt;
                        &lt;img src=&quot;&lt;?php echo $this-&gt;helper('catalog/image')-&gt;init($_product, 'small_image')-&gt;resize(135, 135); ?&gt;&quot; width=&quot;135&quot; height=&quot;135&quot; alt=&quot;&lt;?php echo $this-&gt;htmlEscape($_product-&gt;getName()) ?&gt;&quot; /&gt;
                    &lt;/a&gt;
                &lt;/p&gt;
                &lt;div class=&quot;special-price-desc&quot;&gt;&lt;p class=&quot;special-price-desc&quot;&gt;Description&lt;/p&gt;&lt;?php echo nl2br($_product-&gt;getShortDescription()) ?&gt;&lt;/div&gt;
                &lt;div class=&quot;special-price-control&quot;&gt;
                  &lt;?php echo $this-&gt;getPriceHtml($_product, true) ?&gt;
                  &lt;?php if($_product-&gt;isSaleable()): ?&gt;
                  &lt;button class=&quot;form-button&quot; onclick=&quot;setLocation('&lt;?php echo $this-&gt;getAddToCartUrl($_product) ?&gt;')&quot;&gt;&lt;span&gt;&lt;?php echo $this-&gt;__('Add to Cart') ?&gt;&lt;/span&gt;&lt;/button&gt;
                  &lt;?php else: ?&gt;
                  &lt;div class=&quot;out-of-stock&quot;&gt;&lt;?php echo $this-&gt;__('Out of stock') ?&gt;&lt;/div&gt;
                  &lt;?php endif; ?&gt;
                &lt;/div&gt;
            &lt;/div&gt;
    &lt;?php
     endforeach;
    endif;
    ?&gt;
    

    you’ll have to excuse my css. im not really one for designing. im a backend developer lol.

    as you can see this would be an example better suited for having it’s own page but could easily be used on say the “home page” or any page of your choosing

  19. Hi Rob,

    Didn’t get your last post, can you please help me with what exactly I should do.

  20. Shailendra

    I think when the number of products are more this if condition will effect the pagination.

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top