moved example code around
authorArmin Ronacher <armin.ronacher@active-4.com>
Wed, 7 May 2008 13:39:39 +0000 (15:39 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Wed, 7 May 2008 13:39:39 +0000 (15:39 +0200)
--HG--
branch : trunk
rename : examples/cycle.py => examples/basic/cycle.py
rename : examples/debugger.py => examples/basic/debugger.py
rename : examples/inheritance.py => examples/basic/inheritance.py
rename : examples/templates/broken.html => examples/basic/templates/broken.html
rename : examples/test.py => examples/basic/test.py
rename : examples/test_filter_and_linestatements.py => examples/basic/test_filter_and_linestatements.py
rename : examples/test_loop_filter.py => examples/basic/test_loop_filter.py
rename : examples/translate.py => examples/basic/translate.py

24 files changed:
examples/basic/cycle.py [moved from examples/cycle.py with 100% similarity]
examples/basic/debugger.py [moved from examples/debugger.py with 100% similarity]
examples/basic/inheritance.py [moved from examples/inheritance.py with 100% similarity]
examples/basic/templates/broken.html [moved from examples/templates/broken.html with 100% similarity]
examples/basic/test.py [moved from examples/test.py with 100% similarity]
examples/basic/test_filter_and_linestatements.py [moved from examples/test_filter_and_linestatements.py with 100% similarity]
examples/basic/test_loop_filter.py [moved from examples/test_loop_filter.py with 100% similarity]
examples/basic/translate.py [moved from examples/translate.py with 100% similarity]
examples/profile.py [new file with mode: 0644]
tests/runtime/bigbench.py [deleted file]
tests/runtime/bigtable.py [deleted file]
tests/runtime/columntest.py [deleted file]
tests/runtime/exception.py [deleted file]
tests/runtime/inheritance.py [deleted file]
tests/runtime/layout.py [deleted file]
tests/runtime/modglobals.py [deleted file]
tests/runtime/strange.py [deleted file]
tests/runtime/super.py [deleted file]
tests/runtime/templates/a.html [deleted file]
tests/runtime/templates/b.html [deleted file]
tests/runtime/templates/c.html [deleted file]
tests/runtime/templates/included_error.html [deleted file]
tests/runtime/templates/index.html [deleted file]
tests/runtime/templates/layout.html [deleted file]

similarity index 100%
rename from examples/cycle.py
rename to examples/basic/cycle.py
similarity index 100%
rename from examples/test.py
rename to examples/basic/test.py
diff --git a/examples/profile.py b/examples/profile.py
new file mode 100644 (file)
index 0000000..843efb1
--- /dev/null
@@ -0,0 +1,56 @@
+try:
+    from cProfile import Profile
+except ImportError:
+    from profile import Profile
+from pstats import Stats
+from jinja2 import Environment as JinjaEnvironment
+
+context = {
+    'page_title': 'mitsuhiko\'s benchmark',
+    'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) for x in range(1000)]
+}
+
+jinja_template = JinjaEnvironment(
+    line_statement_prefix='%',
+    variable_start_string="${",
+    variable_end_string="}"
+).from_string("""\
+<!doctype html>
+<html>
+  <head>
+    <title>${page_title|e}</title>
+  </head>
+  <body>
+    <div class="header">
+      <h1>${page_title|e}</h1>
+    </div>
+    <ul class="navigation">
+    % for href, caption in [
+        ('index.html', 'Index'),
+        ('downloads.html', 'Downloads'),
+        ('products.html', 'Products')
+      ]
+      <li><a href="${href|e}">${caption|e}</a></li>
+    % endfor
+    </ul>
+    <div class="table">
+      <table>
+      % for row in table
+        <tr>
+        % for cell in row
+          <td>${cell}</td>
+        % endfor
+        </tr>
+      % endfor
+      </table>
+    </div>
+  </body>
+</html>\
+""")
+
+
+p = Profile()
+p.runcall(lambda: jinja_template.render(context))
+stats = Stats(p)
+stats.sort_stats('time', 'calls')
+stats.print_stats()
diff --git a/tests/runtime/bigbench.py b/tests/runtime/bigbench.py
deleted file mode 100644 (file)
index 58014bf..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-import jdebug
-from time import time
-from jinja2 import Environment
-tmpl = Environment().from_string('''
-<h1>Bigtable</h1>
-<table>
-{%- for row in table -%}
-  <tr>
-  {%- for col in row.values() %}
-    <td>{{ col }}</td>
-  {%- endfor %}
-  </tr>
-{%- endfor %}
-</table>
-
-<h1>Unfilled</h1>
-<div class="index">
-  {%- for column in items|slice(3) %}
-  <div class="col-{{ loop.index }}">
-    <ul>
-    {%- for item in column %}
-      <li>{{ item }}</li>
-    {%- endfor %}
-    </ul>
-  </div>
-  {%- endfor %}
-</div>
-
-<h1>Filled</h1>
-<div class="index">
-  {%- for column in items|slice(3, 'missing') %}
-  <div class="col-{{ loop.index }}">
-    <ul>
-    {%- for item in column %}
-      <li>{{ item }}</li>
-    {%- endfor %}
-    </ul>
-  </div>
-  {%- endfor %}
-</div>
-
-<h1>Filled Table</h1>
-<table>
-  {%- for row in items|batch(3, '&nbsp;') %}
-  <tr>
-    {%- for column in row %}
-    <td>{{ column }}</td>
-    {%- endfor %}
-  </tr>
-  {%- endfor %}
-</table>
-
-<h1>Unfilled Table</h1>
-<table>
-  {%- for row in items|batch(3) %}
-  <tr>
-    {%- for column in row %}
-    <td>{{ column }}</td>
-    {%- endfor %}
-    {%- if row|length < 3 %}
-    <td colspan="{{ 3 - (row|length) }}">&nbsp;</td>
-    {%- endif %}
-  </tr>
-  {%- endfor %}
-</table>
-
-<h1>Macros</h1>
-{% macro foo seq %}
-  <ul>
-  {%- for item in seq %}
-    <li>{{ caller(item=item) }}</li>
-  {%- endfor %}
-  </ul>
-{% endmacro %}
-
-{% call foo(items) -%}
-  [{{ item }}]
-{%- endcall %}
-''')
-
-start = time()
-for _ in xrange(50):
-    tmpl.render(
-        items=range(200),
-        table=[dict(a='1',b='2',c='3',d='4',e='5',f='6',g='7',h='8',i='9',j='10')
-               for x in range(1000)]
-    )
-print time() - start
diff --git a/tests/runtime/bigtable.py b/tests/runtime/bigtable.py
deleted file mode 100644 (file)
index c86a12a..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-# -*- coding: utf-8 -*_
-# Template language benchmarks
-#
-# Objective: Generate a 1000x10 HTML table as fast as possible.
-# adapted for jinja 1
-#
-# Author: Jonas Borgström <jonas@edgewall.com>
-# Author: Armin Ronacher <armin.ronacher@active-4.com>
-
-import os
-import sys
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
-
-import cgi
-import timeit
-import jdebug
-from StringIO import StringIO
-
-
-try:
-    from genshi.builder import tag
-    from genshi.template import MarkupTemplate
-    have_genshi = True
-except ImportError:
-    have_genshi = False
-
-from jinja2 import Environment
-
-try:
-    from django.conf import settings
-    settings.configure()
-    from django.template import Context as DjangoContext
-    from django.template import Template as DjangoTemplate
-    have_django = True
-except ImportError:
-    have_django = False
-
-try:
-    from kid import Template as KidTemplate
-    have_kid = True
-except ImportError:
-    have_kid = False
-
-try:
-    from Cheetah.Template import Template as CheetahTemplate
-    have_cheetah = True
-except ImportError:
-    have_cheetah = False
-
-try:
-    from mako.template import Template as MakoTemplate
-    have_mako = True
-except ImportError:
-    have_mako = False
-
-table = [dict(zip('abcdefghij', map(unicode,range(1, 11))))
-          for x in range(1000)]
-
-if have_genshi:
-    genshi_tmpl = MarkupTemplate("""
-<table xmlns:py="http://genshi.edgewall.org/">
-<tr py:for="row in table">
-<td py:for="c in row.values()" py:content="c"/>
-</tr>
-</table>
-""")
-
-if have_kid:
-    kid_tmpl = KidTemplate("""
-<table xmlns:py="http://purl.org/kid/ns#">
-<tr py:for="row in table">
-<td py:for="c in row.values()" py:content="c"/>
-</tr>
-</table>
-""")
-
-if have_django:
-    django_tmpl = DjangoTemplate("""
-<table>
-{% for row in table %}
-<tr>{% for col in row.values %}<td>{{ col }}</td>{% endfor %}</tr>
-{% endfor %}
-</table>
-""")
-
-jinja_tmpl = Environment().from_string('''
-<table>
-{% for row in table -%}
-<tr>{% for col in row.values() %}<td>{{ col }}</td>{% endfor %}</tr>
-{% endfor %}
-</table>
-''')
-
-if have_cheetah:
-    cheetah_tmpl = CheetahTemplate('''
-<table>
-#for $row in $table
-<tr>
-#for $col in $row.values()
-<td>$col</td>
-#end for
-</tr>
-#end for
-</table>
-''', searchList=[{'table': table, 'escape': cgi.escape}])
-
-if have_mako:
-    mako_tmpl = MakoTemplate('''
-<table>
-% for row in table:
-<tr>
-% for col in row.values():
-    <td>${col}</td>
-% endfor
-</tr>
-% endfor
-</table>
-''')
-
-def test_django():
-    """Django Templates"""
-    if not have_django:
-        return
-    context = DjangoContext({'table': table})
-    django_tmpl.render(context)
-
-def test_jinja():
-    """Jinja Templates"""
-    jinja_tmpl.render(table=table)
-
-def test_genshi():
-    """Genshi Templates"""
-    if not have_genshi:
-        return
-    stream = genshi_tmpl.generate(table=table)
-    stream.render('html', strip_whitespace=False)
-
-def test_kid():
-    """Kid Templates"""
-    if not have_kid:
-        return
-    kid_tmpl.table = table
-    kid_tmpl.serialize(output="html")
-
-def test_cheetah():
-    """Cheetah Templates"""
-    if not have_cheetah:
-        return
-    cheetah_tmpl.respond()
-
-def test_mako():
-    """Mako Templates"""
-    if not have_mako:
-        return
-    mako_tmpl.render(table=table)
-
-
-def run(which=None, number=10):
-    tests = ['test_django', 'test_jinja', 'test_kid', 'test_genshi',
-             'test_cheetah', 'test_mako']
-
-    if which:
-        tests = filter(lambda n: n[5:] in which, tests)
-
-    for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
-        t = timeit.Timer(setup='from __main__ import %s;' % test,
-                         stmt='%s()' % test)
-        time = t.timeit(number=number) / number
-
-        if time < 0.00001:
-            result = '   (not installed?)'
-        else:
-            result = '%16.2f ms' % (1000 * time)
-        print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
-
-
-if __name__ == '__main__':
-    which = [arg for arg in sys.argv[1:] if arg[0] != '-']
-
-    if '-p' in sys.argv:
-        from cProfile import Profile
-        from pstats import Stats
-        p = Profile()
-        p.runcall(test_jinja)
-        stats = Stats(p)
-        stats.strip_dirs()
-        stats.sort_stats('time', 'calls')
-        stats.print_stats()
-    else:
-        run(which)
diff --git a/tests/runtime/columntest.py b/tests/runtime/columntest.py
deleted file mode 100644 (file)
index ebda8ca..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-import jdebug
-from jinja2 import from_string
-
-
-template = from_string(u'''\
-<h1>Unfilled</h1>
-<div class="index">
-  {%- for column in items|slice(3) %}
-  <div class="col-{{ loop.index }}">
-    <ul>
-    {%- for item in column %}
-      <li>{{ item }}</li>
-    {%- endfor %}
-    </ul>
-  </div>
-  {%- endfor %}
-</div>
-
-<h1>Filled</h1>
-<div class="index">
-  {%- for column in items|slice(3, 'missing') %}
-  <div class="col-{{ loop.index }}">
-    <ul>
-    {%- for item in column %}
-      <li>{{ item }}</li>
-    {%- endfor %}
-    </ul>
-  </div>
-  {%- endfor %}
-</div>
-
-<h1>Filled Table</h1>
-<table>
-  {%- for row in items|batch(3, '&nbsp;') %}
-  <tr>
-    {%- for column in row %}
-    <td>{{ column }}</td>
-    {%- endfor %}
-  </tr>
-  {%- endfor %}
-</table>
-
-<h1>Unfilled Table</h1>
-<table>
-  {%- for row in items|batch(3) %}
-  <tr>
-    {%- for column in row %}
-    <td>{{ column }}</td>
-    {%- endfor %}
-    {%- if row|length < 3 %}
-    <td colspan="{{ 3 - (row|length) }}">&nbsp;</td>
-    {%- endif %}
-  </tr>
-  {%- endfor %}
-</table>''')
-
-print template.render(items=range(16))
diff --git a/tests/runtime/exception.py b/tests/runtime/exception.py
deleted file mode 100644 (file)
index 4fc2cff..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-import os
-import sys
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
-
-import jdebug
-from jinja2 import Environment, DictLoader
-from jinja2.exceptions import TemplateNotFound
-from wsgiref.simple_server import make_server
-
-e = Environment(loader=DictLoader({
-    '/': u'''
-<html>
-  <head>
-    <title>Various Broken Templates</title>
-    <style type="text/css">
-      body {
-        margin: 2em;
-        font-size: 1.5em;
-        font-family: sans-serif
-      }
-      a {
-        color: #d00;
-      }
-    </style>
-  </head>
-  <body>
-    <h1>Various Broken Templates</h1>
-    <p>
-      This small WSGI application serves some Jinja templates that
-      are just broken. It uses the colubrid traceback middleware to
-      render those errors including source code.
-    </p>
-    <ul>
-      <li><a href="syntax_error">syntax error</a></li>
-      <li><a href="runtime_error">runtime error</a></li>
-      <li><a href="nested_syntax_error">nested syntax error</a></li>
-      <li><a href="nested_runtime_error">nested runtime error</a></li>
-      <li><a href="code_runtime_error">runtime error in code</a></li>
-      <li><a href="syntax_from_string">a syntax error from string</a></li>
-      <li><a href="runtime_from_string">runtime error from a string</a></li>
-      <li><a href="multiple_templates">multiple templates</a></li>
-    </ul>
-  </body>
-</html>
-''',
-    '/syntax_error': u'''
-{% for item in foo %}
-    ...
-{% endif %}
-    ''',
-    '/runtime_error': u'''
-{% set foo = 1 / 0 %}
-    ''',
-    '/nested_runtime_error': u'''
-{% include 'runtime_broken' %}
-    ''',
-    '/nested_syntax_error': u'''
-{% include 'syntax_broken' %}
-    ''',
-    '/code_runtime_error': u'''We have a runtime error here:
-    {{ broken() }}''',
-    '/multiple_templates': '''\
-{{ fire_multiple_broken() }}
-''',
-
-    'runtime_broken': '''\
-This is an included template
-{% set a = 1 / 0 %}''',
-    'syntax_broken': '''\
-This is an included template
-{% raw %}just some foo''',
-    'multiple_broken': '''\
-Just some context:
-{% include 'macro_broken' %}
-{{ broken() }}
-''',
-    'macro_broken': '''\
-{% macro broken %}
-    {{ 1 / 0 }}
-{% endmacro %}
-'''
-}))
-e.globals['fire_multiple_broken'] = lambda: \
-    e.get_template('multiple_broken').render()
-
-FAILING_STRING_TEMPLATE = '{{ 1 / 0 }}'
-BROKEN_STRING_TEMPLATE = '{% if foo %}...{% endfor %}'
-
-
-def broken():
-    raise RuntimeError("I'm broken")
-
-
-def test(environ, start_response):
-    path = environ.get('PATH_INFO' or '/')
-    try:
-        tmpl = e.get_template(path)
-    except TemplateNotFound:
-        if path == '/syntax_from_string':
-            tmpl = e.from_string(BROKEN_STRING_TEMPLATE)
-        elif path == '/runtime_from_string':
-            tmpl = e.from_string(FAILING_STRING_TEMPLATE)
-        else:
-            start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
-            return ['NOT FOUND']
-    start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
-    return [tmpl.render(broken=broken).encode('utf-8')]
-
-
-if __name__ == '__main__':
-    from werkzeug.debug import DebuggedApplication
-    app = DebuggedApplication(test, True)
-    make_server("localhost", 7000, app).serve_forever()
diff --git a/tests/runtime/inheritance.py b/tests/runtime/inheritance.py
deleted file mode 100644 (file)
index 1e1ff85..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-from jinja2 import Environment, FileSystemLoader
-e = Environment(loader=FileSystemLoader('templates'))
-
-from jinja2.parser import Parser
-from jinja2.translators.python import PythonTranslator
-
-tmpl = e.loader.load('c.html')
-print tmpl.render()
diff --git a/tests/runtime/layout.py b/tests/runtime/layout.py
deleted file mode 100644 (file)
index 9e1bce5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from jinja2 import Environment, FileSystemLoader
-e = Environment(loader=FileSystemLoader('templates'))
-
-from jinja2.parser import Parser
-from jinja2.translators.python import PythonTranslator
-
-print PythonTranslator(e, e.loader.parse('index.html')).translate()
-
-tmpl = e.loader.load('index.html')
-print tmpl.render(navigation_items=[{
-    'url':          '/',
-    'caption':      'Index'
-}])
diff --git a/tests/runtime/modglobals.py b/tests/runtime/modglobals.py
deleted file mode 100644 (file)
index b8d784b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# test file for block super support
-import jdebug
-from jinja2 import Environment, DictLoader
-
-env = Environment(loader=DictLoader({
-    'a': '''\
-<title>{{ title|e }}</title>
-<body>
-    {% block body %}Default{% endblock %}
-</body>
-''',
-    'b': '''
-{% set foo = 42 %}
-''',
-    'c': '''
-{% extends 'a' %}
-{% if true %}
-    {% set title = "foo" %}
-{% endif %}
-{% include 'b' %}
-{% include 'tools' %}
-{% block body %}
-    hehe, this comes from b: {{ foo }}
-
-    Say hello to the former block content:
-        {{ say_hello(super()) }}
-{% endblock %}
-''',
-    'tools': '''
-{% macro say_hello name -%}
-    Hello {{ name }}!
-{%- endmacro %}
-'''
-}))
-
-tmpl = env.get_template('c')
-print tmpl.render()
diff --git a/tests/runtime/strange.py b/tests/runtime/strange.py
deleted file mode 100644 (file)
index baaae0d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-import jdebug
-from jinja2 import Environment, DictLoader
-
-base_tmpl = """
-{% block content %}Default{% endblock %}
-"""
-
-### condition is inside of block
-
-test1 = """
-{% extends 'base' %}
-
-{% block content %}
-  {% if False %}
-    {{ throw_exception() }}
-  {% endif %}
-{% endblock %}
-"""
-
-### block is inside of condition
-
-test2 = """
-{% extends 'base' %}
-
-{% if False %}
-  {% block content %}
-    {{ throw_exception() }}
-  {% endblock %}
-{% endif %}
-"""
-
-class TestException(Exception):
-    pass
-
-def throw_exception():
-    raise TestException()
-
-env = Environment(
-    loader=DictLoader(dict(base=base_tmpl))
-)
-
-if __name__ == '__main__':
-    for name in 'test1', 'test2':
-        template_body = globals().get(name)
-        template = env.from_string(template_body)
-        try:
-            print 'Rendering template:\n"""%s"""' % template_body
-            template.render(throw_exception=throw_exception)
-        except TestException:
-            print 'Result: throw_exception() was called'
-        else:
-            print 'Result: throw_exception() was not called'
-        print
-
-    print 'First template illustrates that condition is working well'
-    print 'The question is - why {% block %} is being evalueted '\
-          'in false condition in second template?'
diff --git a/tests/runtime/super.py b/tests/runtime/super.py
deleted file mode 100644 (file)
index d777760..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# test file for block super support
-import jdebug
-from jinja2 import Environment, DictLoader
-
-env = Environment(loader=DictLoader({
-    'a': '{% block intro %}INTRO{% endblock %}|BEFORE|{% block data %}INNER{% endblock %}|AFTER',
-    'b': '{% extends "a" %}{% block data %}({{ super() }}){% endblock %}',
-    'c': '{% extends "b" %}{% block intro %}--{{ super() }}--{% endblock %}\n{% block data %}[{{ super() }}]{% endblock %}'
-}))
-
-tmpl = env.get_template('c')
-print tmpl.render()
diff --git a/tests/runtime/templates/a.html b/tests/runtime/templates/a.html
deleted file mode 100644 (file)
index 7aab683..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{% block block1 %}from template a.html{% endblock %}
-{% block block2 %}from template a.html{% endblock %}
-{% block block3 %}from template a.html{% endblock %}
-{% block block4 %}
-  nested block from template a.html
-  {% block block5 %}
-    contents of the nested block from a.html
-    {% block block6 %}
-      double nested block.
-    {% endblock %}
-  {% endblock %}
-{% endblock %}
diff --git a/tests/runtime/templates/b.html b/tests/runtime/templates/b.html
deleted file mode 100644 (file)
index 32626f3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends 'a.html' %}
-{% block block1 %}from template b.html{% endblock %}
-{% block block5 %}
-  contents of nested block from b.html
-  {% block block7 %}
-    new nested block introduced in b.html
-  {% endblock %}
-{% endblock %}
diff --git a/tests/runtime/templates/c.html b/tests/runtime/templates/c.html
deleted file mode 100644 (file)
index 1cc4f71..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{% extends 'b.html' %}
-{% block block2 %}from template c.html{% endblock %}
-{% block block3 %}from template c.html{% endblock %}
-{% block block7 %}
-  nested block from b.html, overridden in c.html
-{% endblock %}
diff --git a/tests/runtime/templates/included_error.html b/tests/runtime/templates/included_error.html
deleted file mode 100644 (file)
index da11ba1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-This breaks the template:
-{{ 1 / 0 }}
diff --git a/tests/runtime/templates/index.html b/tests/runtime/templates/index.html
deleted file mode 100644 (file)
index 1026da6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "layout.html" %}
-
-{% macro say_hello name %}
-Hello {{ name }}!.
-{% endmacro %}
-
-{% set greet = say_hello %}
-
-{% block page_title %}Index{% endblock %}
-{% block body %}
-  This is the index page.<br />
-  {{ greet('John Doe') }}
-{% endblock %}
diff --git a/tests/runtime/templates/layout.html b/tests/runtime/templates/layout.html
deleted file mode 100644 (file)
index bf7b5f0..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Frameset//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
-<html>
-  <head>
-    <title>{% block page_title %}Untitled{% endblock %} | My Webpage</title>
-    {% block page_head %}{% endblock %}
-  </head>
-  <body>
-    <div id="header">
-      <h1>My Webpage</h1>
-      <ul id="navigation">
-      {% for item in navigation_items %}
-        <li><a href="{{ item.url|escape }}">{{ item.caption|escape }}</a></li>
-      {% endfor %}
-      </ul>
-    </div>
-    <div id="body">
-      {% block body %}
-        content goes here.
-      {% endblock %}
-    </div>
-  </body>
-</html>