switched back to explicit set for assignments. {% foo = 42 %} becomes {% set foo...
authorArmin Ronacher <armin.ronacher@active-4.com>
Mon, 12 May 2008 23:03:08 +0000 (01:03 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Mon, 12 May 2008 23:03:08 +0000 (01:03 +0200)
--HG--
branch : trunk

TODO
docs/_templates/genindex.html
docs/_templates/search.html
jinja2/compiler.py
jinja2/defaults.py
jinja2/parser.py
tests/test_macros.py
tests/test_various.py

diff --git a/TODO b/TODO
index 6881b76d7d1e6541a339bba185c08b885e6d88bd..2a022f424f3096bcae4b51f4a54a73697ad5ccca 100644 (file)
--- a/TODO
+++ b/TODO
@@ -48,10 +48,3 @@ unlike locals and filters/tests which are always pulled.  We're not doing that
 for filters/tests/locals as nested scopes may access it and testing is too
 complicated for the tiny performance improvement but easy for attribute
 lookups, keeping the complexity of the whole thing in mind.
-
-Use `set` for Assignments
--------------------------
-
-The keyword-less way to assign variabeles is a left-over from the days when
-it was possible to use Jinja2 like a regular programming language without
-necessary template end/start delimiters to group statements.
index e31a578d906aabb967c904a73c8b9a361ce7b234..9add6e952d48db83af1b0aaffd2260c41f5e0e34 100644 (file)
@@ -1,5 +1,5 @@
 {% extends "layout.html" %}
-{% title = 'Index' %}
+{% set title = 'Index' %}
 {% block body %}
 
   <h1 id="index">Index</h1>
index ab93b75c2ac6a1de01e603e7daf7db278ebd0c6f..0c942b70fcc63c58622f9a4d6e976ad7f9b545fb 100644 (file)
@@ -1,5 +1,5 @@
 {% extends "layout.html" %}
-{% title = 'Search' %}
+{% set title = 'Search' %}
 {% block extrahead %}
     <script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
 {% endblock %}
index cb0da5a1f030408fa4329a3097516a2dfd04a087..4c250b5be742148b739ec5e597c5d984a1443063 100644 (file)
@@ -787,9 +787,9 @@ class CodeGenerator(NodeVisitor):
             self.indent()
             self.writeline('l_%s = environment.undefined(%r %% '
                            'included_template.name, '
-                           'name=included_template.name)' %
+                           'name=%r)' %
                            (alias, 'the template %r does not export '
-                            'the requested name ' + repr(name)))
+                            'the requested name ' + repr(name), name))
             self.outdent()
             if frame.toplevel:
                 self.writeline('context.vars[%r] = l_%s' % (alias, alias))
index e12493076df6ea6c213272fd9bfd6d158b4b5c35..62dfda22542bdd8a837bc76392b033417cfde516 100644 (file)
@@ -25,7 +25,8 @@ LINE_STATEMENT_PREFIX = None
 DEFAULT_NAMESPACE = {
     'range':        xrange,
     'dict':         lambda **kw: kw,
-    'lipsum':       generate_lorem_ipsum
+    'lipsum':       generate_lorem_ipsum,
+    'void':         lambda *a: u''
 }
 
 
index 941e037c2003a02633a97180b1998ad16172e7ee..f2a129c0abdcc00d0dc43c0f3b3fd8b7f761ca60 100644 (file)
@@ -13,7 +13,8 @@ from jinja2.exceptions import TemplateSyntaxError
 
 
 _statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print',
-                                 'macro', 'include', 'from', 'import'])
+                                 'macro', 'include', 'from', 'import',
+                                 'set'])
 _compare_operators = frozenset(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq'])
 
 
@@ -53,36 +54,21 @@ class Parser(object):
 
     def parse_statement(self):
         """Parse a single statement."""
-        token_type = self.stream.current.type
-        if self.stream.current.type is 'name':
-            if self.stream.current.value in _statement_keywords:
-                return getattr(self, 'parse_' + self.stream.current.value)()
-            elif self.stream.current.value == 'call':
-                return self.parse_call_block()
-            elif self.stream.current.value == 'filter':
-                return self.parse_filter_block()
-            else:
-                ext = self.extensions.get(self.stream.current.value)
-                if ext is not None:
-                    return ext(self)
-        lineno = self.stream.current.lineno
-        expr = self.parse_tuple()
-        if self.stream.current.type == 'assign':
-            result = self.parse_assign(expr)
-        else:
-            result = nodes.ExprStmt(expr, lineno=lineno)
-        return result
-
-    def parse_assign(self, target):
-        """Parse an assign statement."""
-        lineno = self.stream.expect('assign').lineno
-        if not target.can_assign():
-            raise TemplateSyntaxError("can't assign to '%s'" %
-                                      target.__class__.__name__.lower(),
-                                      target.lineno, self.filename)
-        expr = self.parse_tuple()
-        target.set_ctx('store')
-        return nodes.Assign(target, expr, lineno=lineno)
+        token = self.stream.current
+        if token.type is not 'name':
+            raise TemplateSyntaxError('tag name expected', token.lineno,
+                                      self.filename)
+        if token.value in _statement_keywords:
+            return getattr(self, 'parse_' + self.stream.current.value)()
+        if token.value == 'call':
+            return self.parse_call_block()
+        if token.value == 'filter':
+            return self.parse_filter_block()
+        ext = self.extensions.get(token.value)
+        if ext is not None:
+            return ext(self)
+        raise TemplateSyntaxError('unknown tag %r' % token.value,
+                                  token.lineno, self.filename)
 
     def parse_statements(self, end_tokens, drop_needle=False):
         """Parse multiple statements into a list until one of the end tokens
@@ -106,6 +92,14 @@ class Parser(object):
             self.stream.next()
         return result
 
+    def parse_set(self):
+        """Parse an assign statement."""
+        lineno = self.stream.next().lineno
+        target = self.parse_assign_target()
+        self.stream.expect('assign')
+        expr = self.parse_tuple()
+        return nodes.Assign(target, expr, lineno=lineno)
+
     def parse_for(self):
         """Parse a for loop."""
         lineno = self.stream.expect('name:for').lineno
index 74594d3754299da2eaab67d12e6ce901d45a9b52..5958250e8da0b4019e47ba609046063f22ef892b 100644 (file)
@@ -40,7 +40,7 @@ COMPLEXCALL = '''\
 '''
 
 CALLERUNDEFINED = '''\
-{% caller = 42 %}\
+{% set caller = 42 %}\
 {% macro test() %}{{ caller is not defined }}{% endmacro %}\
 {{ test() }}\
 '''
index 37082ba2f03e786708725243b7b0cf871b9d1a19..9235a29629f282b04c4dacc3e729d60e466c41c8 100644 (file)
@@ -13,10 +13,10 @@ UNPACKING = '''{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor
 RAW = '''{% raw %}{{ FOO }} and {% BAR %}{% endraw %}'''
 CONST = '''{{ true }}|{{ false }}|{{ none }}|\
 {{ none is defined }}|{{ missing is defined }}'''
-LOCALSET = '''{% foo = 0 %}\
-{% for item in [1, 2] %}{% foo = 1 %}{% endfor %}\
+LOCALSET = '''{% set foo = 0 %}\
+{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\
 {{ foo }}'''
-CONSTASS1 = '''{% true = 42 %}'''
+CONSTASS1 = '''{% set true = 42 %}'''
 CONSTASS2 = '''{% for none in seq %}{% endfor %}'''