Magento: Setting columns and limiting products shown in grid magento help4 120x120I recently started experimenting with creating my own page templates and using the layout update XML to add content into the page. This works well for more complicated page designs and is particularly suitable for the homepage or landing pages. I did hit a minor snag however and that was when I added a product list or grid I couldn’t see how to specify the number of columns the grid should contain. As soon as you step away from the standard page templates the default of three items needs to be changed. Also, depending on how strict your page template is, you may need to be sure only a limited number of items are displayed.

Lets start with the basic XML you need to insert products from a specific category into the content block of your template.

<reference name="content">
<block type="catalog/product_list" name="home.catalog.product.list" alias="products_list" template="catalog/product/list.phtml">
   <action method="setCategoryId"><category_id>3</category_id></action>
</reference>

Fairly simple stuff, notice the action element is used to pass the category id to the setCategoryId method.

The first place I looked for a way to set the columns was in the template file mentioned above, since this is a design change that seems the most logical place. Magento is cleverer than that though and the template and module are already able to deal with the number of columns dynamically. There is a line in the template file that calls the method getColumnCount. The column count is a property of the module, so we can set this variable by passing in a value in the same way as we did for the category. Updated code is below.

<reference name="content">
<block type="catalog/product_list" name="home.catalog.product.list" alias="products_list" template="catalog/product/list.phtml">
   <action method="setCategoryId"><category_id>3</category_id></action>
   <action method="setColumnCount"><columns>2</columns></action>
</reference>

Obviously there must be a way of limiting the number of products that are displayed and it stands to reason that it would be something like the following line.

<action method="setLimit"><limit>2</limit></action>

But it seems Magento doesn’t want to make life easy on us and there doesn’t appear to be any way of passing a limit into the catalog/product_list module. It is the modules job of loading the data, so a quick look at the code quickly uncovers the following line that clearly show the data is loaded without any way of setting a limit (inside the _beforeToHtml method).

$this->_getProductCollection()->load();

In order to solve this problem I decided to resort to creating my own module, something that feels wrong for simple things like this. There are plenty of tutorials explaining how to create a Magento module but you can find the basics in my article: Creating a Magento Module.

Once you have got a basic module, you need to create a class that inherits from the product_list we were originally using. The file is in /app/code/core/Mage/catalog/Block/Product/List.php and the class name is Mage_Catalog_Block_Product_List.

You can then simply add a way of setting a limit and modify the _beforeToHtml method to use your new limit variable.

The following code will allow you to set a limit variable from your layout XML.

private $_limit;

public function setLimit($limit) {  
  $this->_limit = $limit;
}

public function getLimit() {  
  return $this->_limit;
}

The new load call in _beforeToHtml needs to call setPage first.

$this->_getProductCollection()->setPage(1, $this->_limit)->load();

And finally you can use a setLimit action in your XML. Don’t forget to swap the name of the module over to your newly created module though as the catalog/product_list has remained unchanged.

<block type="featuredproduct/limited" name="home.catalog.product.list.leftcol" alias="products_leftcol" template="catalog/product/list.phtml">
  <action method="setCategoryId"><category_id>3</category_id></action>
  <action method="setColumnCount"><columns>2</columns></action>
  <action method="setLimit"><limit>2</limit></action>
</block>
  • notme

    You have a syntax error in the getLimit() function.
    $return should be return.
    BTW, your code works great!

    • admin

      Thanks, well spotted! I have updated the code in the post so as not to confuse anyone.

  • Anderson Fetter

    Thanks, I was looking for this for a long time. Now my web site uses this code and works very well.

  • Amigo

    Thx for this article James. I’ve used your code to limit the product collection you’ve posted above, the limitation seems to be correct but the toolbar/pager isn’t affected by the limitation. Instead of 10, I get 11 products back and no pager is showing up. Maybe i’m missing something?! Here’s what i have:

    The modul:

    protected function _beforeToHtml()
    {
    // the limit is working correct
    $this->_getProductCollection()->setPage(1, $this->_limit);
    return parent::_beforeToHtml();
    }

    the xml, embedded in the cms layout update:

    7
    2
    10

    product_list_toolbar

    • http://www.jimcode.org James Rowe

      Hi Amigo, unfortunately I really designed this specifically so that I didn’t get the pager – i.e. on a homepage where I needed exactly five products.

      You can probably make use of most of this article but instead of restricting the return records by adding the setPage call you need to work out a way of populating the product collection with a limit.

      If all you want to do is set how many products are appearing on the page though you can do this much more easily in the admin.

      Look at the options in System->Configuration->Catalogue->Frontend where you can specify the options in the show n per page dropdown and all specify the default value.

      Hope that helps!

      • Amigo

        Thanks for your reply! The problem is that I have two category pages with different grid views, one is controlled by the backend options but the other not and the setLimit method doesn’t seems to work. Anyway, I’ll figure it out soon. Thanks for your help :-)

        • http://www.jimcode.org James Rowe

          I think you can set the number of products per page in the layout XML when you add the product grid to the page – so you might want to take a look at that. Good luck!

  • Alex

    I have an issue.
    I have modified the “pager/toolbar” for the grid view for a certain category.

    Instead of having the dropdown menu with how many items it should display.. i have removed that dropdown.. and only show 9 products per page and the pagenumbers with a link “Show All“.

    It works fine… but the problem is.. whenever a user comes back to a category where have been clicked on “show all” before.. it shows all the products.

    How do I change the behaviour.. that it ONLY shows all, when there is a querystring “limit=all” set else just 9 products?

    • http://www.jimcode.org Jim Rowe

      Thats a trciky one Alex, I think you will need to create your own module and create a controller to override the code that deals with that bit… not sure it is a simple thing at all, but good luck and please post your solution here if you find one.

  • Ivandolera

    jim; helo jimz..how to display product in a grid when it is equal to its url id.?..any help?

    • http://www.jimcode.org Jim Rowe

      Not sure that you can do that, if you were working in PHP you could always load the product for the url/slug in order to get the ID but in the layout files I think you have to deal with what you are given. You could always create your own module containing a block for doing this but seems like a lot of work for something quite small. Please post back if you find a good solution, thanks!

  • Sheikh Imworkz

    Is there anyway i can the files for the limit? I’m in a rush to finish a clients project, i tried to follow but something went wrong somehere. your help is greatly appreciated

    • http://www.jimcode.org Jim Rowe

      I think the example in the blog is about as simple as it gets I am afraid, no really simple solution in Magento I am sorry. Try and follow the logic – what I have here is taken from a real live project so definately works, if you try and understand what you are doing it will help you spot typos etc. that are oftne the problem.

  • danne

    The best thing to to do is: 1. add a category in the back end. 2. set the attribute “Is Active * ” to “no”. this will prevent the category from displaying in the menu. 3. add the desired products to that category. 4. Display products of that category by the category ID. for example(cms block)
    {{block type=”catalog/product_list” column_count=”5″ category_id=”3″ template=”catalog/product/list.phtml”}}

    You can now conveniently add or remove products from the.

  • Bohdan Cherchyk

    setCategoryId action does not work. I even defined my own method in block class but it is not calling too. Not sure what to do