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