using evoque with django

Using Evoque Templating with
is very simple. All that is needed is for a view
to return a Django HTTPResponse object of an
evoque’d template. The commented code recipe below shows
one way how to set this up and how to use it. You would need
to copy the module into your
django project, and customize as necessary.

Why would you want to use Evoque with Django?

Besides being a full-featured template system, and a
legitimate contender for the
fastest pure-python text templating engine
(see benchmark),
it also offers some important features not offered
by other engines, such as
automatic input quoting and guaranteed XSS protection,
restricted template execution mode to be able to expose
your templates to untrusted editors, processing is always and only
done in unicode, etc.
For more, see features.

The code

import sys
from os.path import join, dirname, abspath
import logging
from evoque.domain import Domain
from django.http import HttpResponse

# to add to global namespace
from django.core.paginator import ObjectPaginator
from my_site import formatting_utils

# default template collection root directory
DEFAULT_DIR = abspath(join(dirname(__file__), 'templates'))

# create template domain instance 
# here restating all defaults, for doc convenience
domain = Domain(DEFAULT_DIR,
    restricted=False, errors=3, log=logging.getLogger("evoque"),
    cache_size=0, auto_reload=60, slurpy_directives=True,
    quoting="xml", input_encoding="utf-8", filters=[] )

# adjust global namespace as needed by application
domain.set_on_globals("ObjectPaginator", ObjectPaginator)
domain.set_on_globals("site_name", "")
domain.set_namespace_on_globals("formatting_utils", formatting_utils)

# set up any other collection, as needed by application 
# here restating all defaults -- when None, domain's value is used
domain.set_collection("custom", "/home/me/custom_collection/",
    cache_size=None, auto_reload=None, slurpy_directives=None, 
    quoting=None, input_encoding=None, filters=None)

# here we would do any other domain setup we might need
# e.g. set a template default for a given collection
# for details see:
# or the source of the evoque.domain module.

def evoque_django_response(request, name, 
        src=None, collection=None, raw=None, data=None, 
        quoting=None, input_encoding=None, filters=None,
    """ Render an evoque template to a django response object 
    # get the template, loading it if necessary. 
    # only name is required but all supported options 
    # are passed on for completeness.
    template = domain.get_template(name, src=src, 
        collection=collection, raw=raw, data=data, 
        quoting=quoting, input_encoding=input_encoding, 
    # evoque the template and create a django HTTPResponse object:
    # - evoque'ations are always in unicode, so we decode to utf-8
    # - any and all kwargs are added to locals namespace
    return HttpResponse(template.evoque(raw=raw, quoting=quoting, 
                request=request, **kwargs).encode('utf-8'))

Just an indication of what you would need to add to your

from evoque_django import evoque_django_response

def some_function_named_in_urlpatterns(request):
    return evoque_django_response(request, 'some_template.html',
            title="some title!")

In addition to the title kwarg we can of course
specify any others, as needed by the view. They will be transferred to the
template’s locals evaluation dictionary.

It is important to remember that an Evoque template collection opens up
access to all files below the specified folder root. Thus you may choose to
organize the templates hierarchically e.g. we could rename and place some_template.html to some_function/template.html
(always relative to the collection’s root folder).
We can then specify to use it in this way:

evoque_django_response(request, 'some_function/template.html')

If for some reason we would wish to use a template that is not
part of the default collection, we would just need to specify
the collection e.g.

evoque_django_response(request, 'some_template.html', collection="custom")