Magento 1.9 – Insert JavaScript Block on Product Pages via Observer

blocksevent-observerjavascriptmagento-1.9

I'm trying to add console.log() to specific page types such as product_view or onepage_success. However, I am encountering difficulties doing so. I'm trying to use an event observer to check which page type I am running:

config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
...
    <global>
        <models>
            <my_module>
                <class>My_Module_Model</class>
            </my_module>
        </models>
    </global>
    <frontend>
        <events> 
            <controller_action_postdispatch_catalog_product_view>
                <observers>
                    <my_module_addjs>
                        <type>singleton</type>
                        <class>my_module/observer</class>
                        <method>addJavascriptBlock</method>
                    </my_module_addjs>
                </observers>
            </controller_action_postdispatch_catalog_product_view>
        </events>   
    </frontend>
</config>

Observer.php

<?php
class My_Module_Model_Observer {
    public function addJavascriptBlock($observer) {
        $controller = $observer->getAction();
        $controller_name = Mage::app()->getFrontController()->getRequest()->getControllerName();
        $controller_action = Mage::app()->getFrontController()->getRequest()->getActionName();
        if ($controller_name === 'product' && $controller_action === 'view') {
            $this->appendJS($controller);
        } 
    }

    private function appendJS($controller) {
        $layout = $controller->getLayout();
        $block = $layout->createBlock('core/text');
        $block->setText(
        '<script type="text/javascript">
            function hello() {
                console.log("Foo");
            }
            hello();
        </script>'
        );        
        $layout->getBlock('head')->append($block);  
    }
}

For which I get Fatal error: Call to a member function getLayout() on a non-object in $layout = $controller->getLayout();

If I use the controller_action_layout_generate_blocks_after event, it works. Any ideas why this happens? Is controller_action_postdispatch_* being fired before the layout gets initialised?

Best Answer

Any particular reason you are not using layout update file (e.g. local.xml) to add your javascript? Seems easier that way.

Anyways, controller_action_postdispatch_*** fires after HTML has been generated, so it's not possible to change layout at that point anymore.

You should use controller_action_layout_render_before_*** event. To get layout object in your observer, simply call Mage::app()->getLayout();

Related Topic