Scratching Django-Compact for Django-Compress

Last week I talked about a project I had started to build called, django- compact, whose goal it was to provide a build process for all the various CSS and Javascript files in a given project.

I was quickly notified in via Will Larson on Twitter that I should checkout django-compress. I did. To say that I was following the same approach would be an understatement. Furthermore, this project was much further along than I was. I spent the better part of this morning getting a subsection of my project wired up to use it and am well satisfied.

There was a small additional feature I wanted to add, so I forked the project and made the additions. I feel like the changes are non-breaking and generally useful and therefore hope to get them pushed upstream.

The feature in question involves being able to have multiple MEDIA_URLs for different outputs. I call them PREFIXes. My approach was to patch the media_url function in compress.utils to accept defaulted argument called prefix. If prefix exists in a non-empty state, then it concatenates itself with the url argument, otherwise it concatenates with the settings.MEDIA_URL setting.

Upstream in render_common I look for a dictionary key called prefix in the extra_context optional dictionary. I then pass this value, that i default to NONE, to the media_url function that I updated.

Finally, in the settings.py, I can now add the parameter when I want to serve the media off of different url paths. This is primarily useful when there ends up being more than a few connections to media elements (images, css, js) on a single page request. Being that most browsers by default will only open up a few connections in parallel per hostname, we can speed things up by adding additional hostnames, especially when these hostnames are part of a CDN (at the cost of additional DNS lookups).

Patch

diff --git a/compress/templatetags/compressed.py b/compress/templatetags/compressed.py
index 0b236e3..f9c55f9 100644
--- a/compress/templatetags/compressed.py
+++ b/compress/templatetags/compressed.py
@@ -14,10 +14,11 @@ def render_common(template_name, obj, filename, version):
         filename = get_output_filename(filename, version)

     context = obj.get('extra_context', {})
+    prefix = context.get('prefix', None)
     if filename.startswith('http://'):
         context['url'] = filename
     else:
-        context['url'] = media_url(filename)
+        context['url'] = media_url(filename, prefix)

     return template.loader.render_to_string(template_name, context)

diff --git a/compress/utils.py b/compress/utils.py
index 6fd21c1..fba6075 100644
--- a/compress/utils.py
+++ b/compress/utils.py
@@ -60,7 +60,9 @@ def media_root(filename):
     """
     return os.path.join(django_settings.MEDIA_ROOT, filename)

-def media_url(url):
+def media_url(url, prefix=None):
+    if prefix:
+        return prefix + urlquote(url)
     return django_settings.MEDIA_URL + urlquote(url)

 def concat(filenames, separator=''):