3

I have a little module that compiles JavaScript modules. I want to add a feature so that it compiles JavaScript files that are added to the default handle separately. I want to know if this will make performance better, because the modules common to every page can be cached, and only the modules specific to each page loaded on every request.

The best way I can think of to do this, is to use the same interface (my block has a method addModule), but to somehow work out whether it was called in the default handle or not.

Is this even possible? I feel like it ought to be, but I'm having some trouble knowing where to look, and the internet isn't being entirely helpful in this.

4
  • I may be wrong here, but I'm I think this is not possible. The blocks and actions from the layout are parsed after the layout handles are merged into one single xml. I really hope I'm wrong.
    – Marius
    Commented Dec 16, 2013 at 9:06
  • Yeah, I'm trying to find the code that does that merging, to see if I'm wrong or not. Otherwise, the only option is parsing the xml (slow), or making a convoluted interface. Commented Dec 16, 2013 at 9:10
  • Not a direct answer but maybe check the code that does the javascript concatenation. That might actually check on which pages a JS file is required when creating the merged files Commented Dec 16, 2013 at 15:00
  • Unfortunately I think @Marius is correct, I don't see how this would be possible to work out. You can find most of the code from a mixture of Mage_Core_Model_Layout_Update and Mage_Core_Controller_Varien_Action. You could possibly find a point in there to add this information into the blocks. Commented Dec 16, 2013 at 20:33

1 Answer 1

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.