Web Design Blog

Magento: How to list all the products in a single category in a sidebar block

03.23.2009 06:57PM by Evan Johnson

The website I’m currently developing wants to have all of the products in “CategoryX” displaying in the left sidebar on all pages. It’s a small category with their 5 core products, and they want to make sure no matter where the visitor is on the site, they are just a click away from viewing these products. The sidebar block only consists of a header with the Category name, and a simple list of the products with links to their product information page. It’s just links in this case – no images or prices or “Add to Cart” buttons – but you could add these easily.

I tried to simply use the “Catalog/Product_List” controller with a modified view based off of “catalog/product/list.phtml”. The problem I ran into is that “Catalog/Product_List” uses the session’s current Category/Layer to populate the list, so I couldn’t show the products in CategoryX in the sidebar when I was viewing CategoryY. I read that you can specify which category it uses, but this only seems to work on pages without a Category/Layer, like the Home/Front page and similar CMS pages.

Fortunately I found a nice snippet of code on exploremagento.com, which gave me a clue about how to do this. I’ve modified this code to better suit my needs, and make it a little more general at the same time. You will need to know how to create a simple Magento module to implement this, and there is a good guide here.

Anyway, here it is the code:

class Mycompany_ProdList_Block_Left extends Mage_Catalog_Block_Product_Abstract  
{ public $_collection; public $_catName; private $_theCat;

public function setCat($category) { $this->_theCat = $category; } public function getCatName() { return $this->_catName; } protected function _getProductCollection() { $storeId = Mage::app()->getStore()->getId(); $product = Mage::getModel(‘catalog/product’); $category = Mage::getModel(‘catalog/category’)->load($this->_theCat); $this->_catName = $category->getName(); $visibility = array( Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH, Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG ); $products = $product->setStoreId($storeId) ->getCollection() ->addAttributeToFilter(‘visibility’, $visibility) ->addCategoryFilter($category) ->addAttributeToSelect(array(‘name’), ‘inner’) //you need to select “name” or you won’t be able to call getName() on the product ->setOrder(‘name’, ‘asc’) ; $this->_collection = $products; return $this->_collection; } public function getCurrentCategory() { return Mage::getModel(‘catalog/category’)->load($this->_theCat); } public function getProductCollection() { return $this->_getProductCollection(); }

And this is how you pass in the category you want to show (in this case, category ID 4), via Layout XML:

<block type="mycompany_prodlist/left" name="leftprodlist" template="prodlist/left.phtml" />
<reference name="leftprodlist">
                <action method="setCat"><category>4</category></action>
</reference>

And finally here is the template file I used to display it (prodlist/left.phtml):


<?php
$this->_getProductCollection();
if(!$this->_collection->count()): ?>
<div class="note-msg">
    <?php echo $this->__('There are no products matching the selection.') ?>
</div>
<?php else: ?>
<div class="box base-mini mini-list">
<div class="head">
<h4><?php echo $this->getCatName(); ?></h4>
</div>
<?php //echo Mage::registry('current_category')->getId(); ?>
<ul>
<?php foreach ($this->_collection as $_product): ?>
            <li><a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->htmlEscape($_product->getName()) ?>"><?php echo $this->htmlEscape($_product->getName()) ?></a></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>

The “_product” model returned is similar to the one used by Catalog/Product_List, so you can work from that example to give your list images, prices, etc. One thing to note though: it looks like you might need to “select” all the variables you’re going use. For instance, the call $_product->getName() didn’t work unless I called addAttributeToSelect(array(‘name’), ‘inner’) when getting the product collection.

Comment

Gravatar Image
On Jul 21, 07:36 AM, (Link)
Paulo Gonçalves said:

Hi, can tou send me the files with structure, it is a good tutorial.

Gravatar Image
On Jul 22, 10:04 PM, (Link)
Evan Johnson said:

Sorry – I haven’t rolled this up into a module I can easily just send you. All of the important code is up there though. If you need help putting it into a module, the tutorial I linked to in the article is what I used to get up and running:

http://www.exploremagento.com/magento/simple-custom-module.php

Gravatar Image
On Aug 4, 12:57 PM, (Link)
Paulo Gonçalves said:

It is not working with the call in Layout XML.

I can only list all…

Gravatar Image
On Aug 10, 05:48 PM, (Link)
Evan Johnson said:

@Paulo

Hmm… there’s not a whole lot for me to go on there, in terms of helping.

The code above still works on the site I implemented it on. That site runs Magento 1.3.1 – maybe this code is broken with newer versions?

Double check the “type”, “template”, and other parts of the code too – you know how it is with programming. One small mistake and the whole thing breaks. :P

Gravatar Image
On Jan 9, 05:42 AM, (Link)
Magento Development said:

It is nice tutorial on Magento, great tips, thank you for sharing with us.

  Subscribe to article comments