I went through this with one of my colleagues, and he was very helpful in pointing me in the right direction, and I finally got somewhere. Magento does store a parsed version of its layout tree, replete with handles. Unfortunately, this is in a protected variable.
I'm doing this as a one time operation, which I will be caching, and it doesn't take too long, so I decided I could afford to parse the layouts again.
There is a handy public function to do this. It's Mage_Core_Model_Layout_Update::getFileLayoutUpdatesXml($area, $package, $theme, $storeId)
.
I called it the same way they call it in fetchFileLayoutUpdates
(which saves its xml in the aforementioned protected variable):
$update = Mage::app()->getLayout()->getUpdate();
$design = Mage::getSingleton('core/design_package');
$layout = $update->getFileLayoutUpdatesXml(
$design->getArea(),
$design->getPackageName(),
$design->getTheme('layout'),
Mage::app()->getStore()->getId()
);
This is the full xml layout tree, which is useful for a lot of things. My module defines a block called amdjs_modules
, and I wanted to know the layout handle where a method was called inside this block. Well, this requires two different XPath queries, unless somebody who learned XPath earlier than yesterday can tell me a better way.
$modules = $layout->xpath("//block[@name=\"amdjs_modules\"]/action/*|//reference[@name=\"amdjs_modules\"]/action/*");
This gives an array of each argument given to every action in my block, referred to by the block name, or the reference.
Once you have these, mapping them to their handle is easy:
$handleMap = array();
foreach ($els as $el) {
$handleMap[$el->__toString()] = $el->xpath("ancestor::*[parent::layouts]")[0]->getName();
}
This works on the assumption that each handle is directly below the root node.
Mage_Core_Model_Layout_Update
andMage_Core_Controller_Varien_Action
. You could possibly find a point in there to add this information into the blocks.