Code

Ticket #5756: 5756.2.patch

File 5756.2.patch, 6.2 KB (added by akaihola, 6 years ago)

Filters as arguments for cycle, firstof, ifchanged, ifequal and include. Depends on #7295.

  • django/template/defaulttags.py

     
    3838        return '' 
    3939 
    4040class CycleNode(Node): 
    41     def __init__(self, cyclevars, variable_name=None): 
    42         self.cycle_iter = itertools_cycle(cyclevars) 
     41    def __init__(self, cyclevals, variable_name=None): 
     42        self.cycle_iter = itertools_cycle(cyclevals) 
    4343        self.variable_name = variable_name 
    4444 
    4545    def render(self, context): 
    4646        value = self.cycle_iter.next() 
    47         value = Variable(value).resolve(context) 
     47        value = value.resolve(context, True) 
    4848        if self.variable_name: 
    4949            context[self.variable_name] = value 
    5050        return value 
     
    7070        return filtered 
    7171 
    7272class FirstOfNode(Node): 
    73     def __init__(self, vars): 
    74         self.vars = map(Variable, vars) 
     73    def __init__(self, vals): 
     74        self.vals = vals 
    7575 
    7676    def render(self, context): 
    77         for var in self.vars: 
    78             try: 
    79                 value = var.resolve(context) 
    80             except VariableDoesNotExist: 
    81                 continue 
     77        for val in self.vals: 
     78            value = val.resolve(context, True) 
    8279            if value: 
    8380                return smart_unicode(value) 
    8481        return u'' 
     
    158155        return nodelist.render(context) 
    159156 
    160157class IfChangedNode(Node): 
    161     def __init__(self, nodelist, *varlist): 
     158    def __init__(self, nodelist, *vallist): 
    162159        self.nodelist = nodelist 
    163160        self._last_seen = None 
    164         self._varlist = map(Variable, varlist) 
     161        self._vallist = vallist 
    165162 
    166163    def render(self, context): 
    167164        if 'forloop' in context and context['forloop']['first']: 
    168165            self._last_seen = None 
    169166        try: 
    170             if self._varlist: 
     167            if self._vallist: 
    171168                # Consider multiple parameters.  This automatically behaves 
    172169                # like an OR evaluation of the multiple variables. 
    173                 compare_to = [var.resolve(context) for var in self._varlist] 
     170                compare_to = [val.resolve(context, True) for val in self._vallist] 
    174171            else: 
    175172                compare_to = self.nodelist.render(context) 
    176173        except VariableDoesNotExist: 
     
    188185            return '' 
    189186 
    190187class IfEqualNode(Node): 
    191     def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): 
    192         self.var1, self.var2 = Variable(var1), Variable(var2) 
     188    def __init__(self, val1, val2, nodelist_true, nodelist_false, negate): 
     189        self.val1, self.val2 = val1, val2 
    193190        self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false 
    194191        self.negate = negate 
    195192 
     
    197194        return "<IfEqualNode>" 
    198195 
    199196    def render(self, context): 
    200         try: 
    201             val1 = self.var1.resolve(context) 
    202         except VariableDoesNotExist: 
    203             val1 = None 
    204         try: 
    205             val2 = self.var2.resolve(context) 
    206         except VariableDoesNotExist: 
    207             val2 = None 
     197        val1, val2 = (self.val1.resolve(context, True), self.val2.resolve(context, True)) 
    208198        if (self.negate and val1 != val2) or (not self.negate and val1 == val2): 
    209199            return self.nodelist_true.render(context) 
    210200        return self.nodelist_false.render(context) 
     
    489479 
    490480    if len(args) > 4 and args[-2] == 'as': 
    491481        name = args[-1] 
    492         node = CycleNode(args[1:-2], name) 
     482        values = [parser.compile_filter(arg) for arg in args[1:-2]] 
     483        node = CycleNode(values, name) 
    493484        if not hasattr(parser, '_namedCycleNodes'): 
    494485            parser._namedCycleNodes = {} 
    495486        parser._namedCycleNodes[name] = node 
    496487    else: 
    497         node = CycleNode(args[1:]) 
     488        values = [parser.compile_filter(arg) for arg in args[1:]] 
     489        node = CycleNode(values) 
    498490    return node 
    499491cycle = register.tag(cycle) 
    500492 
     
    569561    if len(bits) < 1: 
    570562        raise TemplateSyntaxError("'firstof' statement requires at least one" 
    571563                                  " argument") 
    572     return FirstOfNode(bits) 
     564    values = [parser.compile_filter(bit) for bit in bits] 
     565    return FirstOfNode(values) 
    573566firstof = register.tag(firstof) 
    574567 
    575568#@register.tag(name="for") 
     
    640633    if len(bits) != 3: 
    641634        raise TemplateSyntaxError, "%r takes two arguments" % bits[0] 
    642635    end_tag = 'end' + bits[0] 
     636    val1 = parser.compile_filter(bits[1]) 
     637    val2 = parser.compile_filter(bits[2]) 
    643638    nodelist_true = parser.parse(('else', end_tag)) 
    644639    token = parser.next_token() 
    645640    if token.contents == 'else': 
     
    647642        parser.delete_first_token() 
    648643    else: 
    649644        nodelist_false = NodeList() 
    650     return IfEqualNode(bits[1], bits[2], nodelist_true, nodelist_false, negate) 
     645    return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate) 
    651646 
    652647#@register.tag 
    653648def ifequal(parser, token): 
     
    803798    bits = token.contents.split() 
    804799    nodelist = parser.parse(('endifchanged',)) 
    805800    parser.delete_first_token() 
    806     return IfChangedNode(nodelist, *bits[1:]) 
     801    values = [parser.compile_filter(bit) for bit in bits[1:]] 
     802    return IfChangedNode(nodelist, *values) 
    807803ifchanged = register.tag(ifchanged) 
    808804 
    809805#@register.tag 
  • django/template/loader_tags.py

     
    110110 
    111111class IncludeNode(Node): 
    112112    def __init__(self, template_name): 
    113         self.template_name = Variable(template_name) 
     113        self.template_name = template_name 
    114114 
    115115    def render(self, context): 
    116116        try: 
    117             template_name = self.template_name.resolve(context) 
     117            template_name = self.template_name.resolve(context, True) 
    118118            t = get_template(template_name) 
    119119            return t.render(context) 
    120120        except TemplateSyntaxError, e: 
     
    181181    path = bits[1] 
    182182    if path[0] in ('"', "'") and path[-1] == path[0]: 
    183183        return ConstantIncludeNode(path[1:-1]) 
    184     return IncludeNode(bits[1]) 
     184    path_value = parser.compile_filter(path) 
     185    return IncludeNode(path_value) 
    185186 
    186187register.tag('block', do_block) 
    187188register.tag('extends', do_extends)