Magento: Setting columns and limiting products shown in grid

Apr 15, 2011

MagentoI 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][1].

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>

[1]: /2011/02/creating-magento-module/