Unified some code in the super/template reference system.
authorArmin Ronacher <armin.ronacher@active-4.com>
Sat, 20 Sep 2008 10:04:53 +0000 (12:04 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Sat, 20 Sep 2008 10:04:53 +0000 (12:04 +0200)
--HG--
branch : trunk

docs/templates.rst
examples/bench.py
examples/rwbench/rwbench.py
ext/django2jinja/django2jinja.py
jinja2/runtime.py

index f4f7348e72507b12347f4edf21dba967444c8c83..0b686865db60f04cc4736b13fd51f2395c3de39d 100644 (file)
@@ -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.
 
@@ -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:
 
index 8696be06c1c1980f24817d5c199f6bc4a8879ec1..49b1c752aa55a68d9a9ee100dfc203cc8b673705 100644 (file)
@@ -61,7 +61,7 @@ try:
 except ImportError:
     test_django = None
 else:
-    django_template = DjangoTemplate("""\
+    django_template = """\
 <!doctype html>
 <html>
   <head>
@@ -89,13 +89,16 @@ else:
     </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
index 1bde05694786aba2990c56a6d8678b8cc01eac4c..742e0ea9170dbcc6b6e37ce9ef0a8c6105bf883f 100644 (file)
@@ -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))
 
 
index a92781bbcf413fb6c45e7af87c2b1717793fe692..290d559f1b6e520fd70c21f7fcdd471d97282e16 100644 (file)
@@ -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
index bb5d9fdb18160082d6122fe7457c7a6c99d611d5..bd7e3057fad66c07f001707251ba7ece2960a024 100644 (file)
@@ -79,15 +79,13 @@ class Context(object):
         """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 @@ class TemplateReference(object):
         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."""