elfs: (Default)
[personal profile] elfs

One of the nifty things that Django provides is the
{% url backreference %} syntax, which allows
you to name the targets in your list of URL objects and then refer to
them by an explicit name. You can sometimes use the function name
instead, and Django has a way of turning the function name back into
the URL. It works fine as long as the signature of the backreference
and the signature of the function match.

It’s very nice for RESTful interfaces. But what about AJAXy webpages?
AJAX is all about D(X)HTML and the rendering and animation of user
interfaces in a broser, and there’s a lot of Javascript that comes
along with all that HTML and CSS. And embedded AJAX often comes with
its own set of URL calls. I mean, seriously, what if you want to write
something like this:

<example.js>=
$.getJSON(
"{% url results %}", {},
   function(resp) {
   $("#resultswrapper").html(resp.results);
});

Here, I want to replace the string “url results” with the url
that returns the results and shoves their visuals into the
“resultswrapper” HTML object, whatever it is.

You could do this in Django, making this a templatized object
and spewing it out every time. But often enough this URL
never changes during the lifetime of the program. This is
effectively javascript with a macro embedded in it that you want
substituted once, preferably at start-up. Well, I haven’t done the
start-up for you. But here’s a nifty little chunk of code that’ll do
URL reverse lookups in any static files in
your STATIC_DOC_ROOT directory (by the way, that
STATIC_DOC_ROOT setting is pretty useful for development, if you’re
serving static media out of your Django server, as devs frequently
do):

<addition to settings.py>=
import os
DIRNAME = os.path.normpath(os.path.dirname(__file__))
STATIC_DOC_ROOT = os.path.normpath(os.path.join(DIRNAME, 'static')) + '/'

And here’s the routine. Note that I’ve made it a Django command:
put it wherever you want and use it wisely:

<rendertemplates.py>=
from django.core.management.base import NoArgsCommand
from django.core.management.base import CommandError

from settings import STATIC_DOC_ROOT
from django.template import Template
from django.core.urlresolvers import reverse

import os
import os.path
import re

re_walker = re.compile(r'\.tmpl$')

class Command(NoArgsCommand):
    help = ("Run a series of templates through the Template handler to produce "
            "(semi) static files.  This is mostly useful for javascript "
            "handlers with Ajax calls in them that only need the urls "
            "defined when the application is first built or starts running.  It "
            "allows developers to use the {% url somethingorother %} syntax inside "
            "Ajax handlers without burdening the application at runtime.")

    def handle_noargs(self, **options):
        paths = [os.path.join(STATIC_DOC_ROOT, path[0], filename)
                 for path in os.walk(STATIC_DOC_ROOT)
                 for filename in path[2]
                 if re_walker.search(filename)]

        for fn in paths:
            fn_out = re_walker.sub('', fn)
            open(fn_out, 'w+').write(Template(open(fn, 'r').read()).render({}))

It’s not perfect (hey, I wrote it in about 20 minutes, mostly to
fix this problem in a quick and dirty fashion. Given that I didn’t
know how the innards of the Template class worked, and have never used
the new os.walk() function, this was pretty good.

As always, I’ve provided the source code for this.

This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com

Profile

elfs: (Default)
Elf Sternberg

December 2025

S M T W T F S
 12345 6
78910111213
14151617181920
21222324252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 4th, 2026 07:02 pm
Powered by Dreamwidth Studios