Magento extension to avoid browser JavaScript/CSS caching

Do you know how to avoid browser styles and JavaScripts caching during the development process? Especially it will be useful to apply to the mobile devices. Sometimes, we have to recache our website’s look when there was made a significant style change. Our brief article describes an extension that will make those things possible.

In the beginning, we would like to say that the main purpose is not allow the browser to cache the CSS and JS files with tweaking the HTTP requests to the web server. This approach is simple – we will add the random “salt” as a get parameter to the CSS and JS files request.

So, let’s start from scratch. First of all, we need to declare our extension:

<?xml version="1.0"?>
<!--
path to file:
your_magento_location/app/etc/modules/Atwix_Browsercaching.xml
-->
<config>
    <modules>
        <Atwix_Browseruncaching>
            <active>true</active>
            <codePool>local</codePool>
        </Atwix_Browseruncaching>
    </modules>
</config>

Then, we should get a config file. It will contain a helper declaration for the admin settings purposes, block declaration and Mage_Page_Html_Head block rewrite because the JS and CSS files are added to the page right in this block. Check the config.xml file content below:

<?xml version="1.0"?>
<!--
path to file:
your_magento_location/app/code/local/Atwix/Browseruncaching/etc/config.xml	
-->
<config>
    <modules>
        <Atwix_Browseruncaching>
            <version>0.1.0</version>
        </Atwix_Browseruncaching>
    </modules>
    <global>
        <blocks>
            <atwix_browseruncaching>
                <class>Atwix_Browseruncaching_Block</class>
            </atwix_browseruncaching>
            <page>
                <rewrite>
                    <html_head>Atwix_Browseruncaching_Block_Page_Html_Head</html_head>
                </rewrite>
            </page>
        </blocks>
        <helpers>
            <atwix_browseruncaching>
                <class>Atwix_Browseruncaching_Helper</class>
            </atwix_browseruncaching>
        </helpers>
    </global>
</config>

The next step is to create the adminhtml.xml with the following permissions:

<?xml version="1.0"?>
<!--
path to file:
your_magento_location/app/code/local/Atwix/Browseruncaching/etc/adminhtml.xml	
-->
<config>
    <acl>
        <resources>
            <all>
                <title>Allow Everything</title>
            </all>
            <admin>
                <children>
                    <system>
                        <children>
                            <config>
                                <children>
                                    <atwix_browseruncaching>
                                        <title>Atwix Browser Caching Avoid</title>
                                    </atwix_browseruncaching>
                                </children>
                            </config>
                        </children>
                    </system>
                </children>
            </admin>
        </resources>
    </acl>
</config>

Now, let’s create the system.xml which will include the enable\disable option and field for IPs which will be uncached:

<?xml version="1.0"?>
<!--
path to file:
your_magento_location/app/code/local/Atwix/Browseruncaching/etc/system.xml    
-->
<config>
    <tabs>
        <atwix translate="label">
            <label>Atwix Extensions</label>
            <sort_order>100</sort_order>
        </atwix>
    </tabs>
    <sections>
        <atwix_browseruncaching translate="label" module="atwix_browseruncaching">
            <class>separator-top</class>
            <label>Atwix Browser Caching Avoid</label>
            <tab>atwix</tab>
            <sort_order>200</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            <groups>
                <general translate="label">
                    <label>General Options</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>10</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>0</show_in_website>
                    <show_in_store>0</show_in_store>
                    <fields>
                        <enabled translate="label">
                            <label>Enabled</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>100</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <comment>
                                <![CDATA[<span class="notice">enable this to avoid browser caching</span>]]>
                            </comment>
                        </enabled>
                        <ips translate="label">
                            <label>User IPs</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>200</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <comment>
                                <![CDATA[<span class="notice">Comma separated ips. Leave empty to disable browser caching  for all users</span>]]>
                            </comment>
                        </ips>
                    </fields>
                </general>
            </groups>
        </atwix_browseruncaching>
    </sections>
</config>

Furthermore, we will also need the dummy helper to make the admin settings section work:

<?php
/**
 * path to file:
 * your_magento_location/app/code/local/Atwix/Browseruncaching/Helper/Data.php
 */

class Atwix_Browseruncaching_Helper_Data extends Mage_Core_Helper_Abstract
{

}

And finally, we are ready to create a Mage_Page_Block_Html rewrite with a single method override which will add a randomly generated “salt” to the end of the JS and CSS files:

<?php
/**
 * path to file:
 * your_magento_location/app/code/local/Atwix/Browseruncaching/Block/Html/Head.php
 */
class Atwix_Browseruncaching_Block_Page_Html_Head extends Mage_Page_Block_Html_Head
{
    protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems,
                                                      $mergeCallback = null)
    {
        $html = parent::_prepareStaticAndSkinElements($format, $staticItems, $skinItems, $mergeCallback);

        if(Mage::getStoreConfig('atwix_browseruncaching/general/enabled') == 1) {
            $ips = Mage::getStoreConfig('atwix_browseruncaching/general/ips');
            if($ips != '' && in_array(Mage::helper('core/http')->getRemoteAddr(), explode(',', $ips)) == false) {
                return $html;
            }
            $salt = md5(time());
            $html = str_replace('.js', '.js?t='.$salt, $html);
            $html = str_replace('.css', '.css?t='.$salt, $html);
        }

        return $html;
    }
}

Pretty simple, huh? Enabling and disabling the extension from the admin panel will allow you to refresh the cached JS and CSS files for your customers for a limited time. And one more useful option here is the ability to enable the extension only for a certain list of IPs – so, developers, QAs and store owners will see the changes immediately.

You can download the extension from GitHub.

We hope this extension will be useful for your development work. You are welcome to share your thoughts about it in the comments.