Fixed #2800: the ifchanged tag now can optionally take paramaters to be checked for changing (instead of always using the content). Thanks, Wolfram Kriesing.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@4050 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a14dba5eed
commit
b1b4e8e7c4
|
@ -124,17 +124,27 @@ class ForNode(Node):
|
||||||
return nodelist.render(context)
|
return nodelist.render(context)
|
||||||
|
|
||||||
class IfChangedNode(Node):
|
class IfChangedNode(Node):
|
||||||
def __init__(self, nodelist):
|
def __init__(self, nodelist, *varlist):
|
||||||
self.nodelist = nodelist
|
self.nodelist = nodelist
|
||||||
self._last_seen = None
|
self._last_seen = None
|
||||||
|
self._varlist = varlist
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
if context.has_key('forloop') and context['forloop']['first']:
|
if context.has_key('forloop') and context['forloop']['first']:
|
||||||
self._last_seen = None
|
self._last_seen = None
|
||||||
content = self.nodelist.render(context)
|
try:
|
||||||
if content != self._last_seen:
|
if self._varlist:
|
||||||
|
# Consider multiple parameters.
|
||||||
|
# This automatically behaves like a OR evaluation of the multiple variables.
|
||||||
|
compare_to = [resolve_variable(var, context) for var in self._varlist]
|
||||||
|
else:
|
||||||
|
compare_to = self.nodelist.render(context)
|
||||||
|
except VariableDoesNotExist:
|
||||||
|
compare_to = None
|
||||||
|
|
||||||
|
if compare_to != self._last_seen:
|
||||||
firstloop = (self._last_seen == None)
|
firstloop = (self._last_seen == None)
|
||||||
self._last_seen = content
|
self._last_seen = compare_to
|
||||||
context.push()
|
context.push()
|
||||||
context['ifchanged'] = {'firstloop': firstloop}
|
context['ifchanged'] = {'firstloop': firstloop}
|
||||||
content = self.nodelist.render(context)
|
content = self.nodelist.render(context)
|
||||||
|
@ -634,23 +644,34 @@ def ifchanged(parser, token):
|
||||||
"""
|
"""
|
||||||
Check if a value has changed from the last iteration of a loop.
|
Check if a value has changed from the last iteration of a loop.
|
||||||
|
|
||||||
The 'ifchanged' block tag is used within a loop. It checks its own rendered
|
The 'ifchanged' block tag is used within a loop. It has two possible uses.
|
||||||
contents against its previous state and only displays its content if the
|
|
||||||
value has changed::
|
|
||||||
|
|
||||||
<h1>Archive for {{ year }}</h1>
|
1. Checks its own rendered contents against its previous state and only
|
||||||
|
displays the content if it has changed. For example, this displays a list of
|
||||||
|
days, only displaying the month if it changes::
|
||||||
|
|
||||||
{% for date in days %}
|
<h1>Archive for {{ year }}</h1>
|
||||||
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
|
|
||||||
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
{% for date in days %}
|
||||||
{% endfor %}
|
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
|
||||||
|
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
2. If given a variable, check if that variable has changed. For example, the
|
||||||
|
following shows the date every time it changes, but only shows the hour if both
|
||||||
|
the hour and the date has changed::
|
||||||
|
|
||||||
|
{% for date in days %}
|
||||||
|
{% ifchanged date.date %} {{date.date}} {% endifchanged %}
|
||||||
|
{% ifchanged date.hour date.date %}
|
||||||
|
{{date.hour}}
|
||||||
|
{% endifchanged %}
|
||||||
|
{% endfor %}
|
||||||
"""
|
"""
|
||||||
bits = token.contents.split()
|
bits = token.contents.split()
|
||||||
if len(bits) != 1:
|
|
||||||
raise TemplateSyntaxError, "'ifchanged' tag takes no arguments"
|
|
||||||
nodelist = parser.parse(('endifchanged',))
|
nodelist = parser.parse(('endifchanged',))
|
||||||
parser.delete_first_token()
|
parser.delete_first_token()
|
||||||
return IfChangedNode(nodelist)
|
return IfChangedNode(nodelist, *bits[1:])
|
||||||
ifchanged = register.tag(ifchanged)
|
ifchanged = register.tag(ifchanged)
|
||||||
|
|
||||||
#@register.tag
|
#@register.tag
|
||||||
|
|
|
@ -525,16 +525,29 @@ ifchanged
|
||||||
|
|
||||||
Check if a value has changed from the last iteration of a loop.
|
Check if a value has changed from the last iteration of a loop.
|
||||||
|
|
||||||
The ``ifchanged`` block tag is used within a loop. It checks its own rendered
|
The 'ifchanged' block tag is used within a loop. It has two possible uses.
|
||||||
contents against its previous state and only displays its content if the value
|
|
||||||
has changed::
|
|
||||||
|
|
||||||
<h1>Archive for {{ year }}</h1>
|
1. Checks its own rendered contents against its previous state and only
|
||||||
|
displays the content if it has changed. For example, this displays a list of
|
||||||
|
days, only displaying the month if it changes::
|
||||||
|
|
||||||
{% for day in days %}
|
<h1>Archive for {{ year }}</h1>
|
||||||
{% ifchanged %}<h3>{{ day|date:"F" }}</h3>{% endifchanged %}
|
|
||||||
<a href="{{ day|date:"M/d"|lower }}/">{{ day|date:"j" }}</a>
|
{% for date in days %}
|
||||||
{% endfor %}
|
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
|
||||||
|
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
2. If given a variable, check if that variable has changed. For example, the
|
||||||
|
following shows the date every time it changes, but only shows the hour if both
|
||||||
|
the hour and the date has changed::
|
||||||
|
|
||||||
|
{% for date in days %}
|
||||||
|
{% ifchanged date.date %} {{date.date}} {% endifchanged %}
|
||||||
|
{% ifchanged date.hour date.date %}
|
||||||
|
{{date.hour}}
|
||||||
|
{% endifchanged %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
ifequal
|
ifequal
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
|
@ -328,6 +328,21 @@ class Templates(unittest.TestCase):
|
||||||
'ifchanged05': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (1, 2, 3)}, '1123123123'),
|
'ifchanged05': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (1, 2, 3)}, '1123123123'),
|
||||||
'ifchanged06': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2)}, '1222'),
|
'ifchanged06': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2)}, '1222'),
|
||||||
'ifchanged07': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% for y in numy %}{% ifchanged %}{{ y }}{% endifchanged %}{% endfor %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2), 'numy': (3, 3, 3)}, '1233323332333'),
|
'ifchanged07': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% for x in numx %}{% ifchanged %}{{ x }}{% endifchanged %}{% for y in numy %}{% ifchanged %}{{ y }}{% endifchanged %}{% endfor %}{% endfor %}{% endfor %}', { 'num': (1, 1, 1), 'numx': (2, 2, 2), 'numy': (3, 3, 3)}, '1233323332333'),
|
||||||
|
|
||||||
|
# Test one parameter given to ifchanged.
|
||||||
|
'ifchanged-param01': ('{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}', { 'num': (1,2,3) }, '..1..2..3'),
|
||||||
|
'ifchanged-param02': ('{% for n in num %}{% for x in numx %}{% ifchanged n %}..{% endifchanged %}{{ x }}{% endfor %}{% endfor %}', { 'num': (1,2,3), 'numx': (5,6,7) }, '..567..567..567'),
|
||||||
|
|
||||||
|
# Test multiple parameters to ifchanged.
|
||||||
|
'ifchanged-param03': ('{% for n in num %}{{ n }}{% for x in numx %}{% ifchanged x n %}{{ x }}{% endifchanged %}{% endfor %}{% endfor %}', { 'num': (1,1,2), 'numx': (5,6,6) }, '156156256'),
|
||||||
|
|
||||||
|
# Test a date+hour like construct, where the hour of the last day
|
||||||
|
# is the same but the date had changed, so print the hour anyway.
|
||||||
|
'ifchanged-param04': ('{% for d in days %}{% ifchanged %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
|
||||||
|
|
||||||
|
# Logically the same as above, just written with explicit
|
||||||
|
# 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'),
|
||||||
|
|
||||||
### IFEQUAL TAG ###########################################################
|
### IFEQUAL TAG ###########################################################
|
||||||
'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),
|
'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),
|
||||||
|
|
Loading…
Reference in New Issue