From: Armin Ronacher Date: Fri, 11 Apr 2008 17:55:08 +0000 (+0200) Subject: basic inheritance works now X-Git-Tag: 2.0rc1~183 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=41ef36f4d9f3b066d95dae4aae649e3c8178b7a4;p=jinja2.git basic inheritance works now --HG-- branch : trunk --- diff --git a/jinja2/compiler.py b/jinja2/compiler.py index 3d4c655..74cd0a5 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -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 diff --git a/jinja2/loaders.py b/jinja2/loaders.py index 95edfbc..97e51d6 100644 --- a/jinja2/loaders.py +++ b/jinja2/loaders.py @@ -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) diff --git a/jinja2/runtime.py b/jinja2/runtime.py index 82acd6c..27dab9f 100644 --- a/jinja2/runtime.py +++ b/jinja2/runtime.py @@ -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 fcdf050..549efe8 100644 --- 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(""" - - - {{ page_title|e }} - - - -
- {{ body }} -
- -\ -""") +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'''\ + +Foo +{% block body %}{% endblock %} +''' +})) -print tmpl.render(page_title='', body='

Hello World

') +tmpl = env.get_template("child.html") +print tmpl.render()