=======================
Recipies For Developers
=======================

Here some recipies for application developers.

Automagic Template Variables
============================

Python allows some magic stack manipulation which can be used to
pass variables to templates automatically. It's not a recommended
way to pass variables to templates but it can be useful for some
small generation scripts etc.

Just subclass the environment and add an `autorender` function like
this:

.. sourcecode:: python

    import sys
    from jinja import Environment

    class AutoEnvironment(Environment):

        def autorender(self, template):
            tmpl = self.get_template(template)
            return tmpl.render(sys._getframe(1).f_locals)

You can use it now like this:

.. sourcecode:: python

    def foo():
        seq = range(10)
        foo = "blub"
        return env.autorender('foo.html')

In the template you can now access the local variables `seq` and `foo`.

Using Django Filters with Jinja
===============================

If you use Jinja in django and want to use some of the filters that
are part of the django core you can use this snippet:

.. sourcecode:: python

    def convert_django_filter(f):
        def filter_factory(*args):
            def wrapped(env, ctx, value):
                return f(value, *args)
            return wrapped
        return filter_factory

You can now convert django filters for jinja using `convert_filter`. *Note*:
Django only supports one filter argument. Because of this limitation you
shouldn't pass it more arguments than it accepts. Because django uses some
introspection to find out if a filter accepts an argument weird things can
happen if you call it with an incompatible argument count.

You can now register django filters for a jinja environment:

.. sourcecode:: python

    from django.template.defaultfilters import date
    env.filters['date'] = convert_django_filter(date)

And use it:

.. sourcecode:: jinja

    {{ entry.pub_date|date }}

Also keep in mind that Jinja knows about keywords, thus you cannot have a filter
that is called `pluralize` for example.


Using Jinja in Django
=====================

This snippet was contributed by Bryan McLemore. It provides a `render_to_response`
function similar to the one shipped with django just that it uses Jinja for
rendering. It applies the context processors on the context and consumes a
`RequestContext`:

.. sourcecode:: python

    from django.template.context import get_standard_processors
    from django.http import HttpResponse
    from jinja import Environment, FileSystemLoader, ChoiceLoader
    from django.conf import settings

    loaders = []
    for location in settings.TEMPLATE_DIRS:
        loaders.append(FileSystemLoader(location))
    env = Environment(loader=ChoiceLoader(loaders))

    def render_to_response(template, context, request=None):
        template = env.get_template(template)
        if request:
        for processor in get_standard_processors():
            context.update(processor(request))
        return HttpResponse(template.render(context))


If you want to plug Jinja into the Django i18n system you can use this
environment class:

.. sourcecode:: python

    from jinja import Environment
    from django.utils.translation import gettext, ngettext

    class DjangoTranslator(object):

        def __init__(self):
            self.gettext = gettext
            self.ngettext = ngettext

    class DjangoEnvironment(Environment):

        def get_translator(self, context):
            return DjangoTranslator()

Because Django uses gettext internally we can create just assign the
ngettext and gettext functions directly to the translator class.
