Skip to content

Instantly share code, notes, and snippets.

@jwineinger
Created December 16, 2011 16:46
Show Gist options
  • Save jwineinger/1486815 to your computer and use it in GitHub Desktop.
Save jwineinger/1486815 to your computer and use it in GitHub Desktop.
Django staticfiles JS-minifying storage backend
from django.core.files.storage import FileSystemStorage
from slimit import minify
class StaticFileStorageAndJSMinifier(FileSystemStorage):
"""
A storage backend to be used by the staticfiles app -- STATICFILES_STORAGE
setting. This backend operates just as a normal filesystem storage backend
except when it detects a javascript file.
After a javascript file is saved, we reopen the file, minify the contents
and write back to the same place. This allows the default storage
behaviors for finding an unused path to work as defined in core.
Only works in Django > 1.3 where the collectstatic management command
actually uses the storage backend to save the file. In Django 1.3,
collectstatic uses a filesystem copy for local storages, which bypasses
the storage backend so we cannot hook into it to modify the files.
"""
def _minify_js(self, path):
f = open(path, 'r+b')
js_content = f.read()
js_minified = minify(js_content)
f.rewind()
f.write(js_minified)
f.close()
def _save(self, name, content):
name = super(StaticFileStorageAndJSMinifier, self)._save(name, content)
if name.endswith('js'):
full_path = self.path(name)
self._minify_js(full_path)
return name
@btimby
Copy link

btimby commented Feb 20, 2012

Why write the file, read it, minify it and write it again?

@jwineinger
Copy link
Author

This was quick and dirty coding for a proof of concept; I never actually used it. I believe you could easily run the super() call after the conditional, pass the "content" var into _minify_js() and return the minified content, and avoid the write/read/write mess.

@btimby
Copy link

btimby commented Feb 28, 2012

Makes sense, Google took me here and I used it as a possible solution. Of course, since I have not used the storage API, I was not aware that the content parameter is actually a file-like object, not the file's content as a buffer. So the actual solution is a bit different. I will edit my gist to reflect that.

@roidelapluie
Copy link

@jwineinger What is the license of this gist?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment