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=''):
Commentary
Sorry that I was a bit of a prick in my tweet. By the same logic someone should have taken me outside and curbed me for trying to make my own blogging platform. Someone probably still will.
Thanks for the link. I really think something like this should be in contrib... it's extremely useful and is something that almost all sites could benefit from.
Will: No worries, man. I didn't think you were being rude at all, but rather being helpful in pointing me to a project that has saved me tons of hours of work.
Dan: I completely agree. How many of us don't do these "best practices" because we are just lazy and don't have a tool to do it for us?!