Skip to content

Commit

Permalink
Unified some code in the super/template reference system.
Browse files Browse the repository at this point in the history
--HG--
branch : trunk
  • Loading branch information
mitsuhiko committed Sep 20, 2008
1 parent 1b54f74 commit c347ed0
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 16 deletions.
4 changes: 3 additions & 1 deletion docs/templates.rst
Expand Up @@ -346,7 +346,6 @@ If you want to print a block multiple times you can however use the special
<h1>{{ self.title() }}</h1>
{% block body %}{% endblock %}


Unlike Python Jinja does not support multiple inheritance. So you can only have
one extends tag called per rendering.

Expand Down Expand Up @@ -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<call>` tag.

If a macro name starts with an underscore it's not exported and can't
be imported.


.. _call:

Expand Down
9 changes: 6 additions & 3 deletions examples/bench.py
Expand Up @@ -61,7 +61,7 @@ def test_jinja():
except ImportError:
test_django = None
else:
django_template = DjangoTemplate("""\
django_template = """\
<!doctype html>
<html>
<head>
Expand Down Expand Up @@ -89,13 +89,16 @@ def test_jinja():
</div>
</body>
</html>\
""")
"""

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
Expand Down
4 changes: 3 additions & 1 deletion examples/rwbench/rwbench.py
Expand Up @@ -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))


Expand Down
2 changes: 1 addition & 1 deletion ext/django2jinja/django2jinja.py
Expand Up @@ -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
Expand Down
42 changes: 32 additions & 10 deletions jinja2/runtime.py
Expand Up @@ -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
Expand Down Expand Up @@ -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."""

Expand Down

0 comments on commit c347ed0

Please sign in to comment.