Skip to content

Instantly share code, notes, and snippets.

@mtigas
Created March 27, 2012 20:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtigas/2220161 to your computer and use it in GitHub Desktop.
Save mtigas/2220161 to your computer and use it in GitHub Desktop.
Serving retina <img> tags in Django at the Spokesman-Review
<!--
Where {% jsmin %}{% endjsmin %} is a django template tag that
uses a Python port of Crockford's JSMin:
* http://www.crockford.com/javascript/jsmin.html
* https://gist.github.com/1b085c39b85347255557
Where {% mogrify %} is a custom template tag that generates a
URL with a resize command in the filename (semi-compatible with
ImageMagick mogrify) that is caught by a 404-handling script
running on the media server. A special hashed key is generated
and included (so that a third party cannot perform arbitrary
resizings to eat server resources). i.e.:
http://media.example.com/photos/example_r50x50.jpg?d3b07384d113edec49eaa6238ad5ff00bcd80ae3
would return a version of /photos/example.jpg that is resized
to 50x50 (using the "resize" mode of mogrify)
-->
{% spaceless %}<script type="text/javascript">{% jsmin %}
if ((window.devicePixelRatio !== undefined) && (window.devicePixelRatio >= 2))
document.write('<img class="thumb-small" src="{% mogrify photo.photo.url resize "100x100" %}" style="width:50px;height:50px" />');
else
document.write('<img class="thumb-small" src="{% mogrify photo.photo.url resize "50x50" %}" />');
{% endjsmin %}</script>
<noscript>
<img class="thumb-small" src="{% mogrify photo.photo.url resize "50x50" %}" />
</noscript>{% endspaceless%}
<!--
This also works when you want to thumbnail based on width, but
don't know aspect ratio (mostly for story thumbnails and other
photo-ish bits that don't fit into a specific-sized thumbnail
button spot):
-->
{% spaceless %}<script type="text/javascript">{% jsmin %}
if ((window.devicePixelRatio !== undefined) && (window.devicePixelRatio >= 2))
document.write('<img class="thumb-small" src="{% mogrify photo.photo.url thumbnail "100" %}" style="width:50px" />');
else
document.write('<img class="thumb-small" src="{% mogrify photo.photo.url thumbnail "50" %}" />');
{% endjsmin %}</script>
<noscript>
<img class="thumb-small" src="{% mogrify photo.photo.url thumbnail "50" %}" />
</noscript>{% endspaceless%}
@mtigas
Copy link
Author

mtigas commented Mar 27, 2012

Pros:

  • Backwards compatible with everything under the sun (IE6!)
  • Does not result in double-loading of images (as is the case with dynamically replacing the src attribute of applicable <img> tags)
  • No external dependencies (jQuery, jQuery plugins, etc)
  • Existing CSS/JS rules still work (compare with converting to a <div>- or <span>-based system using media queries + background-image — requires rewriting rules that rely in the <img> tag)

Cons:

  • Simple image tag is expanded into nearly 6x more HTML/JS.
  • Duplication of image tag (it's in there three times)
  • Maintainability (see previous point)
  • Other things I probably haven't thought of

@mtigas
Copy link
Author

mtigas commented Mar 27, 2012

Also currently using the above in a {% if request.is_ipad %} block (custom middleware provides that test against user agent), where non-iPad clients get just the regular <img> tag served to them, sans <script> tags.

(We’re not rolling with retina-enabled resources everywhere, as you could guess.)

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