Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
180 lines (135 sloc) 5.36 KB
"""Adapter for using Jinja2 with Django."""
import functools
import imp
import logging
from django import http
from django.conf import settings
from django.template.context import get_standard_processors
from django.template.loaders.app_directories import Loader as AppLoader
from django.utils.importlib import import_module
from django.utils.translation import trans_real
import jinja2
VERSION = (0, 3)
__version__ = '.'.join(map(str, VERSION))
log = logging.getLogger('jingo')
_helpers_loaded = False
class Environment(jinja2.Environment):
def get_template(self, name, parent=None, globals=None):
"""Make sure our helpers get loaded before any templates."""
return super(Environment, self).get_template(name, parent, globals)
def from_string(self, source, globals=None, template_class=None):
return super(Environment, self).from_string(source, globals,
def get_env():
"""Configure and return a jinja2 Environment."""
# Mimic Django's setup by loading templates from directories in
x = ((jinja2.FileSystemLoader, settings.TEMPLATE_DIRS),
(jinja2.PackageLoader, settings.INSTALLED_APPS))
loaders = [loader(p) for loader, places in x for p in places]
opts = {'trim_blocks': True,
'extensions': ['jinja2.ext.i18n'],
'autoescape': True,
'auto_reload': settings.DEBUG,
'loader': jinja2.ChoiceLoader(loaders),
if hasattr(settings, 'JINJA_CONFIG'):
if hasattr(settings.JINJA_CONFIG, '__call__'):
config = settings.JINJA_CONFIG()
config = settings.JINJA_CONFIG
e = Environment(**opts)
# Install null translations since gettext isn't always loaded up during
# testing.
return e
def render(request, template, context=None, **kwargs):
Shortcut like Django's ``render_to_response``, but better.
Minimal usage, with only a request object and a template name::
return jingo.render(request, 'template.html')
With template context and keywords passed to
return jingo.render(request, 'template.html',
{'some_var': 42}, status=209)
rendered = render_to_string(request, template, context)
return http.HttpResponse(rendered, **kwargs)
def render_to_string(request, template, context=None):
Render a template into a string.
def get_context():
c = {} if context is None else context.copy()
for processor in get_standard_processors():
return c
# If it's not a Template, it must be a path to be loaded.
if not isinstance(template, jinja2.environment.Template):
template = env.get_template(template)
return template.render(**get_context())
def load_helpers():
"""Try to import ```` from each app in INSTALLED_APPS."""
# We want to wait as long as possible to load helpers so there aren't any
# weird circular imports with jingo.
global _helpers_loaded
if _helpers_loaded:
_helpers_loaded = True
from jingo import helpers
for app in settings.INSTALLED_APPS:
app_path = import_module(app).__path__
except AttributeError:
imp.find_module('helpers', app_path)
except ImportError:
import_module('%s.helpers' % app)
class Register(object):
"""Decorators to add filters and functions to the template Environment."""
def __init__(self, env):
self.env = env
def filter(self, f):
"""Adds the decorated function to Jinja's filter library."""
self.env.filters[f.__name__] = f
return f
def function(self, f):
"""Adds the decorated function to Jinja's global namespace."""
self.env.globals[f.__name__] = f
return f
def inclusion_tag(self, template):
"""Adds a function to Jinja, but like Django's @inclusion_tag."""
def decorator(f):
def wrapper(*args, **kw):
context = f(*args, **kw)
t = env.get_template(template).render(context)
return jinja2.Markup(t)
return self.function(wrapper)
return decorator
env = get_env()
register = Register(env)
class Template(object):
def __init__(self, template):
self.template = template
def render(self, context):
# flatten the Django Context into a single dictionary.
context_dict = {}
for d in context.dicts:
return self.template.render(context_dict)
class Loader(AppLoader):
is_usable = True
def load_template(self, template_name, template_dirs=None):
if hasattr(template_name, 'rsplit'):
app = template_name.rsplit('/')[0]
if app in getattr(settings, 'DJANGO_TEMPLATE_APPS', []):
return super(Loader, self).load_template(
template_name, template_dirs)
template = env.get_template(template_name)
return Template(template), template.filename
Jump to Line
Something went wrong with that request. Please try again.