Global objects — Jinja Documentation

# Jinja

## Global objects

This section covers the behavior of global objects in the Jinja namespace and also the behavior of their attributes.

## Functions

Filters and Tests are special kind of functions you cannot call without and argument. Global functions are different. Those are really just ordinary python functions. You can register them on the global namespace easily:

    def my_function():
        return [1, 2, 3]

    env.globals['my_function'] = my_function

In the template you can not call it like this:

    {{ my_function() }}

Of couse you can pass any argument to it. But what if you want to access the context or environment? In that case you have to decorate a function or mark it (both work exactly the same, but the decorator way is probably nicer if you have python >= 2.4):

    from cgi import escape
    from pprint import pformat
    from jinja.datastructure import contextcallable

    @contextcallable
    def printcontext(env, context):
        result = []
        for key, value in context.to_dict():
            result.append('<tr><th>%s</th><td>%r</td></tr>' %
                          (escape(unicode(key)), escape(pformat(value))))
        return '<table>%s</table>' % u'\n'.join(result)

If this function is registered in the environment namespace then and called from the template it should return the content of the context as simple html template. Of course you can modify the context too. For more informations about the context object have a look at the context object documentation.

The new `{% call %}` tag that exists with Jinja 1.1 onwards can not only be used with Jinja macros but also with Python functions. If a template designers uses the `{% call %}` tag to call a function provided by the application Jinja will call this function with a keyword argument called caller which points to a function. If you call this function (optionally with keyword arguments that appear in the context) you get a string back that was the content of that block. This should explain this:

    def make_dialog(title, caller=None):
        body = ''
        if caller:
            body = caller(title=title)
        return '<div class="dialog"><h2>%s</h2>%s</div>' % (title, body)

This can be used like this in the template now:

    {% call make_dialog('Dialog Title') %}
        This is the body of the dialog entitled "{{ title }}".
    {% endcall %}

## Deferred Values

You can pass functions to the template that are called to provide values at first access. Say you want to pass the list of recently written comments to all templates. But not necessarily every template will render that. In that situation you can create a function that returns that value and wrap it in an Deferred object. The first time a template accesses the variable then the Deferred object is resolved:

    from jinja.datastructure import Deferred
    from yourapplication.models import Comments

    def get_recent_comments(env, context, name):
        # do what ever you want here.
        return Comments.get_recent(10)

    env.globals['recent_comments'] = Deferred(get_recent_comments)

The function is always called with the same arguments. The first one is the current environment, the second the context and the third is the name of the variable. In this example `recent_comments`.

The value is cached until rendering/streaming finished.

## Unsafe Methods / Attributes

Because Jinja is sandboxed it provides several ways to prevent unsafe attribute access. You can mark both attributes and methods as unsafe:

    from jinja.datastructure import unsafe

    class MyModel(...):

        # just give access to a and b. Default is all
        # note that this also disallows the functions from below.
        # if you use jinja_allowed_attributes you don't have add the
        # code below since methods are treated as attributes too.
        jinja_allowed_attributes = ['a', 'b']

        def __init__(self, ...):
            ...
            self.a = ...
            self.b = ...

        # python2.4 way of marking methods
        @unsafe
        def save(self):
            """Save the model."""

        # python2.3 way for the same
        def delete(self):
            """Delete the model."""
        delete.jinja_unsafe_call = True

## Bypassing Automatic Filtering

With Jinja 1.1 it's possible to assign filters to any variable printed. Of course there are ways to bypass that in order to make sure an object does not get escaped etc.

In order to disable automatic filtering for an object you have to make sure that it's either an subclass of unicode or implements a __unicode__ method. __str__ will work too as long as the return value only contains ASCII values. Additionally you have to add an attribute to that object named jinja_no_finalization and set that to True.