Template loading and rendering outside of Django

Go To StackoverFlow.com

3

Using this guide as my reference, I wrote a set tag parser for a Django template that would apply to TWIG's set syntax, that is:

{% set someVar %} variableAssignment {% endset %}

I am only using Django for it's template system, and up until this point I have been able to get by with the correct imports to display my template correctly. Here is the code I have currently:

from django.template import Context, Template, Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist, resolve_variable
from django.template.loader import *
from django.conf import settings
settings.configure(TEMPLATE_DIRS="/my/templates")
register = Library()
class SetValueNode(Node):
    def __init__(self, variable, nodelist):
        self.variable = variable
        self.nodelist = nodelist
    def render(self, context):
        context[self.variable] = self.nodelist.render(context)
        return ""

@register.tag(name="set")
def set_tag(parser, token):
    print "set_tag called: parser",parser," token",token
    nodelist = parser.parse(("endset",))
    parser.delete_first_token()
    return SetValueNode(arg, nodelist)

def sendServiceEmail(username, first, last, service, service_tuple):
    TEMPLATES_DIR = "/my/templates/"
    emailStr = "myemail.html.twig"
    print "Opening file :"+TEMPLATES_DIR+emailStr
    t = Template(fp.read())
    fp.close()
    c = Context({
            /*Add context from parameters*/
        })
    msg = t.render(c)
    print msg

But the error I get is:

django.template.base.TemplateSyntaxError: 'set_tag' is not a valid tag library: Template library set_tag not found, tried django.templatetags.set_tag

After doing some research and thinking about it a while, it appears that the library that django is looking in is the 'standard' library. I think that I need to tell someone (django settings, Template, or .render) that I want them to use 'Library' and to check library to see if the templatetag has been registered. Is there any way to pass this information in to Django WITHOUT creating a django app?

2012-04-04 20:06
by steve-gregory
Where does this code live? How are you loading it - Daniel Roseman 2012-04-04 20:57
This code lives in a standalone script that will be run by a daemon. The idea is to use the template structure in Django to format an email before sending to the user. It is loaded via a call : sendServiceEmail("testUser","Ima","TestUser","Some Service", ("other stuff",) - steve-gregory 2012-04-04 21:14


2

Following information apply to Django 1.4 You have three options.

An application solution

You need to create an application with defined structure, but it does not have to be a complete django app. Let say you call it myapp

Here is the file structure which is mandatory

myapp/
  __init__.py
  templatetags/
    __init__.py
    your_library.py

In your main script do following

from django.conf import settings
from django.template.loader import get_template

# You need to configure Django a bit
settings.configure(
    # Access to template tags
    INSTALLED_APPS=('myapp', ),
    # Access to templates
    TEMPLATE_DIRS=(TEMPLATES_DIR, ),
)

template = get_template("myemail.html.twig")
# Prepare context ....
return t.render(context)

A module solution

If you are not willing to use such a large structure, it should be possible to create only a module with template tags and pass it to django.template.base.add_to_builtins method, see https://github.com/django/django/blob/master/django/template/base.py#L1349.

Something completely different

Or you might consider using jinja2 http://jinja.pocoo.org/docs/ instead, but I do not know tags work in there.

2013-11-15 13:05
by ziima


1

Thanks for the great tip @zimma. I wanted to provide a complete example of the module loading option.

Let's say you have this important template tag to add from read.py

from django import template

register = template.Library()

@register.filter(name='bracewrap')
def bracewrap(value):
    return "{" + value + "}"

This is the html template file "temp.html":

{{var|bracewrap}}

Finally, here is a Python script that will tie to all together

import django
from django.conf import settings
from django.template import Template, Context
import os

#load your tags
from django.template.loader import get_template
django.template.base.add_to_builtins("read")

# You need to configure Django a bit
settings.configure(
    TEMPLATE_DIRS=(os.path.dirname(os.path.realpath(__file__)), ),
)

#or it could be in python
#t = Template('My name is {{ my_name }}.')
c = Context({'var': 'stackoverflow.com rox'})

template = get_template("temp.html")
# Prepare context ....
print template.render(c)

The output would be

{stackoverflow.com rox}
2013-12-09 20:35
by Gourneau
Ads