Object-specific Layout Update Handles

Every HTTP request in Magento results with a few layout handles which can be used to customize layout of desired pages. If you ever tried to dump layout handles in Magento, you would see many of them. These handles are calculated differently, based on different variables.
Depending on whether the user is logged in or not, Magento uses customer_logged_in and customer_logged_out handles. Different stores have also different layout updates (e.g. STORE_default, STORE_cars, STORE_fashion…).
Themes have their own layout handles, e.g. THEME_frontend_default_default, THEME_frontend_enterprise_default.
While we were working on a website that uses “Shop by Brand” extension, client asked us if we could change layout for one brand page. In order to provide that functionality we had to extend this extension in a way that every brand page has it’s own layout update handle.
You might noticed that Magento uses this functionality to create unique layout handles for different categories (e.g. CATEGORY_96, CATEGORY_35) and products (e.g. PRODUCT_22735, PRODUCT_225).
Here I’ll show you how you can create object-specific layout handle functionality for your custom modules. Handle will be composed of string concatenated to object’s id (like OUR_COOL_OBJECT_535, OUR_COOL_OBJECT_863).
1. Create Observer
In order to add handle to Magento’s layout update object before it’s too late, we have to observe controller_action_layout_load_before event.
<config>
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<inchoo_controller_action_layout_load_before>
<class>inchoo_layouthandle/observer</class>
<method>controllerActionLayoutLoadBefore</method>
</inchoo_controller_action_layout_load_before>
</observers>
</controller_action_layout_load_before>
</events>
</frontend>
</config>
2. Add Handle
Now we have to calculate layout update handle and add it to the layout update object.
<?php
class Inchoo_LayoutHandle_Model_Observer
{
public function controllerActionLayoutLoadBefore(Varien_Event_Observer $observer)
{
/** @var $layout Mage_Core_Model_Layout */
$layout = $observer->getEvent()->getLayout();
$id = Mage::app()->getRequest()->getParam('id');
/* or */
if($ourCoolObject = Mage::registry('our_cool_object'))
{
$id = $ourCoolObject->getId();
}
$layout->getUpdate()->addHandle('OUR_COOL_OBJECT_'.$id);
}
}
That’s it!
Hope this helps! 🙂
4 comments
will Mage::registry(‘our_cool_object’) return null? can’t see any registration? don’t get it 🙁
@Paul – Great plugin. It’s exactly what I need. 😀
We’ve been using some additional handles for most of our products. We’ve created a module H&O Handles which adds some interesting handles.
If you are viewing a category: /products/dvds.html (category id: 5)
By default it adds the handle CATEGORY_5
With our module we add the following:
CATEGORY_2_child_child
CATEGORY_2_child_dvds
CATEGORY_3_child
CATEGORY_3_dvds
This allows us finer granularity for adding designs to pages.
We also add these handles to products and CMS-pages, but the following prefix:
PRODUCT_CATEGORY_
CMS_PAGE_
Also attribute set handles:
PRODUCT_ATTRIBUTE_SET_default
For more info, view: https://github.com/ho-nl/Ho_Handles
link is broken Paul. Can you please fix this? I really need to know how to implement something like CATEGORY_2_child_child. In my case PRODUCT_TYPE_simple_ATTRIBUTE_SET_ID_4 something like this