Created
September 6, 2012 06:05
-
-
Save mjumbewu/3651921 to your computer and use it in GitHub Desktop.
An example of how to do URL resolution with django-jstemplates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# chadmasso has an interesting solution to using Django template tags in your | |
# Handlebars JS templates: precompile the template to Handlebars JS code, and | |
# then run the template through Django's template renderer. | |
# | |
# https://github.com/chadmasso/pencilthin | |
# | |
# Below are two possibilities for how a similar thing would be accomplished in | |
# django-jstemplate. | |
# | |
# 1) PREPROCESSOR(S) | |
# --------------- | |
# | |
# In the first possible way, we could create a preprocessor for those Django | |
# template tags that we care about: | |
import re | |
from django.core.urlresolvers import reverse | |
from django import template | |
class ReverseUrlPreprocessor(object): | |
# Should match strings like: {{ url 'home' }} | |
url_re = re.compile(r'\{\{\s*url\s+(.+?)\s*\}\}') | |
def reverse_url(self, match): | |
"""Resolve the arguments in the current context, and reverse the URL""" | |
unresolved_args = match.group(1).split() | |
resolved_args = [template.Variable(arg).resolve(self.context) | |
for arg in unresolved_args] | |
url_name, url_args = resolved_args[0], resolved_args[1:] | |
return reverse(url_name, args=url_args) | |
def process(self, content, context): | |
self.context = context | |
return re.sub(self.url_re, self.reverse_url, content) | |
# This is nice because (1) it makes the url tag look like a Handlebars expr | |
# (which you could also say is not nice), and (2) it doesn't require an actual | |
# Handlebars renderer, let alone one that renders to JS. | |
# | |
# 2) CUSTOM TAG | |
# ---------- | |
# | |
# This solution is a lot like chadmasso's. However, it still compiles the | |
# Handlebars templates during the Django template compilation process. | |
import subprocess | |
import tempfile | |
from django import template | |
from jstemplates.base import BaseJSTemplateNode, jstemplate_tag_helper | |
register = template.Library() | |
class HandlebarsJSNode(BaseJSTemplateNode): | |
def generate_node_text(self, resolved_name, file_content, context): | |
tfile, tfilename = tempfile.mkstemp() | |
tfile.write(file_content) | |
tfile.close() | |
t = template.Template(subprocess.check_output("handlebars -m %s" % tfilename, shell = True)) | |
output = t.render(context) | |
return output | |
@register.tag | |
def handlebarsjs(parser, token): | |
""" | |
Finds the HandlebarsJS template for the given name, compiles it to | |
JavaScript with the Handlebars node.js compiler, and then renders it with | |
the Django template system. | |
""" | |
return jstemplate_tag_helper('handlebarsjs', HandlebarsJSNode, | |
parser, token) | |
# At the moment, I prefer the latter solution EXCEPT for the fact that it | |
# currently requires node.js to be installed in order to work. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment