summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2010-04-12 14:04:14 +0200
committerArmin Ronacher <armin.ronacher@active-4.com>2010-04-12 14:04:14 +0200
commit5b3f4dcca20184f9edad5e47fee35b25d5c2a5be (patch)
tree30d9c7dd05937ce077e697e0f261b0c3a13a2300
parent4855908121db1f033740c830747d050f8f8a7c51 (diff)
downloadjinja2-5b3f4dcca20184f9edad5e47fee35b25d5c2a5be.tar.gz
Added extension ordering, this fixes #376.
--HG-- branch : trunk
-rw-r--r--jinja2/environment.py9
-rw-r--r--jinja2/ext.py7
-rw-r--r--jinja2/parser.py2
-rw-r--r--jinja2/testsuite/ext.py10
4 files changed, 25 insertions, 3 deletions
diff --git a/jinja2/environment.py b/jinja2/environment.py
index 25cec88..529c14c 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -334,6 +334,11 @@ class Environment(object):
lexer = property(get_lexer, doc="The lexer for this environment.")
+ def iter_extensions(self):
+ """Iterates over the extensions by priority."""
+ return iter(sorted(self.extensions.values(),
+ key=lambda x: x.priority))
+
def getitem(self, obj, argument):
"""Get an item or attribute of an object but prefer the item."""
try:
@@ -407,7 +412,7 @@ class Environment(object):
because there you usually only want the actual source tokenized.
"""
return reduce(lambda s, e: e.preprocess(s, name, filename),
- self.extensions.itervalues(), unicode(source))
+ self.iter_extensions(), unicode(source))
def _tokenize(self, source, name, filename=None, state=None):
"""Called by the parser to do the preprocessing and filtering
@@ -415,7 +420,7 @@ class Environment(object):
"""
source = self.preprocess(source, name, filename)
stream = self.lexer.tokenize(source, name, filename, state)
- for ext in self.extensions.itervalues():
+ for ext in self.iter_extensions():
stream = ext.filter_stream(stream)
if not isinstance(stream, TokenStream):
stream = TokenStream(stream, name, filename)
diff --git a/jinja2/ext.py b/jinja2/ext.py
index 64d5525..63ce408 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -57,6 +57,13 @@ class Extension(object):
#: if this extension parses this is the list of tags it's listening to.
tags = set()
+ #: the priority of that extension. This is especially useful for
+ #: extensions that preprocess values. A lower value means higher
+ #: priority.
+ #:
+ #: .. versionadded:: 2.4
+ priority = 100
+
def __init__(self, environment):
self.environment = environment
diff --git a/jinja2/parser.py b/jinja2/parser.py
index 1f5e12a..9814c93 100644
--- a/jinja2/parser.py
+++ b/jinja2/parser.py
@@ -34,7 +34,7 @@ class Parser(object):
self.filename = filename
self.closed = False
self.extensions = {}
- for extension in environment.extensions.itervalues():
+ for extension in environment.iter_extensions():
for tag in extension.tags:
self.extensions[tag] = extension.parse
self._last_identifier = 0
diff --git a/jinja2/testsuite/ext.py b/jinja2/testsuite/ext.py
index ac273b9..c00c589 100644
--- a/jinja2/testsuite/ext.py
+++ b/jinja2/testsuite/ext.py
@@ -204,6 +204,16 @@ class ExtensionsTestCase(JinjaTestCase):
out = tmpl.render()
assert out == 'Foo BAR Baz'
+ def test_extension_ordering(self):
+ class T1(Extension):
+ priority = 1
+ class T2(Extension):
+ priority = 2
+ env = Environment(extensions=[T1, T2])
+ ext = list(env.iter_extensions())
+ assert ext[0].__class__ is T1
+ assert ext[1].__class__ is T2
+
class InternationalizationTestCase(JinjaTestCase):