Add Paging to a Custom Collection

paging
In this blog post, we will see how to add paging and toolbar to any custom collection.

We will also see in detail how to add Sorting options, Grid List view to your collections. In the end we will take an example of a product collection and see how to display it on any page.

Simple Paging on Collection

First we will see how to add a very simple pager to our collection. Also attached is the source code used for this
Error... Unable to load download template. Search single-download-template.tpl in your plugin folder!
The module created by me is Excellence_Collection, so you need rename the class names as per your module. Below the end result of the code

Magento Custom Collection Paging

Magento Custom Collection Paging


Step1: Controller
First in in our IndexController we will simply load the layout and render it.

<?php
class Excellence_Collection_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
    	
		$this->loadLayout();     
		$this->renderLayout();
    }
}

Step2: Layout
In our module layout file, i.e collection.xml this is the code to put

<?xml version="1.0"?>
<layout version="0.1.0">
    <collection_index_index>
        <reference name="content">
            <block type="collection/collection" name="collection" template="collection/collection.phtml" />
        </reference>
    </collection_index_index>
</layout> 

Step3: Block
Next we will create our block ‘collection/collection’ where the main code for paging goes.

<?php
class Excellence_Collection_Block_Collection extends Mage_Core_Block_Template
{

	public function __construct()
	{
		parent::__construct();
		$collection = Mage::getModel('collection/collection')->getCollection();
		$this->setCollection($collection);
	}

	protected function _prepareLayout()
	{
		parent::_prepareLayout();

		$pager = $this->getLayout()->createBlock('page/html_pager', 'custom.pager');
		$pager->setAvailableLimit(array(5=>5,10=>10,20=>20,'all'=>'all'));
		$pager->setCollection($this->getCollection());
		$this->setChild('pager', $pager);
		$this->getCollection()->load();
		return $this;
	}

	public function getPagerHtml()
	{
		return $this->getChildHtml('pager');
	}
}

As you can see in the above code we have created a block for the pager and set our collection in it.
Step4: phtml file
Next in our collection.phtml file we need to put in this code

<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<?php $collection = $this->getCollection(); ?>
<div class="page-title">
    <h1><?php echo $this->__('My Collection') ?></h1>
</div>
<?php echo $this->getPagerHtml(); ?>
<?php if($collection->getSize()): ?>
<table class="data-table" id="my-custom-table">
    <col width="1" />
    <col width="1" />
    <col />
    <col width="1" />
    <col width="1" />
    <col width="1" />
    <thead>
        <tr>
            <th><?php echo $this->__('ID #') ?></th>
            <th><?php echo $this->__('Title') ?></th>
            <th><span class="nobr"><?php echo $this->__('Created') ?></span></th>
        </tr>
    </thead>
    <tbody>
        <?php $_odd = ''; ?>
        <?php foreach ($collection as $_obj): ?>
        <tr>
            <td><?php echo $_obj->getCollectionId() ?></td>
            <td><span class="nobr"><?php echo $_obj->getTitle(); ?></span></td>
            <td><?php echo $this->formatDate($_obj->getCreatedTime()) ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<script type="text/javascript">decorateTable('my-custom-table');</script>
<?php echo $this->getPagerHtml(); ?>
<?php else: ?>
    <p><?php echo $this->__('The collection is empty.'); ?></p>
<?php endif ?>

This is all that is required, now the paging should show up on your collection.

Showing Toolbar on Custom Collection

Now we will add a toolbar to our custom collection, i.e will add sorting and view modes. Here is the end result of the code

Magento Toolbar on Custom Collection

Magento Toolbar on Custom Collection


Here is attached the code for this
Error... Unable to load download template. Search single-download-template.tpl in your plugin folder!
I will continue on the previous module created itself and only the show the changes to be done. First we will change the entire Collection.php block file. the new code is below

<?php
class Excellence_Collection_Block_Collection extends Mage_Core_Block_Template
{

	public function __construct()
	{
		parent::__construct();
		$collection = Mage::getModel('collection/collection')->getCollection();
		$this->setCollection($collection);
	}

	protected function _prepareLayout()
	{
		parent::_prepareLayout();

		$toolbar = $this->getToolbarBlock();

		// called prepare sortable parameters
		$collection = $this->getCollection();

		// use sortable parameters
		if ($orders = $this->getAvailableOrders()) {
			$toolbar->setAvailableOrders($orders);
		}
		if ($sort = $this->getSortBy()) {
			$toolbar->setDefaultOrder($sort);
		}
		if ($dir = $this->getDefaultDirection()) {
			$toolbar->setDefaultDirection($dir);
		}
		$toolbar->setCollection($collection);

		$this->setChild('toolbar', $toolbar);
		$this->getCollection()->load();
		return $this;
	}
	public function getDefaultDirection(){
		return 'asc';
	}
	public function getAvailableOrders(){
		return array('created_time'=> 'Created Time','update_time'=>'Updated Time','collection_id'=>'ID');
	}
	public function getSortBy(){
		return 'collection_id';
	}
	public function getToolbarBlock()
	{
		$block = $this->getLayout()->createBlock('collection/toolbar', microtime());
		return $block;
	}
	public function getMode()
	{
		return $this->getChild('toolbar')->getCurrentMode();
	}

	public function getToolbarHtml()
	{
		return $this->getChildHtml('toolbar');
	}
}

Next, we will create our own toolbar block class at ‘collection/toobar’.

<?php
class Excellence_Collection_Block_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar{
	public function getPagerHtml()
	{
		$pagerBlock = $this->getLayout()->createBlock('page/html_pager');

		if ($pagerBlock instanceof Varien_Object) {

			/* @var $pagerBlock Mage_Page_Block_Html_Pager */
			$pagerBlock->setAvailableLimit($this->getAvailableLimit());

			$pagerBlock->setUseContainer(false)
			->setShowPerPage(false)
			->setShowAmounts(false)
			->setLimitVarName($this->getLimitVarName())
			->setPageVarName($this->getPageVarName())
			->setLimit($this->getLimit())
			->setCollection($this->getCollection());
			return $pagerBlock->toHtml();
		}
		return '';
	}
}

This class extends the default catalog toolbar, we just override the getPagerHtml() function and put in the default magento pager.
Next in our collection.phtml file we need to change the html code a little bit

<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<?php $collection = $this->getCollection(); ?>
<div class="page-title">
    <h1><?php echo $this->__('My Collection') ?></h1>
</div>
<?php echo $this->getToolbarHtml(); ?>
<?php if($collection->getSize()): ?>
<?php if($this->getMode() == 'list'){ ?>
<table class="data-table" id="my-custom-table">
    <col width="1" />
    <col width="1" />
    <col />
    <col width="1" />
    <col width="1" />
    <col width="1" />
    <thead>
        <tr>
            <th><?php echo $this->__('ID #') ?></th>
            <th><?php echo $this->__('Title') ?></th>
            <th><span class="nobr"><?php echo $this->__('Created') ?></span></th>
        </tr>
    </thead>
    <tbody>
        <?php $_odd = ''; ?>
        <?php foreach ($collection as $_obj): ?>
        <tr>
            <td><?php echo $_obj->getCollectionId() ?></td>
            <td><span class="nobr"><?php echo $_obj->getTitle(); ?></span></td>
            <td><?php echo $this->formatDate($_obj->getCreatedTime()) ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>
<script type="text/javascript">decorateTable('my-custom-table');</script>
<?php }else{ ?>
	<!-- List Mode HTML Here -->
<?php } ?>
<?php echo $this->getToolbarHtml(); ?>
<?php else: ?>
    <p><?php echo $this->__('The collection is empty.'); ?></p>
<?php endif ?>

These are the only 3 changes required to make the toolbar functional. Also all the toolbar properties like modes, limits etc are managed from admin i.e Admin -> System -> Configuration -> Catalog -> Frontend See Screenshot

Product Collection On Module Page

Now we will see show to show a product collection (lets say all the product in magento) on our module page with toolbar. The end result of the code would look like this

Magento Product Collection in Module

Magento Product Collection in Module


This is very easy to do, in your module layout file add this code

<?xml version="1.0"?>
<layout version="0.1.0">
    <collection_index_index>
        <reference name="content">
            <block type="collection/collection" name="product_list" template="catalog/product/list.phtml">
                <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                    <block type="page/html_pager" name="product_list_toolbar_pager"/>
                    <!-- The following code shows how to set your own pager increments -->
                    <!--
                        <action method="setDefaultListPerPage"><limit>4</limit></action>
                        <action method="setDefaultGridPerPage"><limit>9</limit></action>
                        <action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
                        <action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
                        <action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
                        <action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
                        <action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
                    -->
                </block>
                <action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
                <action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
                <action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
                <action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
                <action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
                <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
            </block>
        </reference>
    </collection_index_index>
</layout> 

As you can see, everything is same as the code from catalog.xml except the block which is changed to ‘collection/collection’. The code in the block is

<?php
class Excellence_Collection_Block_Collection extends Mage_Catalog_Block_Product_List
{

	protected function _getProductCollection()
	{
		if (is_null($this->_productCollection)) {
			$collection = Mage::getModel('catalog/product')->getCollection();
			$collection
			->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
			->addMinimalPrice()
			->addFinalPrice()
			->addTaxPercents();

			Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
			Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
			$this->_productCollection = $collection;

		}
		return $this->_productCollection;
	}
}

This is all that is required. Find attached the module here
Error... Unable to load download template. Search single-download-template.tpl in your plugin folder!