tags:

views:

93

answers:

1

Hi, I find that I can add own layout handles with this script:

$this->getLayout()->getUpdate()->addHandle('myhandle');

Then I checked Alan Storm Layout viewers: http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz

?showLayout=handles

Handles For This Request

  1. default
  2. cms_page
  3. STORE_default
  4. THEME_frontend_default_default
  5. cms_index_index
  6. page_two_columns_left
  7. customer_logged_out
  8. myhandle

There was my handle, but my custom layout xml didn't used.

Here is my xml:

<?xml version="1.0"?>
<layout version="0.1.0">

    <myhandle>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </myhandle>
</layout>

This works fine, so the xml file is loaded:

<?xml version="1.0"?>
<layout version="0.1.0">

    <default>
        <reference name="head">
          <action method="addJs"><script>test/your.js</script></action>
        </reference>
    </default>
</layout>

What's wrong? Why doesn't work this solution?

If it's not the right way, how can I add custom css and javascript for the page where the widget used?

Update: Here is something which maybe get close to the solution:

If I add this code after I add the new handle to the page:

$this->getLayout()->getUpdate()->fetchPackageLayoutUpdates('myhandle');
$this->getLayout()->generateXml();

After this the "index.php?showLayout=page" call writes handle code in the xml, but the page don't use it.

+1  A: 

The long and the short of this is you really don't want to inject layout handles this way. It gets pretty complicated (complicated enough that I can't follow it all the way down quickly enough for a Stack Overflow answer), but

  1. If you add your handle before you call $this->loadLayout() from a controller it's too soon.

  2. If you add your handle after you call $this->loadLayout() it's too late.

Here's an experiment, try modifying the loadLayout method in the base Action Controller

File: app/code/core/Mage/Core/Controller/Varien/Action.php
public function loadLayout($handles=null, $generateBlocks=true, $generateXml=true)
{    
    // if handles were specified in arguments load them first
    if (false!==$handles && ''!==$handles) {
        $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
    }

    //YOUR NEW CALL HERE
    $this->getLayout()->getUpdate()->addHandle('myhandle');         

    ...

This should work and apply your layout. Now, doing this in production would be a Bad Idea, I only mention it to show you that handles need to be added at a very specific time layout rendering process. As an end-programmer, it's not really your job to insert layout handles.

The layout system is intended to be a layer that sits between designers and raw PHP system code. Since you're clearly able to write PHP code, I'd look into just directly injecting your javascript into the head block pre-render.

    //from a controller, but could be modified to be used elsewhere
    //also pseudo code
$this->getLayout()->getBlock('header')->append(
    $this->getLayout()
    ->createBlock('core/text', 'some-unique-name')
    ->setText('<script type="text/javascript" src="/foo/baz/bar.js"></script>')
);
Alan Storm
Thank you for your time for this question. This helped me a lot to understand Magento.
Roland Soós