inheritance uses a less awkward hack for contexts now and subclassing templates is possible
--HG--
branch : trunk
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 871728f..9bf1e4d 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -475,14 +475,12 @@
self.blocks[block.name] = block
# generate the root render function.
- self.writeline('def root(globals, environment=environment'
- ', standalone=False):', extra=1)
- self.indent()
- self.writeline('context = TemplateContext(environment, globals, %r, '
- 'blocks, standalone)' % self.name)
+ self.writeline('def root(context, environment=environment'
+ '):', extra=1)
if have_extends:
- self.writeline('parent_root = None')
- self.outdent()
+ self.indent()
+ self.writeline('parent_template = None')
+ self.outdent()
# process the root
frame = Frame()
@@ -490,7 +488,6 @@
frame.toplevel = frame.rootlevel = True
self.indent()
self.pull_locals(frame, indent=False)
- self.writeline('yield context')
self.blockvisit(node.body, frame, indent=False)
self.outdent()
@@ -498,14 +495,13 @@
if have_extends:
if not self.has_known_extends:
self.indent()
- self.writeline('if parent_root is not None:')
+ self.writeline('if parent_template is not None:')
self.indent()
- self.writeline('stream = parent_root(context)')
- self.writeline('stream.next()')
- self.writeline('for event in stream:')
+ self.writeline('for event in parent_template.'
+ 'root_render_func(context):')
self.indent()
self.writeline('yield event')
- self.outdent(1 + self.has_known_extends)
+ self.outdent(2 + (not self.has_known_extends))
# at this point we now have the blocks collected and can visit them too.
for name, block in self.blocks.iteritems():
@@ -513,7 +509,8 @@
block_frame.inspect(block.body)
block_frame.block = name
block_frame.identifiers.add_special('super')
- block_frame.name_overrides['super'] = 'context.super(%r)' % name
+ block_frame.name_overrides['super'] = 'context.super(%r, ' \
+ 'block_%s)' % (name, name)
self.writeline('def block_%s(context, environment=environment):'
% name, block, 1)
self.pull_locals(block_frame)
@@ -524,9 +521,8 @@
extra=1)
# add a function that returns the debug info
- self.writeline('def get_debug_info():', extra=1)
- self.indent()
- self.writeline('return %r' % self.debug_info)
+ self.writeline('debug_info = %r' % '&'.join('%s=%s' % x for x
+ in self.debug_info))
def visit_Block(self, node, frame):
"""Call a block and register it for the template."""
@@ -537,7 +533,7 @@
if self.has_known_extends:
return
if self.extends_so_far > 0:
- self.writeline('if parent_root is None:')
+ self.writeline('if parent_template is None:')
self.indent()
level += 1
self.writeline('for event in context.blocks[%r][-1](context):' % node.name)
@@ -565,7 +561,7 @@
# time too, but i welcome it not to confuse users by throwing the
# same error at different times just "because we can".
if not self.has_known_extends:
- self.writeline('if parent_root is not None:')
+ self.writeline('if parent_template is not None:')
self.indent()
self.writeline('raise TemplateRuntimeError(%r)' %
'extended multiple times')
@@ -576,9 +572,15 @@
raise CompilerExit()
self.outdent()
- self.writeline('parent_root = environment.get_template(', node, 1)
+ self.writeline('parent_template = environment.get_template(', node, 1)
self.visit(node.template, frame)
- self.write(', %r).root_render_func' % self.name)
+ self.write(', %r)' % self.name)
+ self.writeline('for name, parent_block in parent_template.'
+ 'blocks.iteritems():')
+ self.indent()
+ self.writeline('context.blocks.setdefault(name, []).'
+ 'insert(0, parent_block)')
+ self.outdent()
# if this extends statement was in the root level we can take
# advantage of that information and simplify the generated code
@@ -601,11 +603,17 @@
self.write(')')
return
- self.writeline('included_stream = environment.get_template(', node)
+ self.writeline('included_template = environment.get_template(', node)
self.visit(node.template, frame)
- self.write(').root_render_func(context, standalone=True)')
- self.writeline('included_context = included_stream.next()')
- self.writeline('for event in included_stream:')
+ self.write(')')
+ if frame.toplevel:
+ self.writeline('included_context = included_template.new_context('
+ 'context.get_root())')
+ self.writeline('for event in included_template.root_render_func('
+ 'included_context):')
+ else:
+ self.writeline('for event in included_template.root_render_func('
+ 'included_template.new_context(context.get_root())):')
self.indent()
if frame.buffer is None:
self.writeline('yield event')
@@ -796,7 +804,7 @@
# so that they don't appear in the output.
outdent_later = False
if frame.toplevel and self.extends_so_far != 0:
- self.writeline('if parent_root is None:')
+ self.writeline('if parent_template is None:')
self.indent()
outdent_later = True