Jinja templates

Following on from yesterday’s seminar, where we had a render method like this:

def render(self, template, **kw):

We might call render from within the get or post method of a handler like this:

self.render('blog_front.html', posts=oposts)

The posts=oposts argument is of this form because it is being passed into the **kw argument of the render method, which takes any number of key=value pairs (in this case just one). And let us assume that the oposts variable contains a list of previously-collected post objects.

The blog_front template might look like this:

{% extends "base.html" %}
{% block title %}Blog posts{ % endblock %}
{% block content %}
  { % for post in posts %}
    <li><a href="/posts/{{ post.id }}">{{ post.title }}</a></li>
  { % endfor %}
{% endblock %}

And a bare-bones base template might look like this:

<!DOCTYPE html>
    <title>{% block title %}The site{% endblock %}</title>
    {% block content %}
    {% endblock %}

The {% block %} tags indicate a block of text that may be over-written by a template that extends the base template and extends or replaces the block.

The blog_front template might also have something that looks like this:

{{ post.render() }} 

Which will work if each post is an object that has a render method, defined somewhere in your application. This could be used, for example, to turn carriage returns into <br> tags.

It could also have something like this:

{{ post.render() | safe }}

Where the | denotes a custom filter in which the function (and it can be any regular Python function) is on the right and first argument to the function is on the left, so that this is equivalent to inserting into the document:


Which, in this case, will ensure that the post is appropriately escaped.

You could also do something like:

{{ post.date | datetimeformat('%d-%m-%Y') }}

Which will format a date nicely.

There is more (much more) to Jinja and Jinja templating, but this should be enough to get you going.