From 4b408e5f90bd69a27ab93bce299cbe0c55f13ff4 Mon Sep 17 00:00:00 2001 From: Mike Bayer <mike_mp@zzzcomputing.com> Date: Wed, 30 Jun 2010 14:47:56 -0400 Subject: [PATCH] - The <%namespace> tag allows expressions for the `file` argument, i.e. with ${}. The `context` variable, if needed, must be referenced explicitly. [ticket:141] - Fixed previously non-covered regular expression, such that using a ${} expression inside of a tag element that doesn't allow them raises a CompileException instead of silently failing. --- CHANGES | 13 +++++++++++++ doc/build/content/namespaces.txt | 4 ++++ mako/parsetree.py | 6 +++--- test/test_lexer.py | 8 +++++++- test/test_namespace.py | 20 +++++++++++++++++++- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index e02b147..18289c4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +0.3.5 +- The <%namespace> tag allows expressions + for the `file` argument, i.e. with ${}. + The `context` variable, if needed, + must be referenced explicitly. + [ticket:141] + +- Fixed previously non-covered regular + expression, such that using a ${} expression + inside of a tag element that doesn't allow + them raises a CompileException instead of + silently failing. + 0.3.4 - Now using MarkupSafe for HTML escaping, i.e. in place of cgi.escape(). Faster diff --git a/doc/build/content/namespaces.txt b/doc/build/content/namespaces.txt index 46f2e95..f691e31 100644 --- a/doc/build/content/namespaces.txt +++ b/doc/build/content/namespaces.txt @@ -42,6 +42,10 @@ The names imported by the `import` attribute take precedence over any names that **Note** - in current versions of Mako, usage of "import='*'" is known to decrease performance of the template. This will be fixed in a future release. +The `file` argument allows expressions - if looking for context variables, the `context` must be named explicitly: + + <%namespace name="dyn" file="${context['namespace_name']}"/> + ### Ways to Call Namespaces {@name=howtocall} There are essentially four ways to call a function from a namespace. diff --git a/mako/parsetree.py b/mako/parsetree.py index 3a273ac..577b18c 100644 --- a/mako/parsetree.py +++ b/mako/parsetree.py @@ -281,7 +281,7 @@ class Tag(Node): expr.append(repr(x)) self.parsed_attributes[key] = " + ".join(expr) or repr('') elif key in nonexpressions: - if re.search(r'${.+?}', self.attributes[key]): + if re.search(r'\${.+?}', self.attributes[key]): raise exceptions.CompileException( "Attibute '%s' in tag '%s' does not allow embedded " "expressions" % (key, self.keyword), @@ -334,9 +334,9 @@ class NamespaceTag(Tag): def __init__(self, keyword, attributes, **kwargs): super(NamespaceTag, self).__init__( keyword, attributes, - (), + ('file',), ('name','inheritable', - 'file','import','module'), + 'import','module'), (), **kwargs) self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self)))) diff --git a/test/test_lexer.py b/test/test_lexer.py index 2f6a61c..a3cc11e 100644 --- a/test/test_lexer.py +++ b/test/test_lexer.py @@ -78,7 +78,13 @@ class LexerTest(TemplateTest): hi. """ self.assertRaises(exceptions.SyntaxException, Lexer(template).parse) - + + def test_noexpr_allowed(self): + template = """ + <%namespace name="${foo}"/> + """ + self.assertRaises(exceptions.CompileException, Lexer(template).parse) + def test_unmatched_tag(self): template = """ <%namespace name="bar"> diff --git a/test/test_namespace.py b/test/test_namespace.py index 1600ca9..5e0d7a0 100644 --- a/test/test_namespace.py +++ b/test/test_namespace.py @@ -1,7 +1,7 @@ from mako.template import Template from mako import lookup from util import flatten_result, result_lines -from test import TemplateTest +from test import TemplateTest, eq_ class NamespaceTest(TemplateTest): def test_inline_crossreference(self): @@ -81,6 +81,24 @@ class NamespaceTest(TemplateTest): filters=flatten_result ) + def test_dynamic(self): + collection = lookup.TemplateLookup() + + collection.put_string('a', """ + <%namespace name="b" file="${context['b_def']}"/> + + a. b: ${b.body()} +""") + + collection.put_string('b', """ + b. +""") + + eq_( + flatten_result(collection.get_template('a').render(b_def='b')), + "a. b: b." + ) + def test_template(self): collection = lookup.TemplateLookup() -- GitLab