Magento – Custom layout handle based on phtml file

layouttemplatexml

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');
    }
}

Best Answer

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.

Related Topic