Serving dynamic content can be very useful, regardless of programming language or platform. In my personal experience the technique becomes particularly handy when I need to supply certain configurable information to a script.

The following example shows how to achieve that in Magento. Its a common practice between Magento extension developers, especially for those extensions that are heavy on JavaScript.

1. Some Conventions

I assume we all know the basics of how to create a module so I won’t stop on many details on that topic. There some interesting articles here and there about how to do this.

I won’t use the usual “YourCompany/YourModule” approach throughout this article because I (personally) don’t like it so much. The word “Model” seems redundant when naming a module and early in my learning process it only confused me when used inside PHP or XML code, specially in the context of Magento or Zend. So instead, we’ll create a module named “Dynamic” under namespace “Acme“.

Last but not least I’m going to place some files under the ‘default/default’ package/theme. If you’re using another package or theme I assume you know what you’re doing there as well.

2. Configuration File

The configuration file sets up your module for use in Magento. Among a few other things, here’s where we will build our route. Our goal is to retrieve the generated javascript from the following URL: .

app/code/local/Acme/Dynamic/etc/config.xml (click to download a clean version)

<!--?xml version="1.0?-->
    <modules><!-- basic information about the module -->
        <routers> <!-- use this section to build routes (i.e., URLs) -->
            <!-- build our routes here -->
            <dynamic> <!-- router namespace - module name should be used, as a 
                           good practice -->
                <!-- setup a standard router for this route -->
                     <!-- search for classes starting with "Acme_Dynamic_" -->
                    <!-- 'frontName' builds the route: 
                  [frontName]/[action]/[params] -->
                    <!-- the generated route is: 
                  [action]/[params] -->
        <layout> <!-- use this section to specify layout files -->
            <updates> <!-- we're going to include layout updates -->
                <dynamic> <!-- layout update namespace, same as with router -->
                    <!-- we can give any name to the file, but good practice is 
                         to use "[namespace]-[module].xml" -->
                    <!-- the file will be located at:
                         app/design/frontend/default/default/layout/ -->

3. The Controller

We are going to serve JavaScript under the ‘index’ action in this controller.


class Acme_Dynamic_JsController extends Mage_Core_Controller_Front_Action {
     * Index action
     * This function enables the following route:
     *    //
     * Since 'index' is the default action for the controller, 
     * the following route is also equivalent:
     *    //
    public function indexAction() {
        // Set the appropriate content-type
        $this->getResponse()->setHeader('Content-type', 'text/javascript');
        // Loads and renders the layout file we will create soon
     * We could declare other actions here by using the format
     *    public function [name]Action()
     * which will map to the routes in the form:
     *    //[name]

4. The Layout File

Just like we specified on line 31 of config.xml we’re going to use a layout file to configure exactly what we want the index to return (i.e., the JavaScript).


<?xml version="1.0"?>
<!-- Configure the layout for the 'index' action created above -->
<layout version="0.1.0">
    <!-- Note how the following tag goes: [namespace]_[module]_[controller]_[action]
         You can repeat the same pattern for any number of actions. -->
        <reference name="root"> <!-- reference the root block of the layout -->
            <!-- The 'setTemplate' action configures which file will be rendered 
                 with the referenced block, which in this case is the 'root' block -->
            <action method="setTemplate"><template>acme/dynamic/js.phtml</template></action>
            <!-- So the 'index' action will render the template file located at 
                 '.app/design/frontend/default/default/template/acme/dynamic/js.phtml -->

5. The Template File

This is where it all makes sense, hopefully. The file will be rendered with the correct content-type and interpreted by the browser as JavaScript.


 * Use this file to generate your JS magic, just as you would an HTML page. For example:
$_product = Mage::getModel('catalog/product')->load(27); // for the sake of the example
    $('#featured').html('Featured Product: <?php echo $_product->getName() ?>');

6. Activate the Module

A small but important step. Further explanation would fall out of scope so I’ll just provide the link to a file you can use to activate this module.


Conclusion + Resources

That’s it! You can actually generate any kind of file with this method, including images and PDFs.

I made a compressed version of the entire module available here. You can also view the source online as a Github Gist.

If you liked this article please leave comment or share it!

Leave a Reply