Entry http://webnewage.org/media/upload/filecache/switchcase.py | Highlight | highlightit.org

Highlighted url: http://webnewage.org/media/upload/filecache/switchcase.py

Type: Python

1
# -*- coding: utf-8 -*-
2
#--------------------------------
3
#$Date$
4
#$Author$
5
#$Revision$
6
#--------------------------------
7
#Copyright (C) 2007 Alexander Koshelev (daevaorn@gmail.com)
8
"""
9
    Switch/case/default tag for Django.
10
    Based on original idea of jacobian's snippest http://www.djangosnippets.org/snippets/300/
11
    
12
    Usage::
13
    
14
    {% load switchcase %}
15
    {% switch meal %}
16
        {% case "spam" %}...{% endcase %}
17
        {% case "eggs" "appels"%}...{% endcase %}
18
        {% default  %}...{% enddefault %}
19
    {% endswitch %}
20
"""
21
from django import template
22
    
23
register = template.Library()
24
25
@register.tag
26
def switch(parser, token):
27
    """
28
        Switch tag.  Usage::
29
        
30
            {% switch meal %}
31
                {% case "spam" %}...{% endcase %}
32
                {% case "eggs" %}...{% endcase %}
33
            {% endswitch %}
34
            
35
        Note that ``{% case %}`` arguments can be variables if you like (as can
36
        switch arguments, buts that's a bit silly).
37
    """
38
    # Parse out the arguments.
39
    args = token.split_contents()
40
    if len(args) != 2:
41
        raise template.TemplateSyntaxError("%s tag tags exactly 2 arguments." % args[0])
42
        
43
    # Pull out all the children of the switch tag (until {% endswitch %}).
44
    childnodes = parser.parse(("endswitch",))
45
        
46
    # Remove the {% endswitch %} node so it doesn't get parsed twice.
47
    parser.delete_first_token()
48
        
49
    # We just care about case children; all other direct children get ignored.
50
    casenodes = childnodes.get_nodes_by_type(CaseNode)
51
    default = childnodes.get_nodes_by_type(DefaultNode)
52
    assert( len( default) < 2 )
53
    
54
        
55
    return SwitchNode(args[1], casenodes, len( default ) and default[ 0 ] or None )
56
        
57
@register.tag
58
def case(parser, token):
59
    """
60
        Case tag. Used only inside ``{% switch %}`` tags, so see above for those docs.
61
    """
62
    args = token.split_contents()
63
    #assert len(args) == 2
64
    
65
    # Same dance as above, except this time we care about all the child nodes
66
    children = parser.parse(("endcase",))
67
    parser.delete_first_token()
68
    return CaseNode(args[1:], children)
69
70
@register.tag
71
def default(parser, token ):
72
    """
73
    """
74
    args = token.split_contents()
75
    assert len(args) == 1
76
77
    children = parser.parse(("enddefault",))
78
    parser.delete_first_token()
79
80
    return DefaultNode(children)
81
 
82
class SwitchNode(template.Node):
83
    def __init__(self, value, cases, default):
84
        self.value = value
85
        self.cases = cases
86
        self.default = default
87
            
88
    def render(self, context):
89
        # Resolve the value; if it's a non-existant variable don't even bother
90
        # checking the values of the cases since they'll never match.
91
        try:
92
            value = template.resolve_variable(self.value, context)
93
        except template.VariableDoesNotExist:
94
            return ""
95
            
96
        # Check each case, and if it matches return the rendered content
97
        # of that case (short-circuit).
98
        for case in self.cases:
99
            if case.equals(value, context):
100
                return case.render(context)
101
        if self.default:
102
            return self.default.render( context )
103
            
104
        # No matches and no default; render nothing.
105
        return ""
106
            
107
class CaseNode(template.Node):
108
    def __init__(self, values, childnodes):
109
        self.values = values
110
        self.childnodes = childnodes
111
            
112
    def equals(self, otherval, context):
113
        """
114
        Check to see if this case's value equals some other value. This is
115
        called from ``SwitchNode.render()``, above.
116
        """
117
        try:
118
            for value in self.values:
119
                if template.resolve_variable( value, context) == otherval:
120
                    return True
121
            return False
122
        except template.VariableDoesNotExist:
123
            # If the variable doesn't exist, it doesn't equal anything.
124
            return False
125
         
126
    def render(self, context):
127
        """Render this particular case, which means rendering its child nodes."""
128
        return self.childnodes.render(context)
129
    
130
class DefaultNode( template.Node ):
131
    def __init__(self, childnodes):
132
        self.childnodes = childnodes
133
134
    def render(self, context):
135
        """Render this default, which means rendering its child nodes."""
136
        return self.childnodes.render(context)
137

Home Feedback Terms of use