Magento Product Collection Limit via XML

2019-07-23 07:27发布

问题:

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!

回答1:

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.