Using the MEDIA_URL setting in a template context variable is a very practical way
to have the media files being served from a location defined in the settings file.
James Bennett explains here
how to define and use this context variable.
But, for example, if I need to have media urls in my javascript files, which are static files, I don't have access
to this variable. Take this very simple example. I have a image placeholder in the
markup.
<h1>Test 01</h1>
<img id="placeholder" src="">
And the image url is set with javascript.
function set_image() {
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src","http://localhost:8000/static/django.gif");
}
window.onload = set_image
In this case the full url is hardcoded which, of course is not what I want. Like
for the other media files I want to use the above url during development and
in deployment switch to the media server url. Something like:
http://media.someserver.com/django.gif
I discuss bellow the approaches I have been trying.
Always use the media server urls in the javascript
Just always using the media server url in the javascript files. It's simple and works
fine if I don't need to change the static resources. But changing the static files
during development becomes a problem. And developing offline it's also a problem. So it's not
a good solution.
Global javascript variable with the media url
This means having the following code in the base template.
<script src="{{ media_url }}test.js" type="text/javascript"></script>
<script language="javascript">var MEDIA_URL = "{{ MEDIA_URL }}";</script>
and in the javascript
function set_image() {
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", MEDIA_URL + "django.gif");
}
This approach works, and I consider it more practical than the previous one, but
to have a global variable and extra markup is not very clean.
Media url stored in a meta tag
As a variant of the previous approach, instead of creating a global javascript variable
I set a meta tag with the location of the media_url.
<meta name="media_url" id="media_url" content="{{ MEDIA_URL }}" />
Then in the javascript file extract the value from the DOM.
document.getElementById("media_url").getAttribute("content");
Again it's not a very clean solution.
Take the media url from the CSS url
This last one is based on convention. I always have the CSS files in the root of my media
folder. If the urls for my CSS files are like:
http://media.someserver.com/style.css
then my media url is
http://media.someserver.com/
So in this case the idea is to always fetch the media url from the CSS file url (and so the document
must always have a CSS file). The javascript function for such task:
function get_media_url() {
var css_url = document.styleSheets[0].href;
var last_slash = css_url.lastIndexOf('/');
return css_url.substr(0,last_slash+1);
}
Although being based on convention this last one is the one I am more keen on using.
But to be honest, one of the reasons to write this post was to try to find some best practice for
this topic. And maybe (hopefully) someone from the community can show some better practice.