fixed a bug in extension handling
authorArmin Ronacher <armin.ronacher@active-4.com>
Sun, 11 May 2008 17:48:12 +0000 (19:48 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Sun, 11 May 2008 17:48:12 +0000 (19:48 +0200)
--HG--
branch : trunk

docs/cache_extension.py
docs/extensions.rst
jinja2-debug.py [new file with mode: 0755]
jinja2/compiler.py
jinja2/environment.py
jinja2/ext.py

index c9ed92c837dfeaafd0d3b3e15e37180a1109921c..9f324d2cb94bd7739cca1672b5641745150f66b5 100644 (file)
@@ -38,10 +38,8 @@ class FragmentCacheExtension(Extension):
 
         # now return a `CallBlock` node that calls our _cache_support
         # helper method on this extension.
-        return nodes.CallBlock(
-            nodes.Call(self.attr('_cache_support'), args, [], None, None),
-            [], [], body
-        ).set_lineno(lineno)
+        return nodes.CallBlock(self.call_method('_cache_support', args),
+                               [], [], body).set_lineno(lineno)
 
     def _cache_support(self, name, timeout, caller):
         """Helper callback."""
index 13fe639ebcd29615475288ee1824e0ba66af808e..f5527f7c1156988a2ad877beaa69f011ab7160b4 100644 (file)
@@ -134,7 +134,7 @@ Extension API
 Extensions always have to extend the :class:`jinja2.ext.Extension` class:
 
 .. autoclass:: Extension
-    :members: parse, attr
+    :members: parse, attr, call_method
 
     .. attribute:: identifier
 
diff --git a/jinja2-debug.py b/jinja2-debug.py
new file mode 100755 (executable)
index 0000000..1e90242
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    Jinja2 Debug Interface
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Helper script for internal Jinja2 debugging.  Requires Werkzeug.
+
+    :copyright: Copyright 2008 by Armin Ronacher.
+    :license: BSD.
+"""
+import sys
+import jinja2
+from werkzeug import script
+
+env = jinja2.Environment()
+
+def shell_init_func():
+    def _compile(x):
+        print env.compile(x, raw=True)
+    result = {
+        'e':        env,
+        'c':        _compile,
+        't':        env.from_string,
+        'p':        env.parse
+    }
+    for key in jinja2.__all__:
+        result[key] = getattr(jinja2, key)
+    return result
+
+
+def action_compile():
+    print env.compile(sys.stdin.read(), raw=True)
+
+action_shell = script.make_shell(shell_init_func)
+
+
+if __name__ == '__main__':
+    script.run()
index 6518427d2fddcdf1142d0cba7e92a21720f3a4d6..7b8366cd8f6da813b50bc76e3665ce57991ce343 100644 (file)
@@ -719,7 +719,8 @@ class CodeGenerator(NodeVisitor):
         # if this extends statement was in the root level we can take
         # advantage of that information and simplify the generated code
         # in the top level from this point onwards
-        self.has_known_extends = True
+        if frame.rootlevel:
+            self.has_known_extends = True
 
         # and now we have one more
         self.extends_so_far += 1
index 2fbe217b8dd844adc4fea2039e6c7448f899034e..e1040900aacb15c9761f8f95ed0b198acd7e4a5a 100644 (file)
@@ -15,7 +15,6 @@ from jinja2.parser import Parser
 from jinja2.optimizer import optimize
 from jinja2.compiler import generate
 from jinja2.runtime import Undefined, Context
-from jinja2.debug import translate_exception, translate_syntax_error
 from jinja2.exceptions import TemplateSyntaxError
 from jinja2.utils import import_string, LRUCache, Markup, missing, concat
 
@@ -299,6 +298,7 @@ class Environment(object):
         try:
             return Parser(self, source, filename).parse()
         except TemplateSyntaxError, e:
+            from jinja2.debug import translate_syntax_error
             exc_type, exc_value, tb = translate_syntax_error(e)
             raise exc_type, exc_value, tb
 
@@ -486,6 +486,7 @@ class Template(object):
         try:
             return concat(self._generate(*args, **kwargs))
         except:
+            from jinja2.debug import translate_exception
             exc_type, exc_value, tb = translate_exception(sys.exc_info())
             raise exc_type, exc_value, tb
 
@@ -507,6 +508,7 @@ class Template(object):
             for item in self._generate(*args, **kwargs):
                 yield item
         except:
+            from jinja2.debug import translate_exception
             exc_type, exc_value, tb = translate_exception(sys.exc_info())
             raise exc_type, exc_value, tb
 
index f60b85a17d28f69e54276ee1ea0d0cee6c20e8df..53b4041ce03a619fac30ffadd71a6cd8d14ba82a 100644 (file)
@@ -73,6 +73,7 @@ class Extension(object):
         is the name token that matched.  This method has to return one or a
         list of multiple nodes.
         """
+        raise NotImplementedError()
 
     def attr(self, name, lineno=None):
         """Return an attribute node for the current extension.  This is useful
@@ -84,6 +85,16 @@ class Extension(object):
         """
         return nodes.ExtensionAttribute(self.identifier, name, lineno=lineno)
 
+    def call_method(self, name, args=None, kwargs=None, dyn_args=None,
+                    dyn_kwargs=None, lineno=None):
+        """Call a method of the extension."""
+        if args is None:
+            args = []
+        if kwargs is None:
+            kwargs = []
+        return nodes.Call(self.attr(name, lineno=lineno), args, kwargs,
+                          dyn_args, dyn_kwargs, lineno=lineno)
+
 
 class InternationalizationExtension(Extension):
     """This extension adds gettext support to Jinja2."""