Accessing Django Template Variables in Javascript

How do we follow the Django DRY principle and avoid as many hard coded elements as possible in our project when we need to include Javascript? A good example of this is if we are pulling in a bookmarklet that will be offered on the site. We need to reference the domain of our project in the bookmarklet, but this then yields code buried in our project’s static files that needs to be altered by anyone that might be utilizing your open sourced code.

This example presents a little bit of a challenge. If this were HTML in our template we could simply reference a DOMAIN variable that we would feed in through a view. However, this is a static Javascript file, so how do we go about utilizing Django template variables in supposedly static Javascript?

Here is a simple method. In our HTML template, we will setup a Javascript global variable that is created to reference a template variable that we feed in from our view, here a domain, and this variable is then referenced in our static Javascript files.

<!-- Our HTML Template (templates/index.html) that is fed data from -->
{% extends "base.html" %}
{% block content %}

<script type="text/javascript" src="/static/somejs.js"></script>

var DOMAIN = "{{ site_domain }}";

<!-- rest of our template, business as usual. -->
{% endblock %}

As you can see, we would feed in a site_domain variable from that might be created something like this.

from django.contrib.sites.models import Site
from django.shortcuts import render_to_response

def index(request):
    '''Our main index view.'''
    site_domain = smart_str(Site.objects.get_current().domain)
    # more of our view code...
    return render_to_response('templates/index.html', {
	'site_domain': site_domain, of our template vars

Now, how do we use this in our static Javascript? We reference that global Javascript variable we declared in our template using our Django template variable site_domain.

// Our Javascript file ... /static/somejs.js 
alert("Your current domain is: "+DOMAIN);

Now our code is much more portable, even in places where things should essentially be static.