Armin Ronacher | fb2e38a | 2008-05-09 15:33:18 +0200 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- |
| 2 | """ |
| 3 | djangojinja2 |
| 4 | ~~~~~~~~~~~~ |
| 5 | |
| 6 | Adds support for Jinja2 to Django. |
| 7 | |
| 8 | Configuration variables: |
| 9 | |
| 10 | ======================= ============================================= |
| 11 | Key Description |
| 12 | ======================= ============================================= |
| 13 | `JINJA2_TEMPLATE_DIRS` List of template folders |
| 14 | `JINJA2_EXTENSIONS` List of Jinja2 extensions to use |
| 15 | `JINJA2_CACHE_SIZE` The size of the Jinja2 template cache. |
| 16 | ======================= ============================================= |
| 17 | |
| 18 | :copyright: Copyright 2008 by Armin Ronacher. |
| 19 | :license: BSD. |
| 20 | """ |
| 21 | from itertools import chain |
| 22 | from django.conf import settings |
| 23 | from django.core.exceptions import ImproperlyConfigured |
| 24 | from django.template.context import get_standard_processors |
| 25 | from django.template import TemplateDoesNotExist |
| 26 | from jinja2 import Environment, FileSystemLoader, TemplateNotFound |
| 27 | from jinja2.defaults import DEFAULT_NAMESPACE |
| 28 | |
| 29 | |
| 30 | # the environment is unconfigured until the first template is loaded. |
| 31 | _jinja_env = None |
| 32 | |
| 33 | |
| 34 | def get_env(): |
| 35 | """Get the Jinja2 env and initialize it if necessary.""" |
| 36 | global _jinja_env |
| 37 | if _jinja_env is None: |
| 38 | _jinja_env = create_env() |
| 39 | return _jinja_env |
| 40 | |
| 41 | |
| 42 | def create_env(): |
| 43 | """Create a new Jinja2 environment.""" |
| 44 | searchpath = list(settings.JINJA2_TEMPLATE_DIRS) |
| 45 | return Environment(loader=FileSystemLoader(searchpath), |
| 46 | auto_reload=not settings.TEMPLATE_DEBUG, |
| 47 | cache_size=getattr(settings, 'JINJA2_CACHE_SIZE', 50), |
| 48 | extensions=getattr(settings, 'JINJA2_EXTENSIONS', ())) |
| 49 | |
| 50 | |
| 51 | def get_template(template_name, globals=None): |
| 52 | """Load a template.""" |
| 53 | try: |
| 54 | return get_env().get_template(template_name, globals=globals) |
| 55 | except TemplateNotFound, e: |
| 56 | raise TemplateDoesNotExist(str(e)) |
| 57 | |
| 58 | |
| 59 | def select_template(templates, globals=None): |
| 60 | """Try to load one of the given templates.""" |
| 61 | env = get_env() |
| 62 | for template in templates: |
| 63 | try: |
| 64 | return env.get_template(template, globals=globals) |
| 65 | except TemplateNotFound: |
| 66 | continue |
| 67 | raise TemplateDoesNotExist(', '.join(templates)) |
| 68 | |
| 69 | |
| 70 | def render_to_string(template_name, context=None, request=None, |
| 71 | processors=None): |
| 72 | """Render a template into a string.""" |
| 73 | context = dict(context or {}) |
| 74 | if request is not None: |
| 75 | context['request'] = request |
| 76 | for processor in chain(get_standard_processors(), processors or ()): |
| 77 | context.update(processor(request)) |
| 78 | return get_template(template_name).render(context) |
| 79 | |
| 80 | |
| 81 | def render_to_response(template_name, context=None, request=None, |
| 82 | processors=None, mimetype=None): |
| 83 | """Render a template into a response object.""" |
| 84 | return HttpResponse(render_to_string(template_name, context, request, |
| 85 | processors), mimetype=None) |