Commit 6b383afd authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixes #1338, Refs #1400, #2237 -- Modified variable resolution to allow...

Fixes #1338, Refs #1400, #2237 -- Modified variable resolution to allow template 'if' statements to work if TEMPLATE_STRING_IF_INVALID is set. Modified unit tests to force the use of this variable, so that returning '' isn't confused with an actual failure.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@3268 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 009f224e
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -543,11 +543,14 @@ class FilterExpression(object):
            raise TemplateSyntaxError, "Could not parse the remainder: %s" % token[upto:]
        self.var, self.filters = var, filters

    def resolve(self, context):
    def resolve(self, context, ignore_failures=False):
        try:
            obj = resolve_variable(self.var, context)
        except VariableDoesNotExist:
            obj = settings.TEMPLATE_STRING_IF_INVALID
            if ignore_failures:
                return None
            else:
                return settings.TEMPLATE_STRING_IF_INVALID
        for func, args in self.filters:
            arg_vals = []
            for lookup, arg in args:
+2 −2
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ class Context(object):
        for d in self.dicts:
            if d.has_key(key):
                return d[key]
        return settings.TEMPLATE_STRING_IF_INVALID
        raise KeyError(key)

    def __delitem__(self, key):
        "Delete a variable from the current context"
@@ -49,7 +49,7 @@ class Context(object):
                return True
        return False

    def get(self, key, otherwise):
    def get(self, key, otherwise=None):
        for d in self.dicts:
            if d.has_key(key):
                return d[key]
+14 −5
Original line number Diff line number Diff line
@@ -45,7 +45,10 @@ class FirstOfNode(Node):

    def render(self, context):
        for var in self.vars:
            try:
                value = resolve_variable(var, context)
            except VariableDoesNotExist:
                continue
            if value:
                return str(value)
        return ''
@@ -144,8 +147,14 @@ class IfEqualNode(Node):
        return "<IfEqualNode>"

    def render(self, context):
        try:
            val1 = resolve_variable(self.var1, context)
        except VariableDoesNotExist:
            val1 = None
        try:
            val2 = resolve_variable(self.var2, context)
        except VariableDoesNotExist:
            val2 = None
        if (self.negate and val1 != val2) or (not self.negate and val1 == val2):
            return self.nodelist_true.render(context)
        return self.nodelist_false.render(context)
@@ -177,7 +186,7 @@ class IfNode(Node):
        if self.link_type == IfNode.LinkTypes.or_:
            for ifnot, bool_expr in self.bool_exprs:
                try:
                    value = bool_expr.resolve(context)
                    value = bool_expr.resolve(context, True)
                except VariableDoesNotExist:
                    value = None
                if (value and not ifnot) or (ifnot and not value):
@@ -186,7 +195,7 @@ class IfNode(Node):
        else:
            for ifnot, bool_expr in self.bool_exprs:
                try:
                    value = bool_expr.resolve(context)
                    value = bool_expr.resolve(context, True)
                except VariableDoesNotExist:
                    value = None
                if not ((value and not ifnot) or (ifnot and not value)):
+10 −6
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ TEMPLATE_TESTS = {
    '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", {}, "asdf"),
    'basic-syntax04': ("as{{ missing }}df", {}, "asINVALIDdf"),

    # A variable may not contain more than one word
    'basic-syntax06': ("{{ multi word variable }}", {}, template.TemplateSyntaxError),
@@ -94,7 +94,7 @@ TEMPLATE_TESTS = {
    '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()}, ""),
    '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),
@@ -110,10 +110,10 @@ TEMPLATE_TESTS = {
    '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"}}, ""),
    'basic-syntax19': ("{{ foo.spam }}", {"foo" : {"bar" : "baz"}}, "INVALID"),

    # Fail silently when accessing a non-simple method
    'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ""),
    'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, "INVALID"),

    # Basic filter usage
    'basic-syntax21': ("{{ var|upper }}", {"var": "Django is the greatest!"}, "DJANGO IS THE GREATEST!"),
@@ -152,7 +152,7 @@ TEMPLATE_TESTS = {
    '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()}, "12"),
    'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, "1INVALID2"),

    # In methods that raise an exception without a "silent_variable_attribute" set to True,
    # the exception propogates
@@ -495,7 +495,7 @@ TEMPLATE_TESTS = {
                  '{{ item.foo }}' + \
                  '{% endfor %},' + \
                  '{% endfor %}',
                  {}, ''),
                  {}, 'INVALID:INVALIDINVALIDINVALIDINVALIDINVALIDINVALIDINVALID,'),

    ### TEMPLATETAG TAG #######################################################
    'templatetag01': ('{% templatetag openblock %}', {}, '{%'),
@@ -579,6 +579,9 @@ def run_tests(verbosity=0, standalone=False):

    # Turn TEMPLATE_DEBUG off, because tests assume that.
    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'
    
    for name, vals in tests:
        install()
        if 'LANGUAGE_CODE' in vals[1]:
@@ -609,6 +612,7 @@ def run_tests(verbosity=0, standalone=False):
    loader.template_source_loaders = old_template_loaders
    deactivate()
    settings.TEMPLATE_DEBUG = old_td
    settings.TEMPLATE_STRING_IF_INVALID = old_invalid

    if failed_tests and not standalone:
        msg = "Template tests %s failed." % failed_tests