Ticket #5865: cycle.diff
File cycle.diff, 6.7 KB (added by , 17 years ago) |
---|
-
django/template/defaulttags.py
39 39 40 40 class CycleNode(Node): 41 41 def __init__(self, cyclevars, variable_name=None): 42 self.cycle_iter = itertools_cycle(cyclevars)42 self.cycle_iter = None 43 43 self.variable_name = variable_name 44 self.cyclevars = cyclevars 45 self.resolve = None 46 self.collection = None 44 47 48 def render_init(self,context): 49 if len(self.cyclevars) == 1: 50 #startning from syntax check 51 if not context.has_key(self.cyclevars[0]): 52 raise TemplateSyntaxError("Named cycle '%s' does not exist" % self.cyclevars[0]) 53 try: 54 i = iter(Variable(self.cyclevars[0]).resolve(context)) 55 isiterable = True 56 except TypeError: 57 isiterable = False 58 except NameError: 59 isiterable = False 60 if len(self.cyclevars) == 1 and context.has_key(self.cyclevars[0]) and isiterable: 61 #the {% cycle colors %} case 62 self.resolve = False 63 self.collection = Variable(self.cyclevars[0]).resolve(context) 64 self.cycle_iter = itertools_cycle(self.collection) 65 else: 66 self.resolve = True 67 self.collection = self.cyclevars 68 self.cycle_iter = itertools_cycle(self.collection) 69 context['cycle'] = { 70 # cycle internals 71 'collection': self.collection, 72 'name':self.variable_name, 73 'value':None, 74 } 75 76 def __repr__(self): 77 return "<Cycle Node: cycle_iter %s, variable_name %s, cyclevars %s, resolve %s, collection %s>" % \ 78 (self.cycle_iter, self.variable_name, self.cyclevars, self.resolve, self.collection) 79 45 80 def render(self, context): 46 value = self.cycle_iter.next() 47 value = Variable(value).resolve(context) 81 if self.collection == None: 82 #first execution of render, so finally we will know the context 83 self.render_init(context) 84 #all is initiated 85 if self.resolve: 86 value = self.cycle_iter.next() 87 try: 88 value = Variable(value).resolve(context) 89 except NameError: 90 pass 91 else: 92 value = self.cycle_iter.next() 93 48 94 if self.variable_name: 49 95 context[self.variable_name] = value 50 return value 96 context['cycle'] = { 97 # cycle internals 98 'collection': self.collection, 99 'name':self.variable_name, 100 'value':value, 101 } 102 return value 51 103 52 104 class DebugNode(Node): 53 105 def render(self, context): … … 456 508 457 509 You can use any number of values, seperated by spaces. Commas can also 458 510 be used to separate values; if a comma is used, the cycle values are 459 interpreted as literal strings. 511 interpreted as literal strings. 512 513 Additionally when you pass a single value, the cycle tag resolves it from 514 context and than iterates over context value:: 515 516 {'colors': ['red', 'blue', 'green']} 517 518 {% for row in mydata %} 519 <tr class="{% cycle colors %}">...</tr> 520 {% endfor %} 460 521 """ 461 522 462 523 # Note: This returns the exact same node on each {% cycle name %} call; … … 480 541 args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] 481 542 482 543 if len(args) == 2: 483 # {% cycle foo %} case. 544 #two cases: 545 # {% cycle foo %} 546 # {% cycle foos %} where foos are an iterable type defined in context 484 547 name = args[1] 485 548 if not hasattr(parser, '_namedCycleNodes'): 486 raise TemplateSyntaxError("No named cycles in template." 487 " '%s' is not defined" % name) 488 if not name in parser._namedCycleNodes: 489 raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) 490 return parser._namedCycleNodes[name] 549 #if not a table than we will throw an exception at rendering 550 parser._namedCycleNodes = {} 551 node = CycleNode(args[1:2]) 552 parser._namedCycleNodes[name] = node 553 else: 554 if not name in parser._namedCycleNodes: 555 raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) 556 node = parser._namedCycleNodes[name] 557 return node 491 558 492 if len(args) > 4 and args[-2] == 'as':559 if len(args) >= 4 and args[-2] == 'as': 493 560 name = args[-1] 494 561 node = CycleNode(args[1:-2], name) 495 562 if not hasattr(parser, '_namedCycleNodes'): -
tests/regressiontests/templates/tests.py
394 394 'cycle13': ("{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}", {'test': range(5)}, 'a0,b1,a2,b3,a4,'), 395 395 'cycle14': ("{% cycle one two as foo %}{% cycle foo %}", {'one': '1','two': '2'}, '12'), 396 396 'cycle13': ("{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}", {'test': range(5), 'aye': 'a', 'bee': 'b'}, 'a0,b1,a2,b3,a4,'), 397 # List format 398 'cycle20': ("{% cycle colors %}", {'colors': 'r'}, 'r'), 399 'cycle21': ("{% cycle colors %}{% cycle colors %}", {'colors': ['r', 'g', 'b']}, 'rg'), 400 # 'cycle22': ("{% cycle colors %}{% cycle colors %}", {'colors': {'r': 1, 'g': 2}}, 'rg'), not reliable test 401 'cycle23': ("{% cycle colors %}{% cycle colors %}{% cycle colors %}", {'colors': ['r', 'g', 'b']}, 'rgb'), 402 'cycle24': ("{% cycle colors %}{% cycle colors %}{% cycle colors %}{% cycle colors %}", {'colors': ['r', 'g', 'b']}, 'rgbr'), 403 'cycle25': ("{% cycle colors as color %}{% cycle color %}", {'colors': ['r', 'g', 'b']}, 'rg'), 404 'cycle26': ("{% cycle colors as color %}{% cycle color %}{% cycle color %}", {'colors': ['r', 'g', 'b']}, 'rgb'), 405 'cycle27': ("{% cycle colors as color %}{% cycle color %}{% cycle color %}{% cycle color %}", {'colors': ['r', 'g', 'b']}, 'rgbr'), 406 'cycle28': ("{% for i in test %}{% cycle colors %}{{ cycle.value }}{{ i }},{% endfor %}", {'test': range(5),'colors': ['r', 'g', 'b']}, 'rr0,gg1,bb2,rr3,gg4,'), 407 'cycle29': ("{% for i in test %}{% cycle colors %}{% cycle colors %}{{ i }},{% endfor %}", {'test': range(5),'colors': ['r', 'g', 'b']}, 'rg0,br1,gb2,rg3,br4,'), 397 408 398 409 ### EXCEPTIONS ############################################################ 399 410