Ticket #3791: if_templatetag.diff
File if_templatetag.diff, 5.3 KB (added by , 18 years ago) |
---|
-
django/template/defaulttags.py
6 6 from django.conf import settings 7 7 import sys 8 8 9 # For Python 2.3 10 if not hasattr(__builtins__, 'set'): 11 from sets import Set as set 12 9 13 register = Library() 10 14 11 15 class CommentNode(Node): … … 176 180 return self.nodelist_false.render(context) 177 181 178 182 class IfNode(Node): 179 def __init__(self, bool_exprs, nodelist_true, nodelist_false, link_type): 180 self.bool_exprs = bool_exprs 183 def __init__(self, expression, variables, nodelist_true, nodelist_false): 184 self.expression = expression 185 self.variables = variables 181 186 self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false 182 self.link_type = link_type183 187 184 188 def __repr__(self): 185 189 return "<If node>" … … 199 203 return nodes 200 204 201 205 def render(self, context): 202 if self.link_type == IfNode.LinkTypes.or_: 203 for ifnot, bool_expr in self.bool_exprs: 204 try: 205 value = bool_expr.resolve(context, True) 206 except VariableDoesNotExist: 207 value = None 208 if (value and not ifnot) or (ifnot and not value): 209 return self.nodelist_true.render(context) 206 variable_context = {} 207 expression = self.expression 208 for variable in self.variables: 209 try: 210 value = variable.resolve(context, True) 211 except VariableDoesNotExist: 212 value = None 213 214 context_name = 'var%s' % len(variable_context) 215 expression = re.sub(r'(?<![\w\.\"\'])%s(?![\w\.\"\'])' % re.escape(variable.token), context_name, expression) 216 variable_context[context_name] = value 217 try: 218 resultant = eval(expression, variable_context) 219 except: 220 resultant = False 221 if not resultant: 210 222 return self.nodelist_false.render(context) 211 else: 212 for ifnot, bool_expr in self.bool_exprs: 213 try: 214 value = bool_expr.resolve(context, True) 215 except VariableDoesNotExist: 216 value = None 217 if not ((value and not ifnot) or (ifnot and not value)): 218 return self.nodelist_false.render(context) 219 return self.nodelist_true.render(context) 223 return self.nodelist_true.render(context) 220 224 221 class LinkTypes:222 and_ = 0,223 or_ = 1224 225 225 class RegroupNode(Node): 226 226 def __init__(self, target, expression, var_name): 227 227 self.target, self.expression = target, expression … … 622 622 There are no athletes, or there are some coaches. 623 623 {% endif %} 624 624 625 For simplicity, ``if`` tags do not allow ``and`` clauses. Use nested ``if`` 626 tags instead:: 625 Regular python conditional syntax and comparisons are avaialble, however, 626 variables must use the Django Template "." syntax to access dict keys and 627 array indicies. 627 628 628 {% if athlete_list %} 629 {% if coach_list %} 630 Number of athletes: {{ athlete_list|count }}. 631 Number of coaches: {{ coach_list|count }}. 632 {% endif %} 633 {% endif %} 629 {% if ("Jacob" in athelete_list and "Mike" not in athelete_list) or athelete_list.count > 2 %} 630 Jacob is an athelete and Mikey is not OR there are more than 2 atheletes. 631 {% endif %} 634 632 """ 635 bits = token.contents.split( )633 bits = token.contents.split(None, 1) 636 634 del bits[0] 637 if not bits: 635 expression = bits[0] 636 variables = set([ parser.compile_filter(x) for x in re.findall('[\w\.]+', expression) if x not in ('and', 'or', 'not', 'in') ]) 637 if not variables: 638 638 raise TemplateSyntaxError, "'if' statement requires at least one argument" 639 # bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] 640 bitstr = ' '.join(bits) 641 boolpairs = bitstr.split(' and ') 642 boolvars = [] 643 if len(boolpairs) == 1: 644 link_type = IfNode.LinkTypes.or_ 645 boolpairs = bitstr.split(' or ') 646 else: 647 link_type = IfNode.LinkTypes.and_ 648 if ' or ' in bitstr: 649 raise TemplateSyntaxError, "'if' tags can't mix 'and' and 'or'" 650 for boolpair in boolpairs: 651 if ' ' in boolpair: 652 try: 653 not_, boolvar = boolpair.split() 654 except ValueError: 655 raise TemplateSyntaxError, "'if' statement improperly formatted" 656 if not_ != 'not': 657 raise TemplateSyntaxError, "Expected 'not' in if statement" 658 boolvars.append((True, parser.compile_filter(boolvar))) 659 else: 660 boolvars.append((False, parser.compile_filter(boolpair))) 639 661 640 nodelist_true = parser.parse(('else', 'endif')) 662 641 token = parser.next_token() 663 642 if token.contents == 'else': … … 665 644 parser.delete_first_token() 666 645 else: 667 646 nodelist_false = NodeList() 668 return IfNode( boolvars, nodelist_true, nodelist_false, link_type)647 return IfNode(expression, variables, nodelist_true, nodelist_false) 669 648 do_if = register.tag("if", do_if) 670 649 671 650 #@register.tag