Saturday, 1 February 2014

Custom Django Template Tags in Google App Engine

First published on adamalton.co.uk 24th May 2010.

Google App Engine uses the Django templating system, but its own AppEngine-ified version of it. This means that if you want to write your own custom template tags you have to do a bit of jiggery pokery in order to bring the required bits of Django and App Engine into harmony with one another. I Googled for how to do this, and found very little, so now that I've done it, here's how... There are 2 different varieties of the Django templating framework floating around in App Engine, and in order to write a custom template tag you need to use bits of both of them. First up, the AppEngine-ified version, this is the one that we'll need to register the template tag with: from google.appengine.ext.webapp import template And secondly, the Django one, which is what we'll use to build our template tag: from django import template as django_template Make sure you import them as different names, otherwise you'll be screwed. Next up, write your custom template tag, making sure to use things from django_template (or whatever you imported it as) where necessary:
def my_tag(parser, token):
    bits = list(token.split_contents())
    if len(bits) != 2:
        raise django_template.TemplateSyntaxError, "Error!!"
    return MyNode(bits[1])


class MyNode(django_template.Node):
    def __init__(self, my_var):
        self.my_var = my_var

    def render(self, context):
        try:
            my_var = django_template.resolve_variable(self.my_var, context)
        except django_template.VariableDoesNotExist:
            my_var = None
        return "my var is: %s" % my_var
Everything as normal there, but using resolve_variable, Node, TemplateSyntaxError and VariableDoesNotExist from the django template module rather than the App Engine template module. Alternatively you could do:
from django.template import (
    resolve_variable,
    Node,
    TemplateSyntaxError,
    VariableDoesNotExist
And next: You need to register your template tag with the App Engine template framework:
register = template.create_template_register()
my_tag = register.tag(my_tag)
Remember, we imported template from google.appengine.ext.webapp. And finally... We need to register the module which has got our custom template tag in it: In main.py (or whatever file is handling your request):
from google.appengine.ext.webapp import template
template.register_template_library('file_which_contains_your_custom_tag')
Smashing.


1 comment: