mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #4534 -- Added an "else" option to the "ifchanged" template tag.
Patch from SmileyChris. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8095 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -157,8 +157,8 @@ class ForNode(Node): | ||||
|         return nodelist.render(context) | ||||
|  | ||||
| class IfChangedNode(Node): | ||||
|     def __init__(self, nodelist, *varlist): | ||||
|         self.nodelist = nodelist | ||||
|     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._id = str(id(self)) | ||||
| @@ -173,20 +173,21 @@ class IfChangedNode(Node): | ||||
|                 # like an OR evaluation of the multiple variables. | ||||
|                 compare_to = [var.resolve(context) for var in self._varlist] | ||||
|             else: | ||||
|                 compare_to = self.nodelist.render(context) | ||||
|                 compare_to = self.nodelist_true.render(context) | ||||
|         except VariableDoesNotExist: | ||||
|             compare_to = None | ||||
|  | ||||
|         if  compare_to != self._last_seen: | ||||
|         if compare_to != self._last_seen: | ||||
|             firstloop = (self._last_seen == None) | ||||
|             self._last_seen = compare_to | ||||
|             context.push() | ||||
|             context['ifchanged'] = {'firstloop': firstloop} | ||||
|             content = self.nodelist.render(context) | ||||
|             content = self.nodelist_true.render(context) | ||||
|             context.pop() | ||||
|             return content | ||||
|         else: | ||||
|             return '' | ||||
|         elif self.nodelist_false: | ||||
|             return self.nodelist_false.render(context) | ||||
|         return '' | ||||
|  | ||||
| class IfEqualNode(Node): | ||||
|     def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): | ||||
| @@ -803,9 +804,14 @@ def ifchanged(parser, token): | ||||
|             {% endfor %} | ||||
|     """ | ||||
|     bits = token.contents.split() | ||||
|     nodelist = parser.parse(('endifchanged',)) | ||||
|     parser.delete_first_token() | ||||
|     return IfChangedNode(nodelist, *bits[1:]) | ||||
|     nodelist_true = parser.parse(('else', 'endifchanged')) | ||||
|     token = parser.next_token() | ||||
|     if token.contents == 'else': | ||||
|         nodelist_false = parser.parse(('endifchanged',)) | ||||
|         parser.delete_first_token() | ||||
|     else: | ||||
|         nodelist_false = NodeList() | ||||
|     return IfChangedNode(nodelist_true, nodelist_false, *bits[1:]) | ||||
| ifchanged = register.tag(ifchanged) | ||||
|  | ||||
| #@register.tag | ||||
|   | ||||
| @@ -828,6 +828,19 @@ The 'ifchanged' block tag is used within a loop. It has two possible uses. | ||||
|             {% endifchanged %} | ||||
|         {% endfor %} | ||||
|  | ||||
| The ``ifchanged`` tag also takes an optional ``{% else %}`` clause that will | ||||
| be displayed if the value has not changed:: | ||||
|  | ||||
|     {% for match in matches %} | ||||
|         <div style="background-color: | ||||
|             {% ifchanged match.ballot_id %} | ||||
|                 {% cycle red,blue %} | ||||
|             {% else %} | ||||
|                 grey | ||||
|             {% endifchanged %} | ||||
|         ">{{ match }}</div> | ||||
|     {% endfor %} | ||||
|  | ||||
| ifequal | ||||
| ~~~~~~~ | ||||
|  | ||||
|   | ||||
| @@ -565,6 +565,14 @@ class Templates(unittest.TestCase): | ||||
|             # ifchanged for the day. | ||||
|             'ifchanged-param04': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'), | ||||
|  | ||||
|             # Test the else clause of ifchanged. | ||||
|             'ifchanged-else01': ('{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-first,1-other,2-first,2-other,2-other,3-first,'), | ||||
|  | ||||
|             'ifchanged-else02': ('{% for id in ids %}{{ id }}-{% ifchanged id %}{% cycle red,blue %}{% else %}grey{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1-grey,2-blue,2-grey,2-grey,3-red,'), | ||||
|             'ifchanged-else03': ('{% for id in ids %}{{ id }}{% ifchanged id %}-{% cycle red,blue %}{% else %}{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1,2-blue,2,2,3-red,'), | ||||
|  | ||||
|             'ifchanged-else04': ('{% for id in ids %}{% ifchanged %}***{{ id }}*{% else %}...{% endifchanged %}{{ forloop.counter }}{% endfor %}', {'ids': [1,1,2,2,2,3,4]}, '***1*1...2***2*3...4...5***3*6***4*7'), | ||||
|  | ||||
|             ### IFEQUAL TAG ########################################################### | ||||
|             'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""), | ||||
|             'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"), | ||||
| @@ -712,7 +720,7 @@ class Templates(unittest.TestCase): | ||||
|  | ||||
|          	# Inheritance from a template that doesn't have any blocks | ||||
|          	'inheritance27': ("{% extends 'inheritance26' %}", {}, 'no tags'), | ||||
|          	 | ||||
|  | ||||
|             ### I18N ################################################################## | ||||
|  | ||||
|             # {% spaceless %} tag | ||||
| @@ -893,16 +901,16 @@ class Templates(unittest.TestCase): | ||||
|             'cache07': ('{% load cache %}{% cache 2 test foo %}cache07{% endcache %}', {'foo': 1}, 'cache05'), | ||||
|  | ||||
|             # Allow first argument to be a variable. | ||||
|             'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'),  | ||||
|             'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'),  | ||||
|             'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'),  | ||||
|             'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'), | ||||
|             'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'), | ||||
|             'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'), | ||||
|  | ||||
|             # Raise exception if we don't have at least 2 args, first one integer. | ||||
|             'cache11': ('{% load cache %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError), | ||||
|             'cache12': ('{% load cache %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError), | ||||
|             'cache13': ('{% load cache %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError), | ||||
|             'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError),  | ||||
|             'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError),  | ||||
|             'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError), | ||||
|             'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError), | ||||
|  | ||||
|             ### AUTOESCAPE TAG ############################################## | ||||
|             'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user