Tornado is awesome — its documentation at this point isn't. So here's my little contribution to make a great web framework a little easier to develop in.
First things first, Tornado's templates aren't sandboxed like Django's. Meaning it converts your templates into Python code and then executes them with a given context. And there's a benefit in rendering templates as evaluated Python code. Speed. Aside from being fast, I've personally found Tornado's templating syntax to be much easier to write in than Django's, though they are very similar.
But there's also a downside. Templates in Tornado make it possible to do almost anything, including accessing your database, deleting your files, terminating your webserver's instance, etc. These things can actually can be done in Django if you use a custom filter or tag, but straight out of the box, Django protects you from your templates. So a redundant and some-what-obvious word of warning: use discretion when writing your templates in Tornado.
Basic Output
1 Hello, {{ current_user.name }}
Basic Logic
1 {% if not current_user %}
2 You're not logged in!
3 {% elif current_user and curent_user.is_admin %}
4 Good day, sir!
5 {% else %}
6 Howdy!
7 {% end %}
8
9 {% for link in links %}
10 <a href="{{ link.href }}">{{ link.title }}</a>
11 {% end %}
12
13 {% set i = 10 %}
14 {% while i %}
15 Item {{ i }}
16 {% set i -= 1 %}
17 {% end %}
18
19 {% try %}
20 {{ undeclared_var }}
21 {% except NameError, e %}
22 {{ e }}
23 {% end %}
Inheritance
1 <!-- base.html Template -->
2 <body>
3 <div id="main">
4 {% block main %}
5 You'll see me if the 'main' block isn't overridden
6 {% end %}
7 </body>
8
9 <!-- home.html Template -->
10 {% extends "base.html" %}
11 {% block main %}
12 Now you see me!
13 {% end %}
Comments
1 {% comment "I'm a comment" %}
Includes
1 {% include "other_template.html" %}
Imports
1 {% import os %}
2 {% import sys %}
Setting Variables
1 {% set DEBUG = True %}
2 {% set BASEPATH = os.getcwd() %}
Applying a function to a block
1 {% apply escape %}
2 <h1>Hello World</h1>
3 {% end %}
4 output: <h1>Hello World</h1>
5
6 {% apply base64.b64encode %}
7 Base64 Encode Me!
8 {% end %}
9 output: CkJhc2U2NCBFbmNvZGUgTWUhCg==
Caveats
Because the templates are executed as Python code, they follow the same explicit rules as Python. For instance, if you try to access a variable that doesn't exist in scope {{ myvar }} , you'll get a NameError. If you're used to using Django or Jinja, this might throw you off. Also note that every closing block tag is always just {% end %} .
There's a lot more you can do with templates when they're integrated with Tornado's tornado.web.RequestHandler. I would recommend, if you haven't already, giving Tornado a try. It's a perfect combination of simplicity and power.