diff options
| -rw-r--r-- | django/template/defaulttags.py | 55 | ||||
| -rw-r--r-- | tests/regressiontests/templates/tests.py | 9 |
2 files changed, 33 insertions, 31 deletions
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 091130956d..14f6532645 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -39,7 +39,7 @@ class CommentNode(Node): class CycleNode(Node): def __init__(self, cyclevars, variable_name=None): - self.cycle_iter = itertools_cycle([Variable(v) for v in cyclevars]) + self.cycle_iter = itertools_cycle(cyclevars) self.variable_name = variable_name def render(self, context): @@ -70,14 +70,11 @@ class FilterNode(Node): class FirstOfNode(Node): def __init__(self, vars): - self.vars = map(Variable, vars) + self.vars = vars def render(self, context): for var in self.vars: - try: - value = var.resolve(context) - except VariableDoesNotExist: - continue + value = var.resolve(context) if value: return smart_unicode(value) return u'' @@ -169,7 +166,7 @@ class IfChangedNode(Node): def __init__(self, nodelist_true, nodelist_false, *varlist): self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false self._last_seen = None - self._varlist = map(Variable, varlist) + self._varlist = varlist self._id = str(id(self)) def render(self, context): @@ -180,7 +177,7 @@ class IfChangedNode(Node): if self._varlist: # Consider multiple parameters. This automatically behaves # like an OR evaluation of the multiple variables. - compare_to = [var.resolve(context) for var in self._varlist] + compare_to = [var.resolve(context, True) for var in self._varlist] else: compare_to = self.nodelist_true.render(context) except VariableDoesNotExist: @@ -200,7 +197,7 @@ class IfChangedNode(Node): class IfEqualNode(Node): def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): - self.var1, self.var2 = Variable(var1), Variable(var2) + self.var1, self.var2 = var1, var2 self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false self.negate = negate @@ -208,14 +205,8 @@ class IfEqualNode(Node): return "<IfEqualNode>" def render(self, context): - try: - val1 = self.var1.resolve(context) - except VariableDoesNotExist: - val1 = None - try: - val2 = self.var2.resolve(context) - except VariableDoesNotExist: - val2 = None + val1 = self.var1.resolve(context, True) + val2 = self.var2.resolve(context, True) if (self.negate and val1 != val2) or (not self.negate and val1 == val2): return self.nodelist_true.render(context) return self.nodelist_false.render(context) @@ -371,11 +362,10 @@ class URLNode(Node): args = [arg.resolve(context) for arg in self.args] kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) - - + # Try to look up the URL twice: once given the view name, and again - # relative to what we guess is the "main" app. If they both fail, - # re-raise the NoReverseMatch unless we're using the + # relative to what we guess is the "main" app. If they both fail, + # re-raise the NoReverseMatch unless we're using the # {% url ... as var %} construct in which cause return nothing. url = '' try: @@ -388,7 +378,7 @@ class URLNode(Node): except NoReverseMatch: if self.asvar is None: raise - + if self.asvar: context[self.asvar] = url return '' @@ -514,12 +504,14 @@ def cycle(parser, token): if len(args) > 4 and args[-2] == 'as': name = args[-1] - node = CycleNode(args[1:-2], name) + values = [parser.compile_filter(arg) for arg in args[1:-2]] + node = CycleNode(values, name) if not hasattr(parser, '_namedCycleNodes'): parser._namedCycleNodes = {} parser._namedCycleNodes[name] = node else: - node = CycleNode(args[1:]) + values = [parser.compile_filter(arg) for arg in args[1:]] + node = CycleNode(values) return node cycle = register.tag(cycle) @@ -594,7 +586,7 @@ def firstof(parser, token): if len(bits) < 1: raise TemplateSyntaxError("'firstof' statement requires at least one" " argument") - return FirstOfNode(bits) + return FirstOfNode([parser.compile_filter(bit) for bit in bits]) firstof = register.tag(firstof) #@register.tag(name="for") @@ -629,10 +621,10 @@ def do_for(parser, token): <li>Sorry, no athletes in this list.</li> {% endfor %} <ul> - + The above is equivalent to -- but shorter, cleaner, and possibly faster than -- the following:: - + <ul> {% if althete_list %} {% for athlete in athlete_list %} @@ -701,7 +693,9 @@ def do_ifequal(parser, token, negate): parser.delete_first_token() else: nodelist_false = NodeList() - return IfEqualNode(bits[1], bits[2], nodelist_true, nodelist_false, negate) + val1 = parser.compile_filter(bits[1]) + val2 = parser.compile_filter(bits[2]) + return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate) #@register.tag def ifequal(parser, token): @@ -864,7 +858,8 @@ def ifchanged(parser, token): parser.delete_first_token() else: nodelist_false = NodeList() - return IfChangedNode(nodelist_true, nodelist_false, *bits[1:]) + values = [parser.compile_filter(bit) for bit in bits[1:]] + return IfChangedNode(nodelist_true, nodelist_false, *values) ifchanged = register.tag(ifchanged) #@register.tag @@ -1105,7 +1100,7 @@ def url(parser, token): args = [] kwargs = {} asvar = None - + if len(bits) > 2: bits = iter(bits[2:]) for bit in bits: diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 7bb37b9fd0..2211ac77be 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -424,13 +424,13 @@ class Templates(unittest.TestCase): 'cycle07': ('{% cycle a,b,c as foo %}{% cycle bar %}', {}, template.TemplateSyntaxError), 'cycle08': ('{% cycle a,b,c as foo %}{% cycle foo %}{{ foo }}{{ foo }}{% cycle foo %}{{ foo }}', {}, 'abbbcc'), 'cycle09': ("{% for i in test %}{% cycle a,b %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), - # New format: 'cycle10': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}", {}, 'ab'), 'cycle11': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}", {}, 'abc'), 'cycle12': ("{% cycle 'a' 'b' 'c' as abc %}{% cycle abc %}{% cycle abc %}{% cycle abc %}", {}, 'abca'), 'cycle13': ("{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), 'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'), 'cycle15': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'), + 'cycle16': ("{% cycle one|lower two as foo %}{% cycle foo %}", {'one': 'A','two': '2'}, 'a2'), ### EXCEPTIONS ############################################################ @@ -638,6 +638,13 @@ class Templates(unittest.TestCase): 'ifequal-numeric11': ('{% ifequal x -5.2 %}yes{% endifequal %}', {'x': -5.2}, 'yes'), 'ifequal-numeric12': ('{% ifequal x +5 %}yes{% endifequal %}', {'x': 5}, 'yes'), + # FILTER EXPRESSIONS AS ARGUMENTS + 'ifequal-filter01': ('{% ifequal a|upper "A" %}x{% endifequal %}', {'a': 'a'}, 'x'), + 'ifequal-filter02': ('{% ifequal "A" a|upper %}x{% endifequal %}', {'a': 'a'}, 'x'), + 'ifequal-filter03': ('{% ifequal a|upper b|upper %}x{% endifequal %}', {'a': 'x', 'b': 'X'}, 'x'), + 'ifequal-filter04': ('{% ifequal x|slice:"1" "a" %}x{% endifequal %}', {'x': 'aaa'}, 'x'), + 'ifequal-filter05': ('{% ifequal x|slice:"1"|upper "A" %}x{% endifequal %}', {'x': 'aaa'}, 'x'), + ### IFNOTEQUAL TAG ######################################################## 'ifnotequal01': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 2}, "yes"), 'ifnotequal02': ("{% ifnotequal a b %}yes{% endifnotequal %}", {"a": 1, "b": 1}, ""), |
