moved example code around
--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
This commit is contained in:
parent
5cdc1ac3d9
commit
612b3a88e2
56
examples/profile.py
Normal file
56
examples/profile.py
Normal file
@ -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()
|
||||
@ -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, ' ') %}
|
||||
<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) }}"> </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
|
||||
@ -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)
|
||||
@ -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, ' ') %}
|
||||
<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) }}"> </td>
|
||||
{%- endif %}
|
||||
</tr>
|
||||
{%- endfor %}
|
||||
</table>''')
|
||||
|
||||
print template.render(items=range(16))
|
||||
@ -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()
|
||||
@ -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()
|
||||
@ -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'
|
||||
}])
|
||||
@ -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()
|
||||
@ -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?'
|
||||
@ -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()
|
||||
@ -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 %}
|
||||
@ -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 %}
|
||||
@ -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 %}
|
||||
@ -1,2 +0,0 @@
|
||||
This breaks the template:
|
||||
{{ 1 / 0 }}
|
||||
@ -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 %}
|
||||
@ -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>
|
||||
Loading…
Reference in New Issue
Block a user