How to 'force' Magento to load a different layout

Background: I need to be able to load upsell / crosssell products in a lightbox complete with add-to-cart functionality.

My idea for achieving this was to ‘force’ Magento to load products in a different layout. I thought of using an observer on the controller_action_layout_generate_xml_before event (code below).

Unfortunately what I have is not working. Any pointers (or completely different / better ideas) are much appreciated.

<?php 
class My_ForceLayout_Model_Observer
{
    public function changeLayoutEvent($observer)
    {
        $action = $observer->getEvent()->getAction();
        $layout = $observer->getEvent()->getLayout();

        if($action->getRequest()->getControllerName() == 'product'
            && $action->getRequest()->getActionName() == 'view') 
        {

            $update = $layout->getUpdate();
            $update->load('popup'); // for testing only
            $layout->generateXml();
        } 
    }
}

2 thoughts on “How to 'force' Magento to load a different layout”

  1. I managed to get this to work exactly as I first intended. Thanks to @Jonathan Day for making me realize the reason it was not working was trivial.

    Config.xml:

    <config>
        ....
    <frontend>
        <events>
            <controller_action_layout_generate_blocks_before>
                <observers>
                    <forcelayout>
                        <type>singleton</type>
                        <class>forcelayout/observer</class>
                        <method>changeLayoutEvent</method>
                    </forcelayout>
                </observers>
            </controller_action_layout_generate_blocks_before>
        </events>
    </frontend>
        ....
    </config>
    

    Observer.php:

    class Unleaded_ForceLayout_Model_Observer
    {
        public function changeLayoutEvent($observer)
        {
            $action = $observer->getEvent()->getAction();
            $layout = $observer->getEvent()->getLayout();
    
            if($action->getRequest()->getControllerName() == 'product'
              && $action->getRequest()->getActionName() == 'view')
            {
                $template = $action->getRequest()->template;
                if (isset($template) && $template != '')
                {
                    $update = $layout->getUpdate();
                    $update->load($template);
                    $layout->generateXml();
                }
            } 
        }
    }
    

    Local.xml:

    <popup translate="label">
        <label>Catalog Product View Lightbox</label>
        <remove name="right"/>
        <remove name="left"/>
        <reference name="root">
            <action method="setTemplate">
                <template>page/popup.phtml</template>
            </action>
        </reference>
        <reference name="content">
            <remove name="product.info.upsell"/>
        </reference>
    </popup>
    

    Product url in .phtml file:

    echo $this->getProductUrl($_item) . '?template=popup';
    

  2. Why don’t you want to use just regular layout udates?

    <catalog_product_view translate="label">
        <label>Catalog Product View (Any)</label>
        <!-- Mage_Catalog -->
        <remove name="right"/>
        <remove name="left"/>
        <reference name="content">
            <block type="new_catalog/product_view" 
                name="new.product.info" 
                template="new/catalog/product/view_popup.phtml">
                ...
            </block>
        </reference>
    </catalog_product_view> 
    

    If you want to change the design of your product page depends on some conditions, you could use layout handler functionality. It means that you have to check your parameters in controller and add handler for layout updates, then you could use it in layout file as any other handler. For example:

    if ($this->check_parameters()) {
        $update->addHandle('new_magic_handler');
        $this->loadLayoutUpdates();
    }
    

    And in layout:

    <new_magic_handler translate="label">
        <label>New Magic</label>
        ...
    </new_magic_handler> 
    

    Check for details Mage_Catalog_ProductController::_initProductLayout()

Leave a Reply

Your email address will not be published. Required fields are marked *