1

I am trying to create a custom layout handle based on if the page/popup.phtml file is used as the template for the page.

I know how to build the module for the custom handle. The thing I don't know is the logic needed to find out if a page is using popup.phtml and if that is even possible since the layout files set a log of those templates.

Update: Here is the Observer code I am trying to use. It is failing on the line marked below (line 11) with this error:

Call to undefined method KNG_LayoutHandles_Model_Observer::getLayout().

<?php
class KNG_LayoutHandles_Model_Observer {
    /**
     * Adds layout handle modal_window.
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addPopupHandle(Varien_Event_Observer $observer) {
        $template = $this->getLayout()->getBlock('root')->getTemplate(); //Failing here

        /**
         * Return if it is not modal window
         */
        if ($template !== 'page/popup.phtml') {
            return;
        }

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer->getEvent()->getLayout()->getUpdate();
        $update->addHandle('modal_window');
    }
}
  • If you are loading that template through your own defined block, maybe you could just check if that block is loaded in the current layout, something like $this->getLayout()->getBlock('your_block_name') – pspahn Jan 11 '14 at 2:39
  • What are you trying to do, exactly? – benmarks Jan 11 '14 at 13:20
  • @benmarks I included javascript on all pages but now I need to remove it from all our popups. – njm5785 Jan 13 '14 at 17:36
3

Once the layout is loaded (as it is for the controller_action_layout_generate_blocks_after event) all of the actions have been processed. Adding a new handle to the update object at this point (or even manually merging its contents into the already-merged contents) doesn't make sense as you would have to regenerate things. You should take a different approach.

Stop and think what you need to do: unset JS on the head block, an instance of Mage_Page_Block_Html_Head.

If you leave your current observer as it is configured, you can do

public function removePopupJs($observer)
{
    $list = $this->getRemoveList(); // not sure how you want to transport values in

    $root = $observer->getLayout()->getBlock('root');
    $head = $observer->getLayout()->getBlock('head');

    if (
            is_object($root)
            && $root->getTemplate() == 'page/popup.phtml'
            && is_object($head)
       )
    {
        foreach ($list as $type => $path) {
            $head->removeItem($type,$path);
        }
    }
}

As I said, not sure how you want to propagate "remove this, not that" into the observer context. It would suck to maintain dual lists in separate "spaces", i.e. one in layout XML for adding and one in PHP for removing. Perhaps, if all JS needing removal is added in one layout XML file, you could re-load() that file, or you could tag each JS-add directive with a custom attribute to select via XPATH.

You could also get rid of the observer and do the above in a helper method which just needs to be called after all JS has been added to the head block. Add your action to both the <customer_logged_out /> and <customer_logged_in /> handles as they will be executed on all page loads and after most other handles are executed.

There are other options as well. Layout it wicked flexible.

1

The event you have chosen will not have any of the block information as it happens before all the layout is generated. My first suggestion is to use the event controller_action_layout_generate_blocks_after.

This is dispatched as follows.

Mage::dispatchEvent(
    'controller_action_layout_generate_blocks_after',
    array('action'=>$this, 'layout'=>$this->getLayout())
);

So you already have the layout passed into the event. You can then call the getBlock function on this layout object as follows.

$template = $observer->getLayout()->getBlock('root')->getTemplate();
  • I tried your example code but i get this error: Call to a member function getTemplate() on a non-object – njm5785 Jan 13 '14 at 21:45
  • @Nick see my edited answer. But I am fairly sure that you could also do this via layout xml. – David Manners Jan 14 '14 at 8:08
  • well you answer did make it so I could get the template inside the observer. The problem is that now the handle doesn't work because it tries to create it after the handles are already done. I may have to come up with another way to do this. – njm5785 Jan 15 '14 at 17:15
  • @Nick sadly I dont think this will work in your case as you need to load the blocks to get the templates but once that has happened you have already processed all the handles. As far as I am aware :( – David Manners Jan 16 '14 at 15:17
0

try this code this will help i think so.

$this->getLayout()->getBlock('root')->getTemplate();
  • This was what I was looking for but it doesn't work in the Observer class. I posted an update above with the error I am getting when using this. Any way to make it work in that class? – njm5785 Jan 13 '14 at 19:38
  • Your observer does not have a getLayout() method. But you can always use Mage::app()->getLayout() – Fabian Schmengler Feb 19 '14 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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