Often times when I am developing in Magento, I do not take the time to dig in and find out exactly how something is working. Instead, I assume that they will work the way expect them to work. I was recently working in a situation where I wanted to change the functionality of a grouped product page to use an entirely different layout. Normally, I would have expected to be able to simply remove certain handles and add others to the layout. For products, this is buried inside several different function calls but I eventually found what I was looking for (the addition of the product specific handles) in Mage_Catalog_Helper_Product_View::initProductLayout. I proceeded to modify the layout to load my code by replacing the default:
$update->addHandle('default'); $controller->addActionLayoutHandles(); $update->addHandle('PRODUCT_TYPE_' . $product->getTypeId()); $update->addHandle('PRODUCT_' . $product->getId()); $controller->loadLayoutUpdates();
Depending on whether the product was a grouped product or not, I changed which handles were used. Since we didn’t want all of the PRODUCT_ handles or even the catalog_product_view handle for grouped products anymore, I modified the layout portion to:
$update->load('default'); $update->load('myhandle_index_index');
This worked just fine until I turned caching on. It turned out that the load method uses caching (specifically the layout cache tag) to store the results of loading default. This cached value is the result after all merging had been finished, so when the second load ran, it was simply added to the end of the layout without merging the two together, which resulted in a fairly jumbled up layout. Once I dug in and found out what the issue was, it turned out to be a simple fix to make sure the cached version would be correct:
$update->load(array('default', 'myhandle_index_index'));
It is likely that this would have worked just as well:
$update->addHandle('default'); $update->addHandle('myhandle_index_index'); $controller->loadLayoutUpdates();
So if you ever find that your layout caching is causing problems, make sure you are using one of the solutions that takes caching into account above and not calling load for each handle.