views:

468

answers:

2

I am using django-compress with far future expires for my css and js files. Works great.

I'd like to do something similar for other static content (images, flash, etc). I can set a far future expires on this content, but I must manually rename the files when they change.

Is there a better way to handle this?

+4  A: 

With django-compress, you're treating CSS and JS as dynamic files - which is fine. However, the other files are static - and Django doesn't really want to serve these. They should be served directly by Apache or other webserver.

With Apache, you'd put something like

<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
</FilesMatch>

in .htaccess or the global Apache configuration.

Update: Responding to your comment - Sorry I didn't understand the nuance of your question. There isn't much you can do to avoid using a different URL to indicate to a client that a file (e.g. an image) has changed. This is recommended by e.g. Apache and YAHOO!

Implementing this is IMO not too hard. It's in two parts:

  1. Use a tag (here's a useful snippet) to generate versioned URLs to media files which will appear in your HTML. The versioned URL could be the base URL with the version inserted, e.g. /media/3/header.png where the actual file remains as /media/header.png on the server.
  2. Use a tool like mod_rewrite to convert incoming URLs to the canonical value, i.e. a request for /media/3/header.png gets converted to /media/header.png. This article describes the feature in more detail.
Vinay Sajip
I know how to set the far future expires on images, but I was wondering if there is a better way to handle when I edit an image. Say I have header.png with far future expires. I then edit it in photoshop. I would have to name it to header1.png and then change any references in the code to header1.png. Not ideal for me.
Andrew C
+2  A: 

The best way would be to refer to your static files with a versioned URL, and give your web server a rewrite rule to ignore the version.

See a complete Django example here, which includes an expire_tag helper (created by Arne Brodowski):

<link rel="stylesheet" type="text/css" 
  href="{{ MEDIA_URL }}{% expire_tag "css/reset.css" %}" />

And the relevant Apache rewrite rules.

orip
Now that is pretty slick. I'll have to remember that one.
T. Stone