Django

Code

Changeset 4050

Show
Ignore:
Timestamp:
11/06/06 23:36:51 (2 years ago)
Author:
jacob
Message:

Fixed #2800: the ifchanged tag now can optionally take paramaters to be checked for changing (instead of always using the content). Thanks, Wolfram Kriesing.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/defaulttags.py

    r3938 r4050  
    125125 
    126126class IfChangedNode(Node): 
    127     def __init__(self, nodelist): 
     127    def __init__(self, nodelist, *varlist): 
    128128        self.nodelist = nodelist 
    129129        self._last_seen = None 
     130        self._varlist = varlist 
    130131 
    131132    def render(self, context): 
    132133        if context.has_key('forloop') and context['forloop']['first']: 
    133134            self._last_seen = None 
    134         content = self.nodelist.render(context) 
    135         if content != self._last_seen: 
     135        try: 
     136            if self._varlist: 
     137                # Consider multiple parameters. 
     138                # This automatically behaves like a OR evaluation of the multiple variables. 
     139                compare_to = [resolve_variable(var, context) for var in self._varlist] 
     140            else: 
     141                compare_to = self.nodelist.render(context) 
     142        except VariableDoesNotExist: 
     143            compare_to = None         
     144 
     145        if  compare_to != self._last_seen: 
    136146            firstloop = (self._last_seen == None) 
    137             self._last_seen = content 
     147            self._last_seen = compare_to 
    138148            context.push() 
    139149            context['ifchanged'] = {'firstloop': firstloop} 
     
    635645    Check if a value has changed from the last iteration of a loop. 
    636646 
    637     The 'ifchanged' block tag is used within a loop. It checks its own rendered 
    638     contents against its previous state and only displays its content if the 
    639     value has changed:: 
    640  
    641         <h1>Archive for {{ year }}</h1> 
    642  
    643         {% for date in days %} 
    644         {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} 
    645         <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> 
    646         {% endfor %} 
     647    The 'ifchanged' block tag is used within a loop. It has two possible uses. 
     648 
     649    1. Checks its own rendered contents against its previous state and only 
     650       displays the content if it has changed. For example, this displays a list of 
     651       days, only displaying the month if it changes:: 
     652 
     653            <h1>Archive for {{ year }}</h1> 
     654 
     655            {% for date in days %} 
     656                {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} 
     657                <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> 
     658            {% endfor %} 
     659 
     660    2. If given a variable, check if that variable has changed. For example, the 
     661       following shows the date every time it changes, but only shows the hour if both 
     662       the hour and the date has changed:: 
     663 
     664            {% for date in days %} 
     665                {% ifchanged date.date %} {{date.date}} {% endifchanged %} 
     666                {% ifchanged date.hour date.date %} 
     667                    {{date.hour}} 
     668                {% endifchanged %} 
     669            {% endfor %} 
    647670    """ 
    648671    bits = token.contents.split() 
    649     if len(bits) != 1: 
    650         raise TemplateSyntaxError, "'ifchanged' tag takes no arguments" 
    651672    nodelist = parser.parse(('endifchanged',)) 
    652673    parser.delete_first_token() 
    653     return IfChangedNode(nodelist
     674    return IfChangedNode(nodelist, *bits[1:]
    654675ifchanged = register.tag(ifchanged) 
    655676 
  • django/trunk/docs/templates.txt

    r3938 r4050  
    526526Check if a value has changed from the last iteration of a loop. 
    527527 
    528 The ``ifchanged`` block tag is used within a loop. It checks its own rendered 
    529 contents against its previous state and only displays its content if the value 
    530 has changed:: 
    531  
    532     <h1>Archive for {{ year }}</h1> 
    533  
    534     {% for day in days %} 
    535     {% ifchanged %}<h3>{{ day|date:"F" }}</h3>{% endifchanged %} 
    536     <a href="{{ day|date:"M/d"|lower }}/">{{ day|date:"j" }}</a> 
    537     {% endfor %} 
     528The 'ifchanged' block tag is used within a loop. It has two possible uses. 
     529 
     5301. Checks its own rendered contents against its previous state and only 
     531   displays the content if it has changed. For example, this displays a list of 
     532   days, only displaying the month if it changes:: 
     533 
     534        <h1>Archive for {{ year }}</h1> 
     535 
     536        {% for date in days %} 
     537            {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} 
     538            <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> 
     539        {% endfor %} 
     540         
     5412. If given a variable, check if that variable has changed. For example, the 
     542   following shows the date every time it changes, but only shows the hour if both 
     543   the hour and the date has changed:: 
     544     
     545        {% for date in days %} 
     546            {% ifchanged date.date %} {{date.date}} {% endifchanged %} 
     547            {% ifchanged date.hour date.date %} 
     548                {{date.hour}} 
     549            {% endifchanged %} 
     550        {% endfor %} 
    538551 
    539552ifequal 
  • django/trunk/tests/regressiontests/templates/tests.py

    r3938 r4050  
    329329            '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'), 
    330330            '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'), 
     331             
     332            # Test one parameter given to ifchanged. 
     333            'ifchanged-param01': ('{% for n in num %}{% ifchanged n %}..{% endifchanged %}{{ n }}{% endfor %}', { 'num': (1,2,3) }, '..1..2..3'), 
     334            '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'), 
     335             
     336            # Test multiple parameters to ifchanged. 
     337            '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'), 
     338             
     339            # Test a date+hour like construct, where the hour of the last day 
     340            # is the same but the date had changed, so print the hour anyway. 
     341            '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'), 
     342             
     343            # Logically the same as above, just written with explicit 
     344            # ifchanged for the day. 
     345            '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'), 
    331346 
    332347            ### IFEQUAL TAG ###########################################################