Muffinresearch Labs by Stuart Colville

Automatic asset versioning in Django | Comments (5)

Posted in Code, performance on 8th April 2008, 1:45 am by Stuart

Following on from Ed’s “Automatic versioning of CSS, JavaScript and Images” here is a method to version filenames based on modification times to be used in Django as a template tag.

This is really handy technique for when you set expires headers to a long way into the future. With headers set in this way files need to have their filenames versioned to force the client to download the latest version of a file. The purpose being that with far futures expires the browser will agressively cache the asset thus minimising the amount of requests for assets.

This template tag for Django uses the same method as Ed’s to provide a version string that’s appended to the filename. The awesome part of this is once configured you can just happily change the file as you need to and the caching is taken care of.

{% load utils %}
<link rel="stylesheet" type="text/css" href="{% version '/static/css/style.css' %}">

The code for this is placed in a utils.py in “project/app/templatetags”

from django import template
register = template.Library()
import os, re        

STATIC_PATH="/path/to/templates/"
version_cache = {}

rx = re.compile(r"^(.*)\\.(.*?)$")
def version(path_string):
    try:
        if path_string in version_cache:
            mtime = version_cache[path_string]
        else:
            mtime = os.path.getmtime(’%s%s’ % (STATIC_PATH, path_string,))
            version_cache[path_string] = mtime

        return rx.sub(”\\\\1.%d.\\\\2″ % mtime, path_string)
    except:
        return path_string 

register.simple_tag(version) 

As Brad has pointed out in the comments below the original query string method used will not be cached by UAs following the http spec. The output will now look like the following:

/static/css/style.css?v=1207433992
/static/css/style.1207433992.css

In addition a mod_rewrite rule is required to map the versioned file to the original.

RewriteRule ^/static/(.*?)\.[0-9]+\\.(css|js|jpe?g|gif|png) /static/$1\\.$2 [L]

Post Tools

Comments: Add yours

1. On April 8th, 2008 at 7:43 am Brad Wright said:

Hey Stu,

It seems Opera and Safari don’t cache file paths with query strings, as per the HTTP spec, and given that it’s part of the spec we have no guarantee that other browsers won’t behave the same in the future. Probably best to do something like:

return path_string.replace('.css', '.%d.css' % mtime)

And have something like this in mod_rewrite:

RewriteRule ^/static/([a-z-]+)\.[0-9]+\.(css|js) /static/$1\.$s [L]

This keeps the filenames looking like: /static/css/style.1207433992.css, but rewrites them to the latest versions in your static server.

2. On April 8th, 2008 at 8:35 am Brad Wright said:

Oops, my mod_rewrite had fail:

RewriteRule ^/static/([a-z-]+)\.[0-9]+\.(css|js) /static/$1\.$2 [L]

Is better.

3. On April 8th, 2008 at 10:34 am Stuart Colville said:

@Brad: Excellent points well made. I’ve updated the script accordingly.

4. On April 10th, 2008 at 7:32 am Ross Bruniges said:

I have a feeling that this will provide very very useful to a number of people :>

5. On April 28th, 2008 at 5:50 am Rich said:

I was just looking around for some background to write something just like this for Django!

Thanks very much for saving me several hours!

- rich







XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Standalone mac battery charger|(0)

Got a spare mac battery? I’ve often wondered why up until now no-one’s produced a standalone charger so that you can charge batteries without having to plug them into the mac. Fortunately Fastmac.com have produced a standalone charger that allows you to do just that. and it’s compatible with iBooks, Powerbooks, macbooks and Macbook Pros. It’s also 110/200v. Exactly what I was looking for!

Django Admin Ominigraffle Stencil|(0)

Colleague Alex Lee has created a nice stencil for omingraffle with the Django Admin UI components, perfect for wireframing customised admin screens. For more details and to download the stencil see Alex’s Blog csensedesign.co.uk

Photos on Flickr

© Copyright 2004-08 Stuart Colville, all rights reserved. May contain traces of Muffin. Powered by WordPress. Hosting by 1&1 This page was baked in 0.723s.