Browse files

some more doc changes in jinja for the upcoming release

branch : trunk
  • Loading branch information...
1 parent c9fe16e commit 825e522fb5618d0fcfab0ed0d752332a35e20b94 @mitsuhiko mitsuhiko committed Nov 16, 2007
@@ -0,0 +1,6 @@
@@ -3,7 +3,14 @@ Jinja Changelog
Version 1.2
-(codename to be selected, release date unknown)
+(codename to be hatsuyuki, released Nov 17th 2007)
+.. admonition:: Backwards Incompatible Changes
+ - `call` is a keyword now
+ - the internal parser AST changed
+ - `extends` must be the first tag in a template
+ - the tuple literal yields tuples now, instead of lists.
- environments now have a `translator_factory` parameter that allows
to change the translator without subclassing the environment.
@@ -8,20 +8,25 @@ does not support the `__loader__` hook which is used by Jinja to provide
templates. Although the import system was implemented three Python versions
ago the default traceback system still doesn't support it.
-However most of the extended web development traceback module support it:
+However most of the extended web development traceback modules have support
+for `__loader__`. Either directly or via the linecache module:
-- `Colubrid Debugging Middleware`_
+- `Werkzeug Debugging Middleware`_
+- `Django`_
- `cgitb`_
- `EvalException`_
-Note that the django traceback module currently does not provide this. `A
-ticket`_ was filed already so there is hope that this will be fixed.
To enable debugging you have to use one of those debugging systems or
implement your own one with support for `__loader__`.
+The python implementation of the jinja debugger can only translate the first
+exception in a traceback which can lead to problematic results. If you have
+the extended debugger c extension compiled (default on unix systems but only
+available on Windows if you have a VisualStudio 2003 installation) all frames
+in the traceback will point to the correct linenumbers of the templates.
-.. _Colubrid Debugging Middleware:
+.. _Werkzeug Debugging Middleware:
+.. _Django:
.. _cgitb:
.. _EvalException:
-.. _A ticket:
@@ -223,6 +223,14 @@ table shows which syntax elements are supported:
``undefined`` special Jinja undefined singleton.
======================= ===================================================
+.. admonition:: Common Pitfalls
+ Keep in mind that Jinja literals, keywords and functions are all lowercase.
+ If you're used to Python you probably tried to write `True` which evaluates
+ to undefined because it simply does not exist. The correct name for the
+ true value is just `true` (lowercase).
@@ -38,6 +38,7 @@ You can use it now like this:
In the template you can now access the local variables `seq` and `foo`.
Using Django Filters with Jinja
@@ -75,10 +76,18 @@ And use it:
Also keep in mind that Jinja knows about keywords, thus you cannot have a filter
that is called `pluralize` for example.
+Such a conversion function is also part of the djangosupport module which was
+introduced in Jinja 1.2. It's explained on the `Framework Integration`_ page.
Using Jinja in Django
+.. admonition:: Note
+ This section is more or less obsolete as of Jinja 1.2 which provides a
+ djangosupport module, covered on the `Framework Integration`_ page.
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
@@ -125,3 +134,6 @@ environment class:
Because Django uses gettext internally we can create just assign the
ngettext and gettext functions directly to the translator class.
+.. _Framework Integration: frameworks.txt
@@ -40,8 +40,8 @@ processing).
Starting with `Jinja 1.1` you can also handle some whitespace rules in the
template. If you put an minus sign (`-`) to the start or end of an block
-(for example a `for` tag) or a comment, variable element you can remove
-the whitespaces after that block or before that block:
+(for example a `for` tag), a comment or variable element you can remove
+the whitespaces after or before that block:
.. sourcecode:: jinja
@@ -15,6 +15,7 @@ called `General Template Interface`_ which isn't implemented by any existing
framework so far. This specification however tries to solve the problems that
exist in Buffet.
@@ -108,6 +109,7 @@ a folder in the ``yourapplication`` python package.
The `downloads` action uses the pylons specific leading foreslash notation.
General Template Interface
@@ -121,7 +123,112 @@ Django
Using Jinja in django is straightforward because django has a pretty low
level response interface. Just have a look at the `developer recipies`_,
-there are some examples for django.
+there are some examples for django. Starting with Jinja 1.2 there is also
+a contrib module that simplifies using Jinja in an unicode enabled django.
+To get started execute the following code at the bottom of your
+or in some general application file such as or a central module. The
+only thing that matters is that it's executed right *after* the settings
+were set up and *before* `django.contrib.jinja` is imported::
+ from jinja.contrib import djangosupport
+ djangosupport.configure()
+What this does is setting up a Jinja environment for this django instance
+with loaders for `TEMPLATE_DIRS` etc. It also converts a couple of default
+django filters such as `date` and `timesince` which are not available in
+Jinja per default. If you want to change the list you can provide others
+by passing a list with filter import names as `convert_filters` keyword
+All other keyword arguments are forwarded to the environment. If you want
+to provide a loader yourself pass it a loader keyword argument.
+Rendering Templates
+To render a template you can use the functions `render_to_string` or
+`render_to_response` from the `django.contrib.jinja` module::
+ from django.contrib.jinja import render_to_response
+ resp = render_to_response('Hello {{ username }}!', {
+ 'username': req.session['username']
+ }, req)
+`render_to_string` and `render_to_response` take at least the name of
+the template as argument, then the optional dict which will become the
+context. If you also provide a request object as third argument the
+context processors will be applied.
+`render_to_response` also takes a forth parameter which can be the
+content type which defaults to `DEFAULT_CONTENT_TYPE`.
+Converting Filters
+One of the useful objects provided by `django.contrib.jinja` is the
+`register` object which can be used to register filters, tests and
+global objects. You can also convert any filter django provides in
+a Jinja filter using `convert_django_filter`::
+ from django.contrib.jinja import register, convert_django_filter
+ from django.template.defaultfilters import floatformat
+ register.filter(convert_django_filter(floatformat), 'floatformat')
+Available methods on the `register` object:
+``object (obj[, name])``
+ Register a new global as name or with the object's name.
+ Returns the function object unchanged so that you can use
+ it as decorator if no name is provided.
+``filter (func[, name])``
+ Register a function as filter with the name provided or
+ the object's name as filtername.
+ Returns the function object unchanged so that you can use
+ it as decorator if no name is provided.
+``test (func[, name])``
+ Register a function as test with the name provided or the
+ object's name as testname.
+ Returns the function object unchanged so that you can use
+ it as decorator if no name is provided.
+``context_inclusion (func, template[, name])``
+ Register a function with a name provided or the func object's
+ name in the global namespace that acts as subrender function.
+ func is called with the callers context as dict and the
+ arguments and keywords argument of the inclusion function.
+ The function should then process the context and return a
+ new context or the same context object. Afterwards the
+ template is rendered with this context.
+ Example::
+ def add_author(context, author=None):
+ if author is not None:
+ author = Author.objects.get(name=author)
+ context['author'] = author
+ return context
+ register.context_inclusion(add_author, 'author_details.html',
+ 'render_author_details')
+ You can use it in the template like this then::
+ {{ render_author_details('John Doe') }}
+``clean_inclusion (func, template[, name[, run_processors]]) ``
+ Works like `context_inclusion` but doesn't use the calles
+ context but an empty context. If `run_processors` is `True`
+ it will lookup the context for a `request` object and pass
+ it to the render function to apply context processors.
.. _Pylons:
@@ -4,6 +4,7 @@ Installation
Jinja requires at least Python 2.3 to work correctly.
Installing a released version
@@ -30,6 +31,7 @@ internet connection.
This will install Jinja into your Python installation's site-packages directory.
Installing the development version
@@ -42,7 +44,8 @@ If you want to play around with the code
4. ``ln -s jinja /usr/lib/python2.X/site-packages``
As an alternative to steps 4 you can also do ``python develop``
-which will install the package via setuptools in development mode.
+which will install the package via setuptools in development mode. This also
+has the advantage that the c extensions are compiled.
If you just want the latest features and use them
@@ -55,6 +58,19 @@ This will install a Jinja egg containing the latest Subversion trunk code
in your Python installation's site-packages directory. Every time the command
is run, the sources are updated from Subversion.
+Windows Installation Information
+On windows computers without Visual Studio 2003 Jinja is unable to compile the
+C extensions. This is usually not a problem because there is a fallback for
+native Python implementations of those C libraries. However under certain
+conditions the installation may fail with an error message. In that case try
+to disable the extensions by passing the following parameters to
+ python install --without-speedups --without-extended-debugger
@@ -182,6 +182,5 @@ it. There is however a way to override a variable from an outer scope using the
After the iteration `last_item` will point to the item of the last iteration.
-If `last_item` was not defined in the outer scope it wouldn't exist now because
-in that situation `set`, even with a postfixed bang just behaves like setting a
-scope variable.
+If `last_item` was not defined in the outer scope it would be defined in the
+outermost scope.
@@ -274,7 +274,7 @@ def set_nonlocal(self, name, value):
if name in layer:
layer[name] = value
- self.current[name] = value
+ self.initial[name] = value
def translate_func(self):
@@ -90,15 +90,15 @@ def build_extension(self, ext):
'speedups': Feature(
'optional C-speed enhancements',
- standard = True,
- ext_modules = [
+ standard=True,
+ ext_modules=[
Extension('jinja._speedups', ['jinja/_speedups.c'])
'extended-debugger': Feature(
'extended debugger',
- standard = True,
- ext_modules = [
+ standard=True,
+ ext_modules=[
Extension('jinja._debugger', ['jinja/_debugger.c'])
@@ -6,6 +6,14 @@
:copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
+from jinja import Environment
+{% for item in range(10) %}
+ {%- set outer = item! -%}
+{% endfor -%}
+{{ outer }}'''
class PrivateStuff(object):
@@ -49,3 +57,11 @@ class PublicStuff(object):
TemplateSyntaxError: cannot assign to expression (line 1)
+def test_nonlocal_set():
+ env = Environment()
+ env.globals['outer'] = 42
+ tmpl = env.from_string(NONLOCALSET)
+ assert tmpl.render() == '9'
+ assert env.globals['outer'] == 42

0 comments on commit 825e522

Please sign in to comment.