Ticket #5756: 5756.2.patch

File 5756.2.patch, 6.2 KB (added by akaihola, 7 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)
Back to Top