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)
|
||||
|
||||
class IfChangedNode(Node):
|
||||
def __init__(self, nodelist):
|
||||
def __init__(self, nodelist, *varlist):
|
||||
self.nodelist = nodelist
|
||||
self._last_seen = None
|
||||
self._varlist = varlist
|
||||
|
||||
def render(self, context):
|
||||
if context.has_key('forloop') and context['forloop']['first']:
|
||||
self._last_seen = None
|
||||
content = self.nodelist.render(context)
|
||||
if content != self._last_seen:
|
||||
try:
|
||||
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)
|
||||
self._last_seen = content
|
||||
self._last_seen = compare_to
|
||||
context.push()
|
||||
context['ifchanged'] = {'firstloop': firstloop}
|
||||
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.
|
||||
|
||||
The 'ifchanged' block tag is used within a loop. It checks its own rendered
|
||||
contents against its previous state and only displays its content if the
|
||||
value has changed::
|
||||
The 'ifchanged' block tag is used within a loop. It has two possible uses.
|
||||
|
||||
<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 %}
|
||||
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
|
||||
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
||||
{% endfor %}
|
||||
<h1>Archive for {{ year }}</h1>
|
||||
|
||||
{% for date in days %}
|
||||
{% 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()
|
||||
if len(bits) != 1:
|
||||
raise TemplateSyntaxError, "'ifchanged' tag takes no arguments"
|
||||
nodelist = parser.parse(('endifchanged',))
|
||||
parser.delete_first_token()
|
||||
return IfChangedNode(nodelist)
|
||||
return IfChangedNode(nodelist, *bits[1:])
|
||||
ifchanged = register.tag(ifchanged)
|
||||
|
||||
#@register.tag
|
||||
|
|
|
@ -525,16 +525,29 @@ ifchanged
|
|||
|
||||
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
|
||||
contents against its previous state and only displays its content if the value
|
||||
has changed::
|
||||
The 'ifchanged' block tag is used within a loop. It has two possible uses.
|
||||
|
||||
<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 %}
|
||||
{% ifchanged %}<h3>{{ day|date:"F" }}</h3>{% endifchanged %}
|
||||
<a href="{{ day|date:"M/d"|lower }}/">{{ day|date:"j" }}</a>
|
||||
{% endfor %}
|
||||
<h1>Archive for {{ year }}</h1>
|
||||
|
||||
{% for date in days %}
|
||||
{% 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
|
||||
~~~~~~~
|
||||
|
|
|
@ -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'),
|
||||
'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'),
|
||||
|
||||
# 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 ###########################################################
|
||||
'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),
|
||||
|
|
Loading…
Reference in New Issue