I've got a bestsellers module which I've written and it works great, however I want to be able to change the collection size it returns via the XML, rather than the php/phtml.
Something like this:
<block type="catalog/product_list" name="bestsellers" limit="3"
template="custom/bestsellers.phtml" />
or something like:
<block type="catalog/product_list" name="bestsellers"
template="custom/bestsellers.phtml">
<action method="setLimit">3</action>
</block>
Is this possible?
I'm currently changing the limit via the phtml with:
->setPageSize(3)
->setCurPage(1);
But that is hard coded and nasty, I need to be able to use my phtml file as template for many cases of the bestsellers module being called from anywhere with the XML + limit in the XML.
Thanks in advance if anyone can shed light on this!
The block Mage_Catalog_Block_Product_List
inherits from the Varien_Object
class which contains the methods getData()
and setData()
, as well as the magic methods get*()
and set*()
. These methods allow us to store (you guessed it) keyed-data within an object.
The <action />
tags in the XML allows us to perform method calls on the block instances. You're nearly there with your second example, but the syntax is:
<block type="catalog/product_list" name="bestsellers">
<action method="setLimit"><value>3</value></action>
</block>
Which is equivalent to:
<block type="catalog/product_list" name="bestsellers">
<action method="setData"><key>limit</key><value>3</value></action>
</block>
Which is roughly equivalent to:
$block = new Mage_Catalog_Block_Product_List();
$block->setLimit(3);
With the data set in the object we can now access through the getData()
or get*()
methods by calling $this->getLimit()
or $this->getData('limit')
making our block code:
->setPageSize($this->getLimit())
->setCurPage(1);
You should probably perform a check for the existence of the limit
data first and provide a default value if none is provided in the XML.
Note: The name of the children in the <action />
tag don't matter. It's the order of the arguments that's important. We could just as well have called <action method="setLimit"><foo>3</foo></action>
and it still would have worked.