Brand-related pages are very popular among shop-owners – it’s clear from the number of extensions adding such functionalities as well as from their prices. However, do we always need large modules to get a satisfactory result? Recently, I presented how to add a page with a given brand to your shop – if we use it, we’re already half way there.
In this tutorial, I’ll show you how to add a page with a brand list and how to convert the method from the previous article, so that the content of the custom catalog page changes based on the attribute given in a URL.
We start with creating a new module (first line tells you where the file should be located):
//app/etc/modules/Magently_BrandsPage.xml
<?xml version="1.0"?>
<config>
<modules>
<Magently_BrandsPage>
<active>true</active>
<codePool>local</codePool>
</Magently_BrandsPage>
</modules>
</config>
Our new module needs a helper in which we’ll load the required content, a router which will assign a relevant URL to it (in this case /brands), and a layout to put the content of the page together:
//app/code/local/Magently/BrandsPage/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magently_BrandsPage>
<version>1.0.0</version>
</Magently_BrandsPage>
</modules>
<frontend>
<routers>
<brandspage>
<use>standard</use>
<args>
<module>Magently_BrandsPage</module>
<frontName>brands</frontName>
</args>
</brandspage>
</routers>
<layout>
<updates>
<brandspage>
<file>BrandsPage.xml</file>
</brandspage>
</updates>
</layout>
</frontend>
<global>
<helpers>
<brandspage>
<class>Magently_BrandsPage_Helper</class>
</brandspage>
</helpers>
</global>
</config>
So far, index controller won’t be different from the one we used in the Magently_CustomProductList module, so let’s just copy the file to app/code/local/Magently/BrandsPage/controllers/IndexController.php. Doing this, remember to change the class name.
In order to get a list of brands available in our store we’ll use the following helper:
//app/code/local/Magently/BrandsPage/Helper/Data.php
<?php
class Magently_BrandsPage_Helper_Data extends Mage_Core_Helper_Abstract
{
public function getAvailableBrands() {
//manufacturer is an ID of the attribute that is used by default to determine the brand
$attrName = 'manufacturer';
$attribute = Mage::getModel('eav/entity_attribute')
->loadByCode('catalog_product', $attrName);
//here we get a collection of values this attribute takes
$valuesCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')
->setAttributeFilter($attribute->getData('attribute_id'))
->setStoreFilter(0, false);
//now let’s take the information that is interesting for us from the
// collection – the brands that are assigned to at least one product
$valuesArray = array();
foreach ($valuesCollection as $value) {
$_collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect($attrName);
$amount = $_collection->addAttributeToFilter(
array(
array('attribute'=>$attrName, 'eq'=>$value->getOptionId())
)
)->count();
if ($amount > 0) {
$valuesArray[$value->getOptionId()] = $value->getValue();
}
}
return $valuesArray;
}
}
As for the layout, let’s not dwell on intricacies of creating templates in this tutorial and take a shortcut: use a simple core/template block and show a simple list.
//app/design/frontend/base/default/layout/BrandsPage.xml
<?xml version="1.0"?>
<layout version="0.1.0">
<brandspage_index_index>
<reference name="content">
<block type="core/template" name="brands.list" template="magently/brands_list.phtml" />
</reference>
</brandspage_index_index>
</layout>
We don’t have to worry about displaying the new block using the getChildHtml method when adding it to the content block. This is because the content block is of the core/text_list type and it automatically renders all its child blocks.
//app/design/frontend/base/default/template/magently/brands_list.phtml
<?php
$_helper = Mage::helper('brandspage');
$brands = $_helper->getAvailableBrands();
?>
<h1><?php echo $this->__('Our brands:')?></h1>
<ul>
<?php foreach($brands as $brand): ?>
<li><a href="brands/<?php echo strtolower($brand) ?>"><?php echo $brand ?></a></li>
<?php endforeach; ?>
</ul>
So far, the links we’ve generated don’t lead anywhere. Therefore, we’ll have to add a new action to our controller – let’s call it “catalog”.
//app/code/local/Magently/BrandsPage/controllers/IndexController.php
...
public function catalogAction()
{
$this->loadLayout();
$this->renderLayout();
}
We’ll also have to add a catalog block to the layout – analogically to how we did it in the tutorial on the custom catalog pages. We only need to remember about an adequate handle – we want to use this layout for the catalog action of the index controller.
//app/design/frontend/base/default/layout/BrandsPage.xml
...
<brandspage_index_catalog>
<reference name="content">
<block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml">
<action method="setCollection">
<value helper="brandspage/getCustomCollection"/>
</action>
</block>
</reference>
</brandspage_index_catalog>
Now, the only thing left to do is remaking the getCustomCollection method from our previous module so that the content it returns is dependent on the parameter given in the URL. We also have to remember to handle the variables in such way that is won’t matter whether we wrote them in upper- or lower-case letters.
//app/code/local/Magently/BrandsPage/Helper/Data.php
...
public function getCustomCollection()
{
$attr = 'manufacturer';
//here we take the “brand” parameter value from the URL and change it into lower-case letters
$brand = strtolower(Mage::app()->getRequest()->getParam('brand'));
//and here we use our previous helper method in order to determine its ID
$brandId = array_search($brand, array_map('strtolower',$this->getAvailableBrands()));
//finally, thanks to the ID we find the correct product collection
return Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(
$attr)->addAttributeToFilter(
array(
array('attribute'=>$attr, 'eq'=>$brandId)
)
)->addAttributeToSelect(
array('price', 'name')
);
}
Now, when we go to the URL brands/catalog/index/brand/Adidas, a catalog page containing Adidas products will be displayed. However, it’s too long, so let’s change the URL to keep only brands/Adidas. It’s very easy and can be done from our module’s configuration file.
//app/code/local/Magently/BrandsPage/etc/config.xml
...
<global>
<rewrite>
<brands_url>
<from><![CDATA[/brands\/(.*)/]]></from>
<to><![CDATA[brands/index/catalog/brand/$1]]></to>
<complete>1</complete>
</brands_url>
</rewrite>
And that would be it! Now, we only need a dab of creativity with the layouts and templates, and we can enjoy a new feature on our website!