root/apps/languages/templatetags/get_languages.py @ 1

Revision 1, 6.1 kB (checked in by akaihola, 4 years ago)

Initial repository setup

Line 
1# -*- encoding: utf-8 -*-
2
3try:
4    from django.template import Library, Node, NodeList, Template
5    from django.template.context import Context
6    register = Library()
7except:
8    from django.core.template import Node, NodeList, Template, Context
9    from django.core import template
10    from django.core.template import Context
11    register = template.Library()
12
13try:
14    from ambidjangolib.apps.languages.models import Language
15except:
16    from django.models import languages
17
18
19class LanguagesNode(Node):
20    def __init__(self, varname):
21        self.varname = varname
22
23    def render(self, context):
24        try:
25            context[self.varname] = Language.objects.all()
26        except:
27            context[self.varname] = languages.get_list()
28        return ''
29
30def do_get_languages(parser, token):
31    """
32    {% get_languages as languages %}
33    """
34    print "do_get_languages"
35    bits = token.contents.split()
36    if len(bits) != 3:
37        raise TemplateSyntaxError, \
38              "'%s' tag takes two arguments" % bits[0]
39    if bits[1] != 'as':
40        raise TemplateSyntaxError, \
41              "First argument to '%s' tag must be 'as'" % bits[0]
42    return LanguagesNode(bits[2])
43
44register.tag('get_languages', do_get_languages)
45
46
47def do_url_in_another_language(url, language_code):
48    """
49    url in another language documentation here
50
51    url must be /<language_code>/<path>
52    """
53    current_language, path = url.split('/', 2)[1:]
54    return '/%s/%s' % (language_code, path)
55
56register.filter('url_in_another_language', do_url_in_another_language)
57
58
59
60
61class ForLanguagesNode(Node):
62    def __init__(self, omit_current, nodelist_loop):
63        self.omit_current  = omit_current
64        self.nodelist_loop = nodelist_loop
65
66    def __repr__(self):
67        if self.omit_current: omit_current = ', omit current'
68        else                : omit_current = ''
69        return "<ForLanguages Node, tail_len: %d%s>" % \
70            (len(self.nodelist_loop), omit_current)
71
72    def __iter__(self):
73        for node in self.nodelist_loop: yield node
74
75    def get_nodes_by_type(self, nodetype):
76        nodes = []
77        if isinstance(self, nodetype): nodes.append(self)
78        nodes.extend(self.nodelist_loop.get_nodes_by_type(nodetype))
79        return nodes
80
81    def render(self, context):
82        nodelist = NodeList()
83        if context.has_key('forloop'): parentloop = context['forloop']
84        else                         : parentloop = {}
85        context.push()
86        criteria = {}
87        try:
88            Language.objects
89            if self.omit_current: criteria['code'] = context['LANGUAGE_CODE']
90            values = Language.objects.exclude(**criteria)
91        except:
92            if self.omit_current: criteria['code__ne'] = context['LANGUAGE_CODE']
93            values = languages.get_list(**criteria)
94        len_values = len(values)
95        for i, language in enumerate(values):
96            context['forloop'] = {
97                # shortcuts for current loop iteration number
98                'counter0': i,
99                'counter': i+1,
100                # reverse counter iteration numbers
101                'revcounter': len_values - i,
102                'revcounter0': len_values - i - 1,
103                # boolean values designating first and last times through loop
104                'first': (i == 0),
105                'last': (i == len_values - 1),
106                'parentloop': parentloop,
107                # language specifics
108                'language': language,
109                'url': '/i18n/setlang?language=%s&next=%s' % \
110                (language.code,
111                 do_url_in_another_language(context['request_path'],
112                                            language.code)),
113            }
114            for node in self.nodelist_loop:
115                nodelist.append(node.render(context))
116        context.pop()
117        return nodelist.render(context)
118
119#@register.tag(name="forlanguages")
120def do_for_languages(parser, token):
121    """
122   
123    Loop over available languages.
124
125    For example, to display a list of athletes given ``athlete_list``::
126
127        <ul>
128        {% forlanguages omit_current %}
129            <li>{{ forloop.language.code }}</li>
130        {% endforlanguages %}
131        </ul>
132
133    You can also loop over a list in reverse by using
134    ``{% for obj in list reversed %}``.
135
136    The for loop sets a number of variables available within the loop:
137
138        ==========================  ================================================
139        Variable                    Description
140        ==========================  ================================================
141        ``forloop.counter``         The current iteration of the loop (1-indexed)
142        ``forloop.counter0``        The current iteration of the loop (0-indexed)
143        ``forloop.revcounter``      The number of iterations from the end of the
144                                    loop (1-indexed)
145        ``forloop.revcounter0``     The number of iterations from the end of the
146                                    loop (0-indexed)
147        ``forloop.first``           True if this is the first time through the loop
148        ``forloop.last``            True if this is the last time through the loop
149        ``forloop.parentloop``      For nested loops, this is the loop "above" the
150                                    current one
151        ``forloop.language``        The current language in the loop
152        ``forloop.url``             The current URL for the current language
153        ==========================  ================================================
154
155    """
156    bits = token.contents.split()
157    if len(bits) == 2 and bits[1] != 'omit_current':
158        raise TemplateSyntaxError, "'for' statements with two words should end in 'omit_current': %s" % token.contents
159    if len(bits) not in (1, 2):
160        raise TemplateSyntaxError, "'for' statements should have either one or two words: %s" % token.contents
161    omit_current = (len(bits) == 2)
162    nodelist_loop = parser.parse(('endforlanguages',))
163    parser.delete_first_token()
164    return ForLanguagesNode(omit_current, nodelist_loop)
165do_for_languages = register.tag("forlanguages", do_for_languages)
Note: See TracBrowser for help on using the browser.