Magento Category Collection Grid/List View

In this blog post, we will see how to display a grid/list view of categories.

By default magento only has category pages which display the category products, but there is no page which displays categories and its sub categories. We are going to create a custom module named Excellence_Collection, in which we will display the list of categories. Here is a screenshot of the end result of this module

Category Collection Grid/List View with Paging

Category Collection Grid/List View with Paging

Attached is the source code of this module
[dm]14[/dm]
Now let start with explanation and steps. Please go through the previous blog on paging to understand this better.

Step1: IndexController

In the indexcontroller of your module we will write very simple code, to just load and render the layout.

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

Next in our layout file we will load the relevant block class and phtml file. So there is the code

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

This is the code to put in our block class ‘collection/collection’. The explanation of this code is already given in the previous blog post

<?php
class Excellence_Collection_Block_Collection extends Mage_Core_Block_Template
{

	public function __construct()
	{
		parent::__construct();
		$parent_id = Mage::app()->getStore()->getRootCategoryId();
		if($this->getRequest()->getParam('category_id',false)){
			$parent_id = $this->getRequest()->getParam('category_id');
		}
		$collection = Mage::getModel('catalog/category')->getCollection();
		$collection->addFieldToFilter('parent_id',$parent_id);
		$collection->addIsActiveFilter();
		$collection->addNameToResult();
		$collection->addUrlRewriteToResult();
		//$collection->setLoadProductCount(true);
		$this->setCollection($collection);
	}

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

		$parent_id = Mage::app()->getStore()->getRootCategoryId();
		if($this->getRequest()->getParam('category_id',false)){
			$parent_id = $this->getRequest()->getParam('category_id');
		}
		$category = Mage::getModel('catalog/category')->load($parent_id);

		if ($headBlock = $this->getLayout()->getBlock('head')) {
			if ($title = $category->getMetaTitle()) {
				$headBlock->setTitle($title);
			}
			if ($description = $category->getMetaDescription()) {
				$headBlock->setDescription($description);
			}
			if ($keywords = $category->getMetaKeywords()) {
				$headBlock->setKeywords($keywords);
			}
		}
		$this->setTitle($category->getName());


		$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('name'=> 'Name','position'=>'Position','children_count'=>'Sub Category Count');
	}
	public function getSortBy(){
		return 'name';
	}
	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');
	}
}

also we need to create the block class ‘collection/toolbar’ which is used in the above class

<?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 '';
    }
}
Step4: PHTML Files

The last file remaining is the collections.phtml file. In this we will put the html code to display our category collection

<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<?php $collection = $this->getCollection(); ?>
<div class="page-title">
    <h1><?php echo $this->__($this->getTitle()) ?></h1>
</div>
<?php echo $this->getToolbarHtml(); ?>
<?php if($collection->getSize()): ?>

	<?php if($this->getMode()!='grid'): ?>
	<!-- List Model -->
	<?php $_iterator = 0; ?>
    <ol class="products-list" id="products-list">
    <?php foreach ($collection as $category): 
    	$category = Mage::getModel('catalog/category')->load($category->getId()); ?>
        <li class="item<?php if( ++$_iterator == sizeof($collection) ): ?> last<?php endif; ?>">
            <?php // Product Image ?>
            <a href="<?php echo $category->getUrl() ?>" title="<?php echo $this->stripTags($category->getName()); ?>" class="product-image"><img src="<?php echo $category->getImageUrl() ?>" width="135" height="135" alt="<?php echo $this->stripTags($category->getName()); ?>" /></a>
            <?php // Product description ?>
            <div class="product-shop">
                <div class="f-fix">
                    <?php $_productNameStripped = $this->stripTags($category->getName(), null, true); ?>
                    <h2 class="product-name"><a href="<?php echo $category->getUrl() ?>" title="<?php echo $_productNameStripped; ?>"><?php echo $category->getName(); ?></a></h2>
                    <div class="desc std">
                        <?php echo $category->getDescription(); ?>
                    </div>
                    <?php if($category->getChildrenCount()){ ?>
                    <div>
                    	<a href='<?php echo $this->getUrl('*/*/*',array('category_id'=>$category->getId()))?>'>View Sub Category</a>
                    </div>
                    <?php } ?>
                </div>
            </div>
        </li>
    <?php endforeach; ?>
    </ol>
    <script type="text/javascript">decorateList('products-list', 'none-recursive')</script>
	<?php else: ?>

    <!-- Grid Mode -->

    <?php $_collectionSize = $collection->count() ?>
    <?php 
    	$_columnCount = $this->getColumnCount();
    	if(!$_columnCount){
    		$_columnCount = 3;
    	} 
    ?>
    <?php $i=0; foreach ($collection as $category):
    $category = Mage::getModel('catalog/category')->load($category->getId()); 
    ?>
        <?php if ($i++%$_columnCount==0): ?>
        <ul class="products-grid">
        <?php endif ?>
            <li class="item<?php if(($i-1)%$_columnCount==0): ?> first<?php elseif($i%$_columnCount==0): ?> last<?php endif; ?>">
                <a href="<?php echo $category->getUrl() ?>" title="<?php echo $this->stripTags($category->getName()); ?>" class="product-image"><img src="<?php echo $category->getImageUrl() ?>" width="135" height="135" alt="<?php echo $this->stripTags($category->getName()) ?>" /></a>
                <h2 class="product-name"><a href="<?php echo $category->getUrl() ?>" title="<?php echo $category->getUrl() ?>"><?php echo $category->getName() ?></a></h2>
                <?php if($category->getChildrenCount()){ ?>
                <div>
                    <a href='<?php echo $this->getUrl('*/*/*',array('category_id'=>$category->getId()))?>'>View Sub Category</a>
                </div>
                <?php } ?>
            </li>
        <?php if ($i%$_columnCount==0 || $i==$_collectionSize): ?>
        </ul>
        <?php endif ?>
        <?php endforeach ?>
        <script type="text/javascript">decorateGeneric($$('ul.products-grid'), ['odd','even','first','last'])</script>
    <?php endif; ?>

<?php echo $this->getToolbarHtml(); ?>
<?php else: ?>
    <p><?php echo $this->__('The collection is empty.'); ?></p>
<?php endif ?>

Now open your modules index URL in my case www.mymagento.com/collection and there you will see the category list.

  • Rt

    Hello Manish, once again great post as usual, i’ve been reading tutorials on disabling “sort by” option in the product listing page and today this post has really helped me gain more knowledge. This is really helpful.

    Im facing a strange problem in one of my magento installation, product search results page.I have 5 product categories with several hundreds products inside each category. When i search product in the first 4 product categories, the results are accurate,  Eg: search results gives 55 results. and it displays all 55 products.

    But in one of the category it displays only 2 products, but the search results is 44. the other 42 product wouldn’t show up. Any idea why this is happening. ?

    Thanks.

    • Manish Prakash

      Thanks again 🙂

      Regarding the search results, sorry but i done in depth research in magento search yet. So won’t be able to your question. 

  • Shweta

    Hello, Great Work and superb blog.

    Just one question.

    Will this work for Magento version 1.7 and how can we also display the
    total number of products for each sub category below or above its image
    with the text “total products” or any similar.

    Will it display sub categories in tree like structure in the navigation
    pane until its last sub category level that can be expanded or collapsed
    to see upon clicking.

    Regards

  • tahir

    Hello m not able to download, plz help

  • Holy bananas sir. u saved my life.

  • Hi, I am completely new for Magento, but I am impressed by this article. I have copied the files from your download into their appropriate places, but I am not sure about how to make it work. What’s the next step after copying the files? I hope you can help me out with this. Thank you so much in advance! 🙂

  • samir karmacharya

    Thank you this module is helpful for me.

  • Tahir Mohd

    Fatal error: Call to a member function setAvailableOrders() on a non-object in