basic inheritance works now
authorArmin Ronacher <armin.ronacher@active-4.com>
Fri, 11 Apr 2008 17:55:08 +0000 (19:55 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Fri, 11 Apr 2008 17:55:08 +0000 (19:55 +0200)
--HG--
branch : trunk

jinja2/compiler.py
jinja2/loaders.py
jinja2/runtime.py
test.py

index 3d4c655f3b1ecdd4a1d9c8a02438352811cf5d02..74cd0a52774b27a1008b9379cd3cc6c86a30d0cb 100644 (file)
@@ -340,17 +340,20 @@ class CodeGenerator(NodeVisitor):
 
     def visit_Block(self, node, frame):
         """Call a block and register it for the template."""
+        level = 1
         if frame.toplevel:
             # if we know that we are a child template, there is no need to
             # check if we are one
             if self.has_known_extends:
                 return
-            self.writeline('if parent_root is None:')
-            self.indent()
-        self.writeline('for event in context.blocks[0][%r](context):' % node.name)
+            if self.extends_so_far > 0:
+                self.writeline('if parent_root is None:')
+                self.indent()
+                level += 1
+        self.writeline('for event in context.blocks[%r][-1](context):' % node.name)
         self.indent()
         self.writeline('yield event')
-        self.outdent(1 + frame.toplevel)
+        self.outdent(level)
 
     def visit_Extends(self, node, frame):
         """Calls the extender."""
@@ -380,9 +383,9 @@ class CodeGenerator(NodeVisitor):
                 raise CompilerExit()
             self.outdent()
 
-        self.writeline('parent_root = extends(', node, 1)
+        self.writeline('parent_root = environment.get_template(', node, 1)
         self.visit(node.template, frame)
-        self.write(', context, environment)')
+        self.write(', %r).root_render_func' % self.filename)
 
         # if this extends statement was in the root level we can take
         # advantage of that information and simplify the generated code
index 95edfbc1299c8ecbd4337f9e4d8c5c07547bb07f..97e51d6a2c9d2d9ad7a1c280d2f9342cef00c3c6 100644 (file)
@@ -46,3 +46,14 @@ class FileSystemLoader(BaseLoader):
             return f.read().decode(self.encoding)
         finally:
             f.close()
+
+
+class DictLoader(BaseLoader):
+
+    def __init__(self, mapping):
+        self.mapping = mapping
+
+    def get_source(self, environment, template):
+        if template in self.mapping:
+            return self.mapping[template], template
+        raise TemplateNotFound(template)
index 82acd6cd98afb2a78f0569f64d25d0f8349317e8..27dab9f9777d78da77f6d5960d7503ba40aa9040 100644 (file)
@@ -14,18 +14,10 @@ except ImportError:
     defaultdict = None
 
 
-__all__ = ['extends', 'subscribe', 'LoopContext', 'StaticLoopContext',
+__all__ = ['subscribe', 'LoopContext', 'StaticLoopContext',
            'TemplateContext', 'Macro', 'Undefined']
 
 
-def extends(template_name, context, environment):
-    """This loads a template (and evaluates it) and replaces the blocks."""
-    template = environment.get_template(template_name, context.filename)
-    for name, block in template.blocks.iteritems():
-        context.blocks.setdefault(name, []).append(block)
-    return template.root_render_func
-
-
 def subscribe(obj, argument):
     """Get an item or attribute of an object."""
     try:
@@ -58,7 +50,9 @@ class TemplateContext(dict):
         self.exported = set()
         self.filename = filename
         self.blocks = dict((k, [v]) for k, v in blocks.iteritems())
-        self.stream_muted = False
+        if isinstance(globals, TemplateContext):
+            for name, parent_blocks in globals.blocks.iteritems():
+                self.blocks.setdefault(name, []).extend(parent_blocks)
 
     def __setitem__(self, key, value):
         """If we set items to the dict we track the variables set so
diff --git a/test.py b/test.py
index fcdf0503d3130d9e260b8042c1e686feecda6c2e..549efe8fa7d907e3976e48fe329988b92bd5d10d 100644 (file)
--- a/test.py
+++ b/test.py
@@ -1,27 +1,21 @@
 from jinja2 import Environment
+from jinja2.loaders import DictLoader
 
-env = Environment()
-tmpl = env.from_string("""<!doctype html>
-<html>
-  <head>
-    <title>{{ page_title|e }}</title>
-  </head>
-  <body>
-    <ul class="navigation">
-    {%- for href, caption in [
-        ('index.html', 'Index'),
-        ('projects.html', 'Projects'),
-        ('about.html', 'About')
-    ] %}
-      <li><a href="{{ href|e }}">{{ caption|e }}</a></li>
-    {%- endfor %}
-    </ul>
-    <div class="body">
-      {{ body }}
-    </div>
-  </body>
-</html>\
-""")
+env = Environment(loader=DictLoader({
+'child.html': u'''\
+{% extends master_layout or 'master.html' %}
+{% macro get_the_answer() %}42{% endmacro %}
+{% block body %}
+    {{ get_the_answer() }}
+{% endblock %}
+''',
+'master.html': u'''\
+<!doctype html>
+<title>Foo</title>
+{% block body %}{% endblock %}
+'''
+}))
 
 
-print tmpl.render(page_title='<foo>', body='<p>Hello World</p>')
+tmpl = env.get_template("child.html")
+print tmpl.render()