summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/cache_extension.py6
-rw-r--r--docs/extensions.rst2
-rwxr-xr-xjinja2-debug.py39
-rw-r--r--jinja2/compiler.py3
-rw-r--r--jinja2/environment.py4
-rw-r--r--jinja2/ext.py11
6 files changed, 58 insertions, 7 deletions
diff --git a/docs/cache_extension.py b/docs/cache_extension.py
index c9ed92c..9f324d2 100644
--- a/docs/cache_extension.py
+++ b/docs/cache_extension.py
@@ -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."""
diff --git a/docs/extensions.rst b/docs/extensions.rst
index 13fe639..f5527f7 100644
--- a/docs/extensions.rst
+++ b/docs/extensions.rst
@@ -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
index 0000000..1e90242
--- /dev/null
+++ b/jinja2-debug.py
@@ -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()
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 6518427..7b8366c 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -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
diff --git a/jinja2/environment.py b/jinja2/environment.py
index 2fbe217..e104090 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -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
diff --git a/jinja2/ext.py b/jinja2/ext.py
index f60b85a..53b4041 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -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."""