| 1 | # -*- encoding: utf-8 -*- |
|---|
| 2 | |
|---|
| 3 | try: |
|---|
| 4 | from django.template import Library, Node, NodeList, Template |
|---|
| 5 | from django.template.context import Context |
|---|
| 6 | register = Library() |
|---|
| 7 | except: |
|---|
| 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 | |
|---|
| 13 | try: |
|---|
| 14 | from ambidjangolib.apps.languages.models import Language |
|---|
| 15 | except: |
|---|
| 16 | from django.models import languages |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | class 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 | |
|---|
| 30 | def 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 | |
|---|
| 44 | register.tag('get_languages', do_get_languages) |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | def 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 | |
|---|
| 56 | register.filter('url_in_another_language', do_url_in_another_language) |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | class 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") |
|---|
| 120 | def 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) |
|---|
| 165 | do_for_languages = register.tag("forlanguages", do_for_languages) |
|---|