You have a wonderful example for this in Magento itself. I am talking about Mage_Catalog
module. In order to show different categories, Magento uses the same phtml file and same block itself !.
This is how Magento makes it possible. The template file that is used to show the product lists (in general) is app/design/frontend/base/default/catalog/product/list.phtml
. The block which "controls" this template in almost all case is Mage_Catalog_Block_Product_List
. How magento shows different product collection using the same block and same phtml file ? To get the answer, you need to have a look on the controller files that is processing different criterias. For an example, I am taking the CategoryController
which will use to show different categories in frontend. Have a look on the viewAction
(Module is Mage_Catalog
).
/**
* Category view action
*/
public function viewAction()
{
if ($category = $this->_initCatagory()) {
$design = Mage::getSingleton('catalog/design');
$settings = $design->getDesignSettings($category);
....
}
First of all it calls $this->_initCatagory()
. So let us have a look on what is that method does.
protected function _initCatagory()
{
Mage::dispatchEvent('catalog_controller_category_init_before', array('controller_action' => $this));
$categoryId = (int) $this->getRequest()->getParam('id', false);
if (!$categoryId) {
return false;
}
...
}
There are lot of things happens here. BUt you need to look on this
$this->getRequest()->getParam('id', false);
Here the controller retrieves the passing id through the url which is corresponding to a category. Using this category id, the controller loads the layout. The category view layout holds Mage_Catalog_Block_Product_List
block and it then uses this category id to load the product collection. Have look on the method _getProductCollection()
that comes inside this block class.
So in general, there are lot of methods to do this. If the collection that you need to show an entirely different and you still need to use the same template, then there is an alternative way. For each product collection, you need to create distinct block classes.
An example is shown below. Suppose your template is using a common function, let's say getMyCollection()
to show the product. So your template somewhat looks like this.
FIle : app/design/frontend/<package>/<theme>/template/<namespace_module>/custom/product/list.phtml
$collection = $this->getMyCollection();
foreach ($collection as $item){
//do something
}
Now in your module, you have three blocks that looks like this.
File : app/code/local/Namespace/Module/Block/Custom/Product/List.php
<?php
class Namespace_Module_Block_Custom_Product_List extends Mage_Core_Block_Template
{
protected $_collection = '';
public function setListCollection($collection)
{
$this->_collection = $collection;
return $this;
}
public function getListCollection($collection)
{
return $this->_collection = $collection;
}
}
File : app/code/local/Namespace/Module/Block/Custom/Product/List/List1.php
<?php
class Namespace_Module_Block_Custom_Product_List_List1 extends Namespace_Module_Block_Custom_Product_List
{
public function setList1Collection()
{
//do some collection logic here
$collection = Mage::getCollection('something/something')
->addAttributeToFilter(...)
.....
->load();
//setting collection
$this->setListCollection($collection);
}
public function getMyCollection()
{
return $this->getListCollection();
}
}
File : app/code/local/Namespace/Module/Block/Custom/Product/List/List2.php
<?php
class Namespace_Module_Block_Custom_Product_List_List2 extends Namespace_Module_Block_Custom_Product_List
{
public function setList2Collection()
{
//do some collection logic here
$collection = Mage::getCollection('something/something')
->addAttributeToFilter(...)
.....
->load();
//setting collection
$this->setListCollection($collection);
}
public function getMyCollection()
{
return $this->getListCollection();
}
}
You can see that List1
and List2
has getMyCollection()
method. BUt they return differnt collection, because we are setting different collection on the parent List
block using corresponding setList{1,2}Collection()
method.
Now you are declaring two blocks in your layout like this.
For Namespace_Modulename_ListController::list1Action()
<block type="namespace_module/custom/product/list/list1" name="list1.list" as="some.alias" template="app/design/frontend/<package>/<theme>/template/<namespace_module>/custom/product/list.phtml" />
For Namespace_Modulename_ListController::list2Action()
<block type="namespace_module/custom/product/list/list2" name="list2.list" as="some.other.alias" template="app/design/frontend/<package>/<theme>/template/<namespace_module>/custom/product/list.phtml" />
This will load two different product collection, but still uses same template.
Hope you get some idea now. So ultimately you need to decide which method is good for you and thus proceed.
Good Luck !
list.phtml
template or more page content? Are you showing more than one collection of products on the page or just one which has been modified?