Login

Django 1.2+ template loader for Jinja2

Author:
SimonSapin
Posted:
June 12, 2010
Language:
Python
Version:
1.2
Tags:
template jinja jinja2 django1.2
Score:
2 (after 2 ratings)

This is a minimal template loader for Django 1.2 or higher that loads Jinja2 templates. It is better integrated with Django than using Jinja2 directly:

  • Your view code is the same
  • Unmodified generic views use it
  • RequestContext and context processors still work

To use it, add the following to you settings.py file:

TEMPLATE_LOADERS = (
    'jinja2_for_django.Loader',
)

It searches for templates in the same places as django.template.loaders.app_directories.Loader − that is in the templates directory of each installed app.

Django custom and default template tags and filters are not available. Some are the same in Jinja2, but you need to replace the others yourself. You can add global filters and variables (such as functions) in the Loader.env.filters and Loader.env.globals dicts. You can not add tags. See the Jinja2 documentation for more details.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
"""
See http://docs.djangoproject.com/en/dev/ref/templates/api/#using-an-alternative-template-language

Use:
 * {{ url_for('view_name') }} instead of {% url view_name %},
 * <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
   instead of {% csrf_token %}.

"""

from django.template.loader import BaseLoader
from django.template.loaders.app_directories import app_template_dirs
from django.template import TemplateDoesNotExist
from django.core import urlresolvers
from django.conf import settings
import jinja2

class Template(jinja2.Template):
    def render(self, context):
        # flatten the Django Context into a single dictionary.
        context_dict = {}
        for d in context.dicts:
            context_dict.update(d)
        return super(Template, self).render(context_dict)

class Loader(BaseLoader):
    is_usable = True
    
    env = jinja2.Environment(loader=jinja2.FileSystemLoader(app_template_dirs))
    env.template_class = Template

    # These are available to all templates.
    env.globals['url_for'] = urlresolvers.reverse
    env.globals['MEDIA_URL'] = settings.MEDIA_URL
    #env.globals['STATIC_URL'] = settings.STATIC_URL
    

    def load_template(self, template_name, template_dirs=None):
        try:
            template = self.env.get_template(template_name)
        except jinja2.TemplateNotFound:
            raise TemplateDoesNotExist(template_name)
        return template, template.filename

More like this

  1. Jinja2 integration + application specific functions/filters/tests by hasenj 6 years, 10 months ago
  2. monkey-patch django to use jinja2 templates for 404/500 pages and 3rd-party apps by brondsem 6 years, 4 months ago
  3. "Partial Templates" - an alternative to "include" by vigrid 6 years, 6 months ago
  4. jinja2 csrf_token extension by jasongreen 5 years, 7 months ago
  5. Name Capitalize Filter by hotani 8 years, 3 months ago

Comments

spuriousdata (on August 19, 2010):

Your setup may be different than mine, but I think you want to add settings.TEMPLATE_DIRS to app_template_dirs on line 29. Otherwise it seems that it will only load templates from the django module directories but not from your app.

This is excellent, by the way. It was a huge help.

#

Please login first before commenting.