Django

Code

root/django/branches/newforms-admin/django/views/i18n.py

Revision 7378, 6.4 kB (checked in by jkocherhans, 8 months ago)

newforms-admin: Merged from trunk up to [7377].

  • Property svn:eol-style set to native
Line 
1 from django import http
2 from django.utils.translation import check_for_language, activate, to_locale, get_language
3 from django.utils.text import javascript_quote
4 from django.conf import settings
5 import os
6 import gettext as gettext_module
7
8 def set_language(request):
9     """
10     Redirect to a given url while setting the chosen language in the
11     session or cookie. The url and the language code need to be
12     specified in the request parameters.
13
14     Since this view changes how the user will see the rest of the site, it must
15     only be accessed as a POST request. If called as a GET request, it will
16     redirect to the page in the request (the 'next' parameter) without changing
17     any state.
18     """
19     next = request.REQUEST.get('next', None)
20     if not next:
21         next = request.META.get('HTTP_REFERER', None)
22     if not next:
23         next = '/'
24     response = http.HttpResponseRedirect(next)
25     if request.method == 'POST':
26         lang_code = request.POST.get('language', None)
27         if lang_code and check_for_language(lang_code):
28             if hasattr(request, 'session'):
29                 request.session['django_language'] = lang_code
30             else:
31                 response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
32     return response
33
34 NullSource = """
35 /* gettext identity library */
36
37 function gettext(msgid) { return msgid; }
38 function ngettext(singular, plural, count) { return (count == 1) ? singular : plural; }
39 function gettext_noop(msgid) { return msgid; }
40 """
41
42 LibHead = """
43 /* gettext library */
44
45 var catalog = new Array();
46 """
47
48 LibFoot = """
49
50 function gettext(msgid) {
51   var value = catalog[msgid];
52   if (typeof(value) == 'undefined') {
53     return msgid;
54   } else {
55     return (typeof(value) == 'string') ? value : value[0];
56   }
57 }
58
59 function ngettext(singular, plural, count) {
60   value = catalog[singular];
61   if (typeof(value) == 'undefined') {
62     return (count == 1) ? singular : plural;
63   } else {
64     return value[pluralidx(count)];
65   }
66 }
67
68 function gettext_noop(msgid) { return msgid; }
69 """
70
71 SimplePlural = """
72 function pluralidx(count) { return (count == 1) ? 0 : 1; }
73 """
74
75 InterPolate = r"""
76 function interpolate(fmt, obj, named) {
77   if (named) {
78     return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
79   } else {
80     return fmt.replace(/%s/g, function(match){return String(obj.shift())});
81   }
82 }
83 """
84
85 PluralIdx = r"""
86 function pluralidx(n) {
87   var v=%s;
88   if (typeof(v) == 'boolean') {
89     return v ? 1 : 0;
90   } else {
91     return v;
92   }
93 }
94 """
95
96 def null_javascript_catalog(request, domain=None, packages=None):
97     """
98     Returns "identity" versions of the JavaScript i18n functions -- i.e.,
99     versions that don't actually do anything.
100     """
101     return http.HttpResponse(NullSource + InterPolate, 'text/javascript')
102
103 def javascript_catalog(request, domain='djangojs', packages=None):
104     """
105     Returns the selected language catalog as a javascript library.
106
107     Receives the list of packages to check for translations in the
108     packages parameter either from an infodict or as a +-delimited
109     string from the request. Default is 'django.conf'.
110
111     Additionally you can override the gettext domain for this view,
112     but usually you don't want to do that, as JavaScript messages
113     go to the djangojs domain. But this might be needed if you
114     deliver your JavaScript source from Django templates.
115     """
116     if request.GET:
117         if 'language' in request.GET:
118             if check_for_language(request.GET['language']):
119                 activate(request.GET['language'])
120     if packages is None:
121         packages = ['django.conf']
122     if type(packages) in (str, unicode):
123         packages = packages.split('+')
124     packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
125     default_locale = to_locale(settings.LANGUAGE_CODE)
126     locale = to_locale(get_language())
127     t = {}
128     paths = []
129     # first load all english languages files for defaults
130     for package in packages:
131         p = __import__(package, {}, {}, [''])
132         path = os.path.join(os.path.dirname(p.__file__), 'locale')
133         paths.append(path)
134         try:
135             catalog = gettext_module.translation(domain, path, ['en'])
136             t.update(catalog._catalog)
137         except IOError:
138             # 'en' catalog was missing. This is harmless.
139             pass
140     # next load the settings.LANGUAGE_CODE translations if it isn't english
141     if default_locale != 'en':
142         for path in paths:
143             try:
144                 catalog = gettext_module.translation(domain, path, [default_locale])
145             except IOError:
146                 catalog = None
147             if catalog is not None:
148                 t.update(catalog._catalog)
149     # last load the currently selected language, if it isn't identical to the default.
150     if locale != default_locale:
151         for path in paths:
152             try:
153                 catalog = gettext_module.translation(domain, path, [locale])
154             except IOError:
155                 catalog = None
156             if catalog is not None:
157                 t.update(catalog._catalog)
158     src = [LibHead]
159     plural = None
160     if '' in t:
161         for l in t[''].split('\n'):
162             if l.startswith('Plural-Forms:'):
163                 plural = l.split(':',1)[1].strip()
164     if plural is not None:
165         # this should actually be a compiled function of a typical plural-form:
166         # Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
167         plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1]
168         src.append(PluralIdx % plural)
169     else:
170         src.append(SimplePlural)
171     csrc = []
172     pdict = {}
173     for k, v in t.items():
174         if k == '':
175             continue
176         if type(k) in (str, unicode):
177             csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v)))
178         elif type(k) == tuple:
179             if k[0] not in pdict:
180                 pdict[k[0]] = k[1]
181             else:
182                 pdict[k[0]] = max(k[1], pdict[k[0]])
183             csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v)))
184         else:
185             raise TypeError, k
186     csrc.sort()
187     for k,v in pdict.items():
188         src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1))))
189     src.extend(csrc)
190     src.append(LibFoot)
191     src.append(InterPolate)
192     src = ''.join(src)
193     return http.HttpResponse(src, 'text/javascript')
Note: See TracBrowser for help on using the browser.