Django

Code

Changeset 3714

Show
Ignore:
Timestamp:
09/04/06 09:02:11 (2 years ago)
Author:
russellm
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r3694 r3714  
    105105    Jason McBrayer <http://www.carcosa.net/jason/> 
    106106    michael.mcewan@gmail.com 
    107     mir@noris.de 
    108107    mmarshall 
    109108    Eric Moritz <http://eric.themoritzfamily.com/> 
     
    122121    Daniel Poelzleithner <http://poelzi.org/> 
    123122    J. Rademaker 
     123    Michael Radziej <mir@noris.de> 
    124124    Brian Ray <http://brianray.chipy.org/> 
    125125    rhettg@gmail.com 
     
    128128    David Schein 
    129129    Pete Shinners <pete@shinners.org> 
     130    SmileyChris <smileychris@gmail.com> 
    130131    sopel 
    131132    Thomas Steinacher <tom@eggdrop.ch> 
  • django/trunk/django/template/defaulttags.py

    r3707 r3714  
    8787        context.push() 
    8888        try: 
    89             values = self.sequence.resolve(context
     89            values = self.sequence.resolve(context, True
    9090        except VariableDoesNotExist: 
    9191            values = [] 
     
    213213 
    214214    def render(self, context): 
    215         obj_list = self.target.resolve(context
    216         if obj_list == '': # target_var wasn't found in context; fail silently 
     215        obj_list = self.target.resolve(context, True
     216        if obj_list == None: # target_var wasn't found in context; fail silently 
    217217            context[self.var_name] = [] 
    218218            return '' 
    219219        output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]} 
    220220        for obj in obj_list: 
    221             grouper = self.expression.resolve(Context({'var': obj})
     221            grouper = self.expression.resolve(Context({'var': obj}), True
    222222            # TODO: Is this a sensible way to determine equality? 
    223223            if output and repr(output[-1]['grouper']) == repr(grouper): 
  • django/trunk/django/template/__init__.py

    r3711 r3714  
    550550        except VariableDoesNotExist: 
    551551            if ignore_failures: 
    552                 return None 
     552                obj = None 
    553553            else: 
    554                 return settings.TEMPLATE_STRING_IF_INVALID 
     554                if settings.TEMPLATE_STRING_IF_INVALID: 
     555                    return settings.TEMPLATE_STRING_IF_INVALID 
     556                else: 
     557                    obj = settings.TEMPLATE_STRING_IF_INVALID 
    555558        for func, args in self.filters: 
    556559            arg_vals = [] 
  • django/trunk/docs/templates_python.txt

    r3685 r3714  
    199199~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    200200 
    201 If a variable doesn't exist, the template system inserts the value of the 
    202 ``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''`` (the empty 
    203 string) by default. 
     201Generally, if a variable doesn't exist, the template system inserts the 
     202value of the ``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''`` 
     203(the empty string) by default. 
     204 
     205Filters that are applied to an invalid variable will only be applied if 
     206``TEMPLATE_STRING_IF_INVALID`` is set to ``''`` (the empty string). If 
     207``TEMPLATE_STRING_IF_INVALID`` is set to any other value, variable 
     208filters will be ignored. 
     209 
     210This behaviour is slightly different for the ``if``, ``for`` and ``regroup`` 
     211template tags. If an invalid variable is provided to one of these template 
     212tags, the variable will be interpreted as ``None``. Filters are always 
     213applied to invalid variables within these template tags. 
    204214 
    205215Playing with Context objects 
  • django/trunk/tests/regressiontests/templates/tests.py

    r3661 r3714  
    8585 
    8686            # Fail silently when a variable is not found in the current context 
    87             'basic-syntax04': ("as{{ missing }}df", {}, "asINVALIDdf"), 
     87            'basic-syntax04': ("as{{ missing }}df", {}, ("asdf","asINVALIDdf")), 
    8888 
    8989            # A variable may not contain more than one word 
     
    101101 
    102102            # Fail silently when a variable's attribute isn't found 
    103             'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, "INVALID"), 
     103            'basic-syntax11': ("{{ var.blech }}", {"var": SomeClass()}, ("","INVALID")), 
    104104 
    105105            # Raise TemplateSyntaxError when trying to access a variable beginning with an underscore 
     
    117117 
    118118            # Fail silently when a variable's dictionary key isn't found 
    119             'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, "INVALID"), 
     119            'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, ("","INVALID")), 
    120120 
    121121            # Fail silently when accessing a non-simple method 
    122             'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, "INVALID"), 
     122            'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ("","INVALID")), 
    123123 
    124124            # Basic filter usage 
     
    159159 
    160160            # Fail silently for methods that raise an exception with a "silent_variable_failure" attribute 
    161             'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, "1INVALID2"), 
     161            'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, ("12", "1INVALID2")), 
    162162 
    163163            # In methods that raise an exception without a "silent_variable_attribute" set to True, 
     
    464464            # translation of a constant string 
    465465            'i18n13': ('{{ _("Page not found") }}', {'LANGUAGE_CODE': 'de'}, 'Seite nicht gefunden'), 
     466 
     467            ### HANDLING OF TEMPLATE_TAG_IF_INVALID ################################### 
     468             
     469            'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')), 
     470            'invalidstr02': ('{{ var|default_if_none:"Foo" }}', {}, ('','INVALID')), 
     471            'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, ''), 
     472            'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 'No'), 
     473            'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% endif %}', {}, 'Yes'), 
    466474 
    467475            ### MULTILINE ############################################################# 
     
    508516                          '{% endfor %},' + \ 
    509517                          '{% endfor %}', 
    510                           {}, 'INVALID:INVALIDINVALIDINVALIDINVALIDINVALIDINVALIDINVALID,'), 
     518                          {}, ''), 
    511519 
    512520            ### TEMPLATETAG TAG ####################################################### 
     
    593601         
    594602        # Set TEMPLATE_STRING_IF_INVALID to a known string  
    595         old_invalid, settings.TEMPLATE_STRING_IF_INVALID = settings.TEMPLATE_STRING_IF_INVALID, 'INVALID' 
     603        old_invalid = settings.TEMPLATE_STRING_IF_INVALID 
    596604     
    597605        for name, vals in tests: 
    598606            install() 
     607             
     608            if isinstance(vals[2], tuple): 
     609                normal_string_result = vals[2][0] 
     610                invalid_string_result = vals[2][1] 
     611            else: 
     612                normal_string_result = vals[2] 
     613                invalid_string_result = vals[2] 
     614                 
    599615            if 'LANGUAGE_CODE' in vals[1]: 
    600616                activate(vals[1]['LANGUAGE_CODE']) 
    601617            else: 
    602618                activate('en-us') 
    603             try: 
    604                 output = loader.get_template(name).render(template.Context(vals[1])) 
    605             except Exception, e: 
    606                 if e.__class__ != vals[2]: 
    607                     failures.append("Template test: %s -- FAILED. Got %s, exception: %s" % (name, e.__class__, e)) 
    608                 continue 
     619 
     620            for invalid_str, result in [('', normal_string_result), 
     621                                        ('INVALID', invalid_string_result)]: 
     622                settings.TEMPLATE_STRING_IF_INVALID = invalid_str 
     623                try: 
     624                    output = loader.get_template(name).render(template.Context(vals[1])) 
     625                except Exception, e: 
     626                    if e.__class__ != result: 
     627                        failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s" % (invalid_str, name, e.__class__, e)) 
     628                    continue 
     629                if output != result: 
     630                    failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (invalid_str, name, result, output)) 
     631                     
    609632            if 'LANGUAGE_CODE' in vals[1]: 
    610633                deactivate() 
    611             if output != vals[2]: 
    612                     failures.append("Template test: %s -- FAILED. Expected %r, got %r" % (name, vals[2], output)) 
     634             
    613635        loader.template_source_loaders = old_template_loaders 
    614636        deactivate() 
     
    616638        settings.TEMPLATE_STRING_IF_INVALID = old_invalid 
    617639 
    618         self.assertEqual(failures, []
     640        self.assertEqual(failures, [], '\n'.join(failures)
    619641 
    620642if __name__ == "__main__":