diff --git a/docs/templates.rst b/docs/templates.rst
index f4f7348e7..0b686865d 100644
--- a/docs/templates.rst
+++ b/docs/templates.rst
@@ -346,7 +346,6 @@ If you want to print a block multiple times you can however use the special
{{ self.title() }}
{% block body %}{% endblock %}
-
Unlike Python Jinja does not support multiple inheritance. So you can only have
one extends tag called per rendering.
@@ -615,6 +614,9 @@ are available on a macro object:
This is `true` if the macro accesses the special `caller` variable and may
be called from a :ref:`call` tag.
+If a macro name starts with an underscore it's not exported and can't
+be imported.
+
.. _call:
diff --git a/examples/bench.py b/examples/bench.py
index 8696be06c..49b1c752a 100644
--- a/examples/bench.py
+++ b/examples/bench.py
@@ -61,7 +61,7 @@ def test_jinja():
except ImportError:
test_django = None
else:
- django_template = DjangoTemplate("""\
+ django_template = """\
@@ -89,13 +89,16 @@ def test_jinja():
\
-""")
+"""
def test_django():
c = DjangoContext(context)
c['navigation'] = [('index.html', 'Index'), ('downloads.html', 'Downloads'),
('products.html', 'Products')]
- django_template.render(c)
+ # recompile template each rendering because that's what django
+ # is doing in normal situations too. Django is not thread safe
+ # so we can't cache it in regular apps either.
+ DjangoTemplate(django_template).render(c)
try:
from mako.template import Template as MakoTemplate
diff --git a/examples/rwbench/rwbench.py b/examples/rwbench/rwbench.py
index 1bde05694..742e0ea91 100644
--- a/examples/rwbench/rwbench.py
+++ b/examples/rwbench/rwbench.py
@@ -78,8 +78,10 @@ def test_mako():
from djangoext import django_loader, DjangoContext
-django_template = django_loader.get_template('index.html')
def test_django():
+ # not cached because django is not thread safe and does
+ # not cache by itself so it would be unfair to cache it here.
+ django_template = django_loader.get_template('index.html')
django_template.render(DjangoContext(context))
diff --git a/ext/django2jinja/django2jinja.py b/ext/django2jinja/django2jinja.py
index a92781bbc..290d559f1 100644
--- a/ext/django2jinja/django2jinja.py
+++ b/ext/django2jinja/django2jinja.py
@@ -413,7 +413,7 @@ def if_equal(writer, node):
@node(loader_tags.BlockNode)
def block(writer, node):
- writer.tag('block ' + node.name.replace('-', '_'))
+ writer.tag('block ' + node.name.replace('-', '_').rstrip('_'))
node = node
while node.parent is not None:
node = node.parent
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index bb5d9fdb1..bd7e3057f 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -79,15 +79,13 @@ def super(self, name, current):
"""Render a parent block."""
try:
blocks = self.blocks[name]
- block = blocks[blocks.index(current) + 1]
+ index = blocks.index(current) + 1
+ blocks[index]
except LookupError:
return self.environment.undefined('there is no parent block '
'called %r.' % name,
name='super')
- wrap = self.environment.autoescape and Markup or (lambda x: x)
- render = lambda: wrap(concat(block(self)))
- render.__name__ = render.name = name
- return render
+ return BlockReference(name, self, blocks, index)
def get(self, key, default=None):
"""Returns an item from the template context, if it doesn't exist
@@ -182,20 +180,44 @@ def __init__(self, context):
self.__context = context
def __getitem__(self, name):
- func = self.__context.blocks[name][0]
+ blocks = self.__context.blocks[name]
wrap = self.__context.environment.autoescape and \
Markup or (lambda x: x)
- render = lambda: wrap(concat(func(self.__context)))
- render.__name__ = render.name = name
- return render
+ return BlockReference(name, self.__context, blocks, 0)
def __repr__(self):
return '<%s %r>' % (
self.__class__.__name__,
- self._context.name
+ self.__context.name
)
+class BlockReference(object):
+ """One block on a template reference."""
+
+ def __init__(self, name, context, stack, depth):
+ self.name = name
+ self._context = context
+ self._stack = stack
+ self._depth = depth
+
+ @property
+ def super(self):
+ """Super the block."""
+ if self._depth + 1 >= len(self._stack):
+ return self._context.environment. \
+ undefined('there is no parent block called %r.' %
+ self.name, name='super')
+ return BlockReference(self.name, self._context, self._stack,
+ self._depth + 1)
+
+ def __call__(self):
+ rv = concat(self._stack[self._depth](self._context))
+ if self._context.environment.autoescape:
+ rv = Markup(rv)
+ return rv
+
+
class LoopContext(object):
"""A loop context for dynamic iteration."""