Ticket #7711: new_switch_tag_enhancement.patch

File new_switch_tag_enhancement.patch, 4.6 KB (added by GabrielFalcao, 7 years ago)

A proposal os implementation

  • django/template/defaulttags.py

     
    11031103    parser.delete_first_token()
    11041104    return WithNode(var, name, nodelist)
    11051105do_with = register.tag('with', do_with)
     1106
     1107
     1108class SwitchNode(Node):
     1109    def __init__(self, var1, nodelist_true, nodelist_false):
     1110        self.comparison_base = Variable(var1)
     1111        self.nodelist_true = nodelist_true
     1112        self.nodelist_false = nodelist_false
     1113       
     1114    def __repr__(self):
     1115        return "<SwitchNode>"
     1116
     1117    def render(self, context):
     1118        try:
     1119            val1 = self.comparison_base.resolve(context)
     1120            context['%BASE_COMPARISON%'] =  val1
     1121        except VariableDoesNotExist:
     1122            raise TemplateSyntaxError("Could not resolve variable %r in current context" % \
     1123                                      self.comparison_base.var)
     1124        ok = False
     1125        for node in self.nodelist_true:
     1126            if isinstance(node, CaseNode):
     1127                if node.get_bool(context):
     1128                    ok = True
     1129        if ok:
     1130            return self.nodelist_true.render(context)
     1131        else:
     1132            return self.nodelist_false.render(context)
     1133       
     1134
     1135def do_switch(parser, token):
     1136    """
     1137    Create a context to use case-like coditional
     1138    template rendering.
     1139
     1140    For example::
     1141
     1142        {% switch person.name %}
     1143            {% case 'John Doe' %}
     1144                Hi! My name is John, the master!
     1145            {% endcase %}
     1146            {% case 'Mary Jane' %}
     1147                Hello! My name is Mary. Nice to meet you!
     1148            {% endcase %}           
     1149        {% default %}
     1150            Oh my God! I have no name!
     1151        {% endswitch %}
     1152    """
     1153   
     1154    bits = list(token.split_contents())
     1155    if len(bits) != 2:
     1156        raise TemplateSyntaxError, "%r takes one argument" % bits[0]
     1157    end_tag = 'end' + bits[0]
     1158    nodelist_true = parser.parse(('default', end_tag,))
     1159    token = parser.next_token()
     1160    if token.contents == 'default':
     1161        nodelist_false = parser.parse((end_tag,))
     1162        parser.delete_first_token()
     1163    else:
     1164        nodelist_false = NodeList()
     1165    return SwitchNode(bits[1], nodelist_true, nodelist_false)
     1166do_switch = register.tag('switch', do_switch)
     1167
     1168class CaseNode(Node):
     1169    def __init__(self, var, nodelist):
     1170        self.var = Variable(var)
     1171        self.nodelist = nodelist
     1172
     1173    def __repr__(self):
     1174        return "<CaseNode>"
     1175
     1176    def get_bool(self, context):
     1177        try:
     1178            val = self.var.resolve(context)
     1179        except VariableDoesNotExist:
     1180            val = None
     1181        if context.get("%BASE_COMPARISON%", None) == val:
     1182            return True
     1183        else:
     1184            return False
     1185       
     1186    def render(self, context):
     1187        if self.get_bool(context):
     1188            return self.nodelist.render(context)
     1189        else:
     1190            return NodeList().render(context)
     1191
     1192@register.tag   
     1193def do_case(parser, token):
     1194    bits = list(token.split_contents())
     1195    if len(bits) != 2:
     1196        raise TemplateSyntaxError, "%r takes one argument" % bits[0]
     1197    end_tag = 'end' + bits[0]
     1198    nodelist_true = parser.parse(('else', end_tag))
     1199    token = parser.next_token()
     1200    if token.contents == 'else':
     1201        nodelist_false = parser.parse((end_tag,))
     1202        parser.delete_first_token()
     1203    else:
     1204        nodelist_false = NodeList()
     1205    return CaseNode(bits[1], nodelist_true)
     1206do_case = register.tag('case', do_case)
  • docs/templates.txt

     
    12181218The populated variable (in the example above, ``total``) is only available
    12191219between the ``{% with %}`` and ``{% endwith %}`` tags.
    12201220
     1221switch
     1222~~~~
     1223
     1224**New in Django development version**
     1225
     1226Stores a variable for internal comparison with a ``{% case %}`` tag.
     1227This is useful comparing an "expensive" sequence of instructions ``{% ifequal %}``.
     1228
     1229For example::
     1230
     1231    {% switch person.name %}
     1232        {% case 'John Doe' %}
     1233            Hi! My name is John, the master!
     1234        {% endcase %}
     1235        {% case 'Mary Jane' %}
     1236            Hello! My name is Mary. Nice to meet you!
     1237        {% endcase %}           
     1238    {% default %}
     1239        Oh my God! I have no name!
     1240    {% endswitch %}
     1241
     1242The tag ``case`` above SHALL be used only within  ``{% switch %}`` and ``{% endswitch %}`` tags.
     1243
     1244
    12211245Built-in filter reference
    12221246-------------------------
    12231247
Back to Top