Debugging Layout XML Loading in Magento 1

debugginglayoutmagento-1modulexml

TL;DR: is there a way I can debug the loading of the layout? As I believe one module's layout is conflicting with another.

Related to a previous question I made: How to make a module layout to be shown on all themes

I have successfully loaded my module on my local testing environment (aka my development PC), tested switching between 3 different themes and it is ok. Then I updated the module on the test or "pre-production" environment we have, where there are a lot of different modules, some proprietary other made by us. On this environment, the module does not show what is needed on the product frontpage. After some testings, I finally come to the conclusion that the problem should be on the layout load process.

So, is there a way I can debug the loading of the layout, how different modules replace or add their own blocks? My point is that I believe there is at least one module that should be conflicting with mine. And as we have so many modules I'm looking for an approach different to disabling modules one by one and see which is the problematic one.

My config.xml file is:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Dts_Banners>
            <version>0.1.0</version>
        </Dts_Banners>
    </modules>
    <global>
        <blocks>
            <banners>
                <class>Dts_Banners_Block</class>
            </banners>
        </blocks>
  ....
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <attributesethandle>
                        <class>Dts_Banners_Model_Observer</class>
                        <method>addAttributeSetHandle</method>
                    </attributesethandle>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </global>    
  ....
</config>

My Observer file:

<?php
class Dts_Banners_Model_Observer
{
    /**
     * Checks if the search text on the list of active campaigns (dts_banners_admin table) has some of the comma separated text on the product name
     * If text found, add a layout handle PRODUCT_CAMPAIGN_BANNER after PRODUCT_TYPE_<product_type_id> handle
     * This handle is handled on the banners.xml layout file that triggers the use of the Front.php frontend block
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer) {
        $product = Mage::registry('current_product');
        if (!($product instanceof Mage_Catalog_Model_Product)) return;
      ....
      ....
}

This is my layout file:

<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
    <default>
        <reference name="content">
            <block type="banners/front" name="banners.front" as="banners_front" template="banners/product.phtml" before="-"/>
        </reference>
    </default>
</layout>

Previously had a slightly different one where instead of <default></default> I had <Product_Campaign_Banner></Product_Campaign_Banner>. It also worked.

My product.phtml file:

<div class="visual">
    <?php echo $this->showCampaign(); ?>
</div>

The product.phtml file is not loaded and therefore the showCampaign is not executed and there is where all the needed HTML is created.

Best Answer

You can log the compiled layout XML directives which are used to generate blocks. Create an observer on controller_action_layout_generate_blocks_before, and in the observer method log the update XML from the transported layout object:

public function logCompiledLayout($o)
{
    $req  = Mage::app()->getRequest();
    $info = sprintf(
        "\nRequest: %s\nFull Action Name: %s_%s_%s\nHandles:\n\t%s\nUpdate XML:\n%s",
        $req->getRouteName(),
        $req->getRequestedRouteName(),      //full action name 1/3
        $req->getRequestedControllerName(), //full action name 2/3
        $req->getRequestedActionName(),     //full action name 3/3
        implode("\n\t",$o->getLayout()->getUpdate()->getHandles()),
        $o->getLayout()->getUpdate()->asString()
    );

    // Force logging to var/log/layout.log
    Mage::log($info, Zend_Log::INFO, 'layout.log', true);
}

Output will be similar to:

2013-01-23T16:24:26+00:00 INFO (6): 
Request: cms
Full Action Name: cms_index_index
Handles:
    default
    cms_page
    STORE_default
    THEME_frontend_default_default
    cms_index_index
    page_two_columns_right
    customer_logged_out
Update XML:
<block name="formkey" type="core/template" template="core/formkey.phtml"/>
<label>All Pages</label>
<!-- ... ->