Author: russellm
Date: 2006-09-04 09:02:11 -0500 (Mon, 04 Sep 2006)
New Revision: 3714

Modified:
   django/trunk/AUTHORS
   django/trunk/django/template/__init__.py
   django/trunk/django/template/defaulttags.py
   django/trunk/docs/templates_python.txt
   django/trunk/tests/regressiontests/templates/tests.py
Log:
Fixes #2637 -- Clarified handling of TEMPLATE_STRING_IF_INVALID, especially 
with regards to filtering of invalid values. Modified unit tests to test both 
empty and non-empty values for TEMPLATE_STRING_IF_INVALID. Thanks to 
SmileyChris for identifying and helping to resolve this bug.


Modified: django/trunk/AUTHORS
===================================================================
--- django/trunk/AUTHORS        2006-09-04 13:05:51 UTC (rev 3713)
+++ django/trunk/AUTHORS        2006-09-04 14:02:11 UTC (rev 3714)
@@ -104,7 +104,6 @@
     [EMAIL PROTECTED]
     Jason McBrayer <http://www.carcosa.net/jason/>
     [EMAIL PROTECTED]
-    [EMAIL PROTECTED]
     mmarshall
     Eric Moritz <http://eric.themoritzfamily.com/>
     Robin Munn <http://www.geekforgod.com/>
@@ -121,12 +120,14 @@
     plisk
     Daniel Poelzleithner <http://poelzi.org/>
     J. Rademaker
+    Michael Radziej <[EMAIL PROTECTED]>
     Brian Ray <http://brianray.chipy.org/>
     [EMAIL PROTECTED]
     Oliver Rutherfurd <http://rutherfurd.net/>
     Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
     David Schein
     Pete Shinners <[EMAIL PROTECTED]>
+    SmileyChris <[EMAIL PROTECTED]>
     sopel
     Thomas Steinacher <[EMAIL PROTECTED]>
     Radek Švarz <http://www.svarz.cz/translate/>

Modified: django/trunk/django/template/__init__.py
===================================================================
--- django/trunk/django/template/__init__.py    2006-09-04 13:05:51 UTC (rev 
3713)
+++ django/trunk/django/template/__init__.py    2006-09-04 14:02:11 UTC (rev 
3714)
@@ -549,9 +549,12 @@
             obj = resolve_variable(self.var, context)
         except VariableDoesNotExist:
             if ignore_failures:
-                return None
+                obj = None
             else:
-                return settings.TEMPLATE_STRING_IF_INVALID
+                if settings.TEMPLATE_STRING_IF_INVALID:
+                    return settings.TEMPLATE_STRING_IF_INVALID
+                else:
+                    obj = settings.TEMPLATE_STRING_IF_INVALID
         for func, args in self.filters:
             arg_vals = []
             for lookup, arg in args:

Modified: django/trunk/django/template/defaulttags.py
===================================================================
--- django/trunk/django/template/defaulttags.py 2006-09-04 13:05:51 UTC (rev 
3713)
+++ django/trunk/django/template/defaulttags.py 2006-09-04 14:02:11 UTC (rev 
3714)
@@ -86,7 +86,7 @@
             parentloop = {}
         context.push()
         try:
-            values = self.sequence.resolve(context)
+            values = self.sequence.resolve(context, True)
         except VariableDoesNotExist:
             values = []
         if values is None:
@@ -212,13 +212,13 @@
         self.var_name = var_name
 
     def render(self, context):
-        obj_list = self.target.resolve(context)
-        if obj_list == '': # target_var wasn't found in context; fail silently
+        obj_list = self.target.resolve(context, True)
+        if obj_list == None: # target_var wasn't found in context; fail 
silently
             context[self.var_name] = []
             return ''
         output = [] # list of dictionaries in the format {'grouper': 'key', 
'list': [list of contents]}
         for obj in obj_list:
-            grouper = self.expression.resolve(Context({'var': obj}))
+            grouper = self.expression.resolve(Context({'var': obj}), True)
             # TODO: Is this a sensible way to determine equality?
             if output and repr(output[-1]['grouper']) == repr(grouper):
                 output[-1]['list'].append(obj)

Modified: django/trunk/docs/templates_python.txt
===================================================================
--- django/trunk/docs/templates_python.txt      2006-09-04 13:05:51 UTC (rev 
3713)
+++ django/trunk/docs/templates_python.txt      2006-09-04 14:02:11 UTC (rev 
3714)
@@ -198,10 +198,20 @@
 How invalid variables are handled
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If a variable doesn't exist, the template system inserts the value of the
-``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''`` (the empty
-string) by default.
+Generally, if a variable doesn't exist, the template system inserts the
+value of the ``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''``
+(the empty string) by default.
 
+Filters that are applied to an invalid variable will only be applied if
+``TEMPLATE_STRING_IF_INVALID`` is set to ``''`` (the empty string). If
+``TEMPLATE_STRING_IF_INVALID`` is set to any other value, variable
+filters will be ignored.
+
+This behaviour is slightly different for the ``if``, ``for`` and ``regroup``
+template tags. If an invalid variable is provided to one of these template
+tags, the variable will be interpreted as ``None``. Filters are always
+applied to invalid variables within these template tags.
+
 Playing with Context objects
 ----------------------------
 

Modified: django/trunk/tests/regressiontests/templates/tests.py
===================================================================
--- django/trunk/tests/regressiontests/templates/tests.py       2006-09-04 
13:05:51 UTC (rev 3713)
+++ django/trunk/tests/regressiontests/templates/tests.py       2006-09-04 
14:02:11 UTC (rev 3714)
@@ -84,7 +84,7 @@
             'basic-syntax03': ("{{ first }} --- {{ second }}", {"first" : 1, 
"second" : 2}, "1 --- 2"),
 
             # Fail silently when a variable is not found in the current context
-            'basic-syntax04': ("as{{ missing }}df", {}, "asINVALIDdf"),
+            'basic-syntax04': ("as{{ missing }}df", {}, 
("asdf","asINVALIDdf")),
 
             # A variable may not contain more than one word
             'basic-syntax06': ("{{ multi word variable }}", {}, 
template.TemplateSyntaxError),
@@ -100,7 +100,7 @@
             'basic-syntax10': ("{{ var.otherclass.method }}", {"var": 
SomeClass()}, "OtherClass.method"),
 
             # Fail silently when a variable's attribute isn't found
-            'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, 
"INVALID"),
+            'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, 
("","INVALID")),
 
             # Raise TemplateSyntaxError when trying to access a variable 
beginning with an underscore
             'basic-syntax12': ("{{ var.__dict__ }}", {"var": SomeClass()}, 
template.TemplateSyntaxError),
@@ -116,10 +116,10 @@
             'basic-syntax18': ("{{ foo.bar }}", {"foo" : {"bar" : "baz"}}, 
"baz"),
 
             # Fail silently when a variable's dictionary key isn't found
-            'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, 
"INVALID"),
+            'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, 
("","INVALID")),
 
             # Fail silently when accessing a non-simple method
-            'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, 
"INVALID"),
+            'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, 
("","INVALID")),
 
             # Basic filter usage
             'basic-syntax21': ("{{ var|upper }}", {"var": "Django is the 
greatest!"}, "DJANGO IS THE GREATEST!"),
@@ -158,7 +158,7 @@
             'basic-syntax32': (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno 
}}', {"var": True}, 'yup yes'),
 
             # Fail silently for methods that raise an exception with a 
"silent_variable_failure" attribute
-            'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, 
"1INVALID2"),
+            'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, 
("12", "1INVALID2")),
 
             # In methods that raise an exception without a 
"silent_variable_attribute" set to True,
             # the exception propogates
@@ -464,6 +464,14 @@
             # translation of a constant string
             'i18n13': ('{{ _("Page not found") }}', {'LANGUAGE_CODE': 'de'}, 
'Seite nicht gefunden'),
 
+            ### HANDLING OF TEMPLATE_TAG_IF_INVALID 
###################################
+            
+            'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),
+            'invalidstr02': ('{{ var|default_if_none:"Foo" }}', {}, 
('','INVALID')),
+            'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, 
''),
+            'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 
'No'),
+            'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% 
endif %}', {}, 'Yes'),
+
             ### MULTILINE 
#############################################################
 
             'multiline01': ("""
@@ -507,7 +515,7 @@
                           '{{ item.foo }}' + \
                           '{% endfor %},' + \
                           '{% endfor %}',
-                          {}, 
'INVALID:INVALIDINVALIDINVALIDINVALIDINVALIDINVALIDINVALID,'),
+                          {}, ''),
 
             ### TEMPLATETAG TAG 
#######################################################
             'templatetag01': ('{% templatetag openblock %}', {}, '{%'),
@@ -592,30 +600,44 @@
         old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, False
         
         # Set TEMPLATE_STRING_IF_INVALID to a known string 
-        old_invalid, settings.TEMPLATE_STRING_IF_INVALID = 
settings.TEMPLATE_STRING_IF_INVALID, 'INVALID'
+        old_invalid = settings.TEMPLATE_STRING_IF_INVALID
     
         for name, vals in tests:
             install()
+            
+            if isinstance(vals[2], tuple):
+                normal_string_result = vals[2][0]
+                invalid_string_result = vals[2][1]
+            else:
+                normal_string_result = vals[2]
+                invalid_string_result = vals[2]
+                
             if 'LANGUAGE_CODE' in vals[1]:
                 activate(vals[1]['LANGUAGE_CODE'])
             else:
                 activate('en-us')
-            try:
-                output = 
loader.get_template(name).render(template.Context(vals[1]))
-            except Exception, e:
-                if e.__class__ != vals[2]:
-                    failures.append("Template test: %s -- FAILED. Got %s, 
exception: %s" % (name, e.__class__, e))
-                continue
+
+            for invalid_str, result in [('', normal_string_result),
+                                        ('INVALID', invalid_string_result)]:
+                settings.TEMPLATE_STRING_IF_INVALID = invalid_str
+                try:
+                    output = 
loader.get_template(name).render(template.Context(vals[1]))
+                except Exception, e:
+                    if e.__class__ != result:
+                        failures.append("Template test 
(TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s" % 
(invalid_str, name, e.__class__, e))
+                    continue
+                if output != result:
+                    failures.append("Template test 
(TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % 
(invalid_str, name, result, output))
+                    
             if 'LANGUAGE_CODE' in vals[1]:
                 deactivate()
-            if output != vals[2]:
-                    failures.append("Template test: %s -- FAILED. Expected %r, 
got %r" % (name, vals[2], output))
+            
         loader.template_source_loaders = old_template_loaders
         deactivate()
         settings.TEMPLATE_DEBUG = old_td
         settings.TEMPLATE_STRING_IF_INVALID = old_invalid
 
-        self.assertEqual(failures, [])
+        self.assertEqual(failures, [], '\n'.join(failures))
 
 if __name__ == "__main__":
     unittest.main()


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates
-~----------~----~----~----~------~----~------~--~---

Reply via email to