Search code examples
layoutmagentomoduleblock

Magento :: Layout in Module


Is it possible to create a layout file inside of a module ? How ?

For what:
I want to add a some kind of statistics hit counter for products, and I don't want to override the products class, as that is already done by some module I'm using. Thus I thought it would be best to have a custom module with a block that would be called by a layout statement. Of course I could easily edit my private local.xml or make changes to another layout-xml in the layout folder of my theme, but I want this feature to be available in all themes (independent of any selected theme).

Some constraints:

  • All code in one single module
  • ... so that it is theme independent
  • ... so that the module can be shared with others without them having to change anything (like theme files), so that the install/load of my module would be enough

I would also accept different approaches for my statistics hit counter loading (using the same constraints)


Solution

  • Yes it is possible. Just create your layout xml file in the following path: /design/frontend/default/default/layout/yourlayout.xml(or whatever your theme name is), and add a proper statement in your modules etc/config.xml:

    <config> 
     <frontend>   
      <layout>
        <updates>
          <yourmoduleshortname>
             <file>yourlayout.xml</file>
          <yourmoduleshortname>
        </updates>
      </layout>  
     </frontend>
    </config>
    

    This sample is for frontend user, but adminhtml layouts can be updated in a similar manner. If something doesn't work, be sure to check if your layout is in the proper theme/package directory.

    Edit:

    Second approach:

    You can use a controller of your own, which will extend the core functionality (one of the catalog controllers) - just rewrite it (or just product view action). Inside its action method add something like this:

    $thiss->getLayout()->createBlock('namespacename/block','layout-block-name',
    array('template' => 'relativepathtotemplate.phtml'));
    $this->getLayout()->getBlock('content')->append($block);
    run-original-parent-code();
    

    Third approach:

    Similar to the previous one, but you can use some event observer, and try Mage::getSingleton('core/layout'), and inject your block there. Not in all events the layout will be already available (try the post_dispatch family).

    I don't really recommend the second and third approach, because if someone else wants to find where this 'magic' block comes from, it will most surely look int app/design/(...) directory. Finding it in your controller or model, may be very tricky...

    If you don't want to display your statistic counter, you can also use events (like post_dispatch) to count the controller dispatches. Just create an observer attached to it, and store your data in the DB.