Ticket #3100: fix3100.patch
File fix3100.patch, 9.0 KB (added by , 14 years ago) |
---|
-
django/template/__init__.py
commit a387e97f4faf7f2237297933aa32f3b2d88c3e7f Author: Matthias Kestenholz <mk@spinlock.ch> Date: Thu Oct 7 16:12:05 2010 +0200 WIP diff --git a/django/template/__init__.py b/django/template/__init__.py index c316786..1fc2e7c 100644
a b class Parser(object): 250 250 for lib in builtins: 251 251 self.add_library(lib) 252 252 253 def parse(self, parse_until=None): 254 if parse_until is None: parse_until = [] 253 def parse(self, parse_until=None, parse_until_args_allowed=None): 254 parse_until = parse_until and list(parse_until) or [] 255 parse_until_args_allowed = parse_until_args_allowed and list(parse_until_args_allowed) or [] 255 256 nodelist = self.create_nodelist() 256 257 while self.tokens: 257 258 token = self.next_token() … … class Parser(object): 268 269 # put token back on token list so calling code knows why it terminated 269 270 self.prepend_token(token) 270 271 return nodelist 272 271 273 try: 272 274 command = token.contents.split()[0] 273 275 except IndexError: 274 276 self.empty_block_tag(token) 277 278 if command in parse_until_args_allowed: 279 # put token back on token list so calling code knows why it terminated 280 self.prepend_token(token) 281 return nodelist 282 275 283 # execute callback function for this tag and append resulting node 276 284 self.enter_command(command, token) 277 285 try: 278 286 compile_func = self.tags[command] 279 287 except KeyError: 280 self.invalid_block_tag(token, command, parse_until )288 self.invalid_block_tag(token, command, parse_until_args_allowed + parse_until) 281 289 try: 282 290 compiled_result = compile_func(self, token) 283 291 except TemplateSyntaxError, e: … … class Parser(object): 285 293 raise 286 294 self.extend_nodelist(nodelist, compiled_result, token) 287 295 self.exit_command() 288 if parse_until :289 self.unclosed_block_tag(parse_until )296 if parse_until_args_allowed or parse_until: 297 self.unclosed_block_tag(parse_until_args_allowed + parse_until) 290 298 return nodelist 291 299 292 300 def skip_past(self, endtag): -
django/template/defaulttags.py
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 1b07413..6043d36 100644
a b class IfEqualNode(Node): 235 235 class IfNode(Node): 236 236 child_nodelists = ('nodelist_true', 'nodelist_false') 237 237 238 def __init__(self, var, nodelist_true, nodelist_false=None):239 self. nodelist_true, self.nodelist_false = nodelist_true, nodelist_false240 self. var = var238 def __init__(self, condition_nodelists, else_nodelist): 239 self.condition_nodelists = condition_nodelists 240 self.else_nodelist = else_nodelist 241 241 242 242 def __repr__(self): 243 243 return "<If node>" 244 244 245 245 def __iter__(self): 246 for node in self.nodelist_true: 247 yield node 248 for node in self.nodelist_false: 246 for condition, nodelist in self.condition_nodelists: 247 for node in nodelist: 248 yield node 249 250 for node in else_nodelist: 249 251 yield node 250 252 253 def get_nodes_by_type(self, nodetype): 254 nodes = [] 255 if isinstance(self, nodetype): 256 nodes.append(self) 257 258 for condition, nodelist in self.condition_nodelists: 259 nodes.extend(nodelist.get_nodes_by_type(nodetype)) 260 261 nodes.extend(self.else_nodelist.get_nodes_by_type(nodetype)) 262 263 return nodes 264 251 265 def render(self, context): 252 try: 253 var = self.var.eval(context) 254 except VariableDoesNotExist: 255 var = None 266 for condition, nodelist in self.condition_nodelists: 267 try: 268 yes = condition.eval(context) 269 except VariableDoesNotExist: 270 yes = False 256 271 257 if var:258 return self.nodelist_true.render(context)259 else: 260 return self.nodelist_false.render(context)272 if yes: 273 return nodelist.render(context) 274 275 return self.else_nodelist.render(context) 261 276 262 277 class RegroupNode(Node): 263 278 def __init__(self, target, expression, var_name): … … def do_if(parser, token): 788 803 As you can see, the ``if`` tag can take an option ``{% else %}`` clause 789 804 that will be displayed if the test fails. 790 805 806 If you have multiple conditions to check against, you may wish to use 807 the ``elif`` tag:: 808 809 {% if athlete_list %} 810 Number of athletes: {{ athlete_list|length }} 811 {% elif athletes_in_lockerroom %} 812 There are some athletes queued in the locker room, but they 813 should be out soon! 814 {% else %} 815 No athletes. 816 {% endif %} 817 791 818 ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of 792 819 variables or to negate a given variable:: 793 820 … … def do_if(parser, token): 824 851 825 852 Operator precedence follows Python. 826 853 """ 827 bits = token.split_contents()[1:] 828 var = TemplateIfParser(parser, bits).parse() 829 nodelist_true = parser.parse(('else', 'endif')) 830 token = parser.next_token() 831 if token.contents == 'else': 832 nodelist_false = parser.parse(('endif',)) 833 parser.delete_first_token() 834 else: 835 nodelist_false = NodeList() 836 return IfNode(var, nodelist_true, nodelist_false) 854 # The condition nodelist is constructed of: 855 # [(<if_var>, <nodelist>), 856 # <if_var>, <nodelist>])] 857 # 858 # So as soon as one of these conditions evaluates to True, the 859 # accompanying nodelist is evaluated. 860 condition_nodelists = [] 861 else_nodelist = None 862 all_parsed = False 863 864 while not all_parsed: 865 bits = token.split_contents()[1:] 866 var = TemplateIfParser(parser, bits).parse() 867 nodelist = parser.parse(('else', 'endif'), ('elif',)) 868 condition_nodelists.append((var, nodelist)) 869 870 token = parser.next_token() 871 command = token.contents.split()[0] 872 if command == 'elif': 873 pass 874 elif command == 'else': 875 else_nodelist = parser.parse(('endif',)) 876 parser.delete_first_token() 877 all_parsed = True 878 elif command == 'endif': 879 all_parsed = True 880 881 if not else_nodelist: 882 else_nodelist = NodeList() 883 884 return IfNode(condition_nodelists, else_nodelist) 837 885 do_if = register.tag("if", do_if) 838 886 839 887 #@register.tag -
docs/ref/templates/builtins.txt
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index a20ab17..969ff49 100644
a b displayed by the ``{{ athlete_list|length }}`` variable. 325 325 As you can see, the ``if`` tag can take an optional ``{% else %}`` clause that 326 326 will be displayed if the test fails. 327 327 328 .. versionadded:: 1.2 329 330 If you have multiple conditions to check against, you may wish to use 331 the ``elif`` tag:: 332 333 {% if athlete_list %} 334 Number of athletes: {{ athlete_list|length }} 335 {% elif athletes_in_lockerroom %} 336 There are some athletes queued in the locker room, but they 337 should be out soon! 338 {% else %} 339 No athletes. 340 {% endif %} 341 328 342 Boolean operators 329 343 ^^^^^^^^^^^^^^^^^ 330 344 -
tests/regressiontests/templates/tests.py
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 9e2d175..e721aab 100644
a b class Templates(unittest.TestCase): 316 316 try: 317 317 t = Template("{% if 1 %}lala{% endblock %}{% endif %}") 318 318 except TemplateSyntaxError, e: 319 self.assertEquals(e.args[0], "Invalid block tag: 'endblock', expected 'el se' or 'endif'")319 self.assertEquals(e.args[0], "Invalid block tag: 'endblock', expected 'elif', 'else' or 'endif'") 320 320 321 321 def test_templates(self): 322 322 template_tests = self.get_template_tests() … … class Templates(unittest.TestCase): 711 711 'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"), 712 712 'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"), 713 713 714 'if-tag04': ("{% if foo %}foo{% elif bar %}bar{% else %}nothing{%endif%}", 715 {'foo': True}, "foo"), 716 'if-tag05': ("{% if foo %}foo{% elif bar %}bar{% else %}nothing{%endif%}", 717 {'bar': True}, "bar"), 718 'if-tag06': ("{% if foo %}foo{% elif bar %}bar{% else %}nothing{%endif%}", 719 {}, "nothing"), 720 714 721 # Filters 715 722 'if-tag-filter01': ("{% if foo|length == 5 %}yes{% else %}no{% endif %}", {'foo': 'abcde'}, "yes"), 716 723 'if-tag-filter02': ("{% if foo|upper == 'ABC' %}yes{% else %}no{% endif %}", {}, "no"),