2 import gettext
as gettext_module
4 from django
import http
5 from django
.conf
import settings
6 from django
.utils
import importlib
7 from django
.utils
.translation
import check_for_language
, activate
, to_locale
, get_language
8 from django
.utils
.text
import javascript_quote
9 from django
.utils
.encoding
import smart_unicode
10 from django
.utils
.formats
import get_format_modules
, get_format
12 def set_language(request
):
14 Redirect to a given url while setting the chosen language in the
15 session or cookie. The url and the language code need to be
16 specified in the request parameters.
18 Since this view changes how the user will see the rest of the site, it must
19 only be accessed as a POST request. If called as a GET request, it will
20 redirect to the page in the request (the 'next' parameter) without changing
23 next
= request
.REQUEST
.get('next', None)
25 next
= request
.META
.get('HTTP_REFERER', None)
28 response
= http
.HttpResponseRedirect(next
)
29 if request
.method
== 'POST':
30 lang_code
= request
.POST
.get('language', None)
31 if lang_code
and check_for_language(lang_code
):
32 if hasattr(request
, 'session'):
33 request
.session
['django_language'] = lang_code
35 response
.set_cookie(settings
.LANGUAGE_COOKIE_NAME
, lang_code
)
40 Returns all formats strings required for i18n to work
43 'DATE_FORMAT', 'DATETIME_FORMAT', 'TIME_FORMAT',
44 'YEAR_MONTH_FORMAT', 'MONTH_DAY_FORMAT', 'SHORT_DATE_FORMAT',
45 'SHORT_DATETIME_FORMAT', 'FIRST_DAY_OF_WEEK', 'DECIMAL_SEPARATOR',
46 'THOUSAND_SEPARATOR', 'NUMBER_GROUPING',
47 'DATE_INPUT_FORMATS', 'TIME_INPUT_FORMATS', 'DATETIME_INPUT_FORMATS'
50 for module
in [settings
] + get_format_modules(reverse
=True):
51 for attr
in FORMAT_SETTINGS
:
52 result
[attr
] = get_format(attr
)
54 for k
, v
in result
.items():
55 if isinstance(v
, (basestring
, int)):
56 src
.append("formats['%s'] = '%s';\n" % (javascript_quote(k
), javascript_quote(smart_unicode(v
))))
57 elif isinstance(v
, (tuple, list)):
58 v
= [javascript_quote(smart_unicode(value
)) for value
in v
]
59 src
.append("formats['%s'] = ['%s'];\n" % (javascript_quote(k
), "', '".join(v
)))
63 /* gettext identity library */
65 function gettext(msgid) { return msgid; }
66 function ngettext(singular, plural, count) { return (count == 1) ? singular : plural; }
67 function gettext_noop(msgid) { return msgid; }
68 function pgettext(context, msgid) { return msgid; }
69 function npgettext(context, singular, plural, count) { return (count == 1) ? singular : plural; }
75 var catalog = new Array();
80 function gettext(msgid) {
81 var value = catalog[msgid];
82 if (typeof(value) == 'undefined') {
85 return (typeof(value) == 'string') ? value : value[0];
89 function ngettext(singular, plural, count) {
90 value = catalog[singular];
91 if (typeof(value) == 'undefined') {
92 return (count == 1) ? singular : plural;
94 return value[pluralidx(count)];
98 function gettext_noop(msgid) { return msgid; }
100 function pgettext(context, msgid) {
101 var value = gettext(context + '\x04' + msgid);
102 if (value.indexOf('\x04') != -1) {
108 function npgettext(context, singular, plural, count) {
109 var value = ngettext(context + '\x04' + singular, context + '\x04' + plural, count);
110 if (value.indexOf('\x04') != -1) {
111 value = ngettext(singular, plural, count);
118 /* formatting library */
120 var formats = new Array();
125 function get_format(format_type) {
126 var value = formats[format_type];
127 if (typeof(value) == 'undefined') {
136 function pluralidx(count) { return (count == 1) ? 0 : 1; }
140 function interpolate(fmt, obj, named) {
142 return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
144 return fmt.replace(/%s/g, function(match){return String(obj.shift())});
150 function pluralidx(n) {
152 if (typeof(v) == 'boolean') {
160 def null_javascript_catalog(request
, domain
=None, packages
=None):
162 Returns "identity" versions of the JavaScript i18n functions -- i.e.,
163 versions that don't actually do anything.
165 src
= [NullSource
, InterPolate
, LibFormatHead
, get_formats(), LibFormatFoot
]
166 return http
.HttpResponse(''.join(src
), 'text/javascript')
168 def javascript_catalog(request
, domain
='djangojs', packages
=None):
170 Returns the selected language catalog as a javascript library.
172 Receives the list of packages to check for translations in the
173 packages parameter either from an infodict or as a +-delimited
174 string from the request. Default is 'django.conf'.
176 Additionally you can override the gettext domain for this view,
177 but usually you don't want to do that, as JavaScript messages
178 go to the djangojs domain. But this might be needed if you
179 deliver your JavaScript source from Django templates.
182 if 'language' in request
.GET
:
183 if check_for_language(request
.GET
['language']):
184 activate(request
.GET
['language'])
186 packages
= ['django.conf']
187 if isinstance(packages
, basestring
):
188 packages
= packages
.split('+')
189 packages
= [p
for p
in packages
if p
== 'django.conf' or p
in settings
.INSTALLED_APPS
]
190 default_locale
= to_locale(settings
.LANGUAGE_CODE
)
191 locale
= to_locale(get_language())
194 en_selected
= locale
.startswith('en')
195 en_catalog_missing
= True
196 # paths of requested packages
197 for package
in packages
:
198 p
= importlib
.import_module(package
)
199 path
= os
.path
.join(os
.path
.dirname(p
.__file
__), 'locale')
201 # add the filesystem paths listed in the LOCALE_PATHS setting
202 paths
.extend(list(reversed(settings
.LOCALE_PATHS
)))
203 # first load all english languages files for defaults
206 catalog
= gettext_module
.translation(domain
, path
, ['en'])
207 t
.update(catalog
._catalog
)
211 # 'en' is the selected language and at least one of the packages
212 # listed in `packages` has an 'en' catalog
214 en_catalog_missing
= False
215 # next load the settings.LANGUAGE_CODE translations if it isn't english
216 if default_locale
!= 'en':
219 catalog
= gettext_module
.translation(domain
, path
, [default_locale
])
222 if catalog
is not None:
223 t
.update(catalog
._catalog
)
224 # last load the currently selected language, if it isn't identical to the default.
225 if locale
!= default_locale
:
226 # If the currently selected language is English but it doesn't have a
227 # translation catalog (presumably due to being the language translated
228 # from) then a wrong language catalog might have been loaded in the
229 # previous step. It needs to be discarded.
230 if en_selected
and en_catalog_missing
:
236 catalog
= gettext_module
.translation(domain
, path
, [locale
])
239 if catalog
is not None:
240 locale_t
.update(catalog
._catalog
)
246 for l
in t
[''].split('\n'):
247 if l
.startswith('Plural-Forms:'):
248 plural
= l
.split(':',1)[1].strip()
249 if plural
is not None:
250 # this should actually be a compiled function of a typical plural-form:
251 # 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;
252 plural
= [el
.strip() for el
in plural
.split(';') if el
.strip().startswith('plural=')][0].split('=',1)[1]
253 src
.append(PluralIdx
% plural
)
255 src
.append(SimplePlural
)
258 for k
, v
in t
.items():
261 if isinstance(k
, basestring
):
262 csrc
.append("catalog['%s'] = '%s';\n" % (javascript_quote(k
), javascript_quote(v
)))
263 elif isinstance(k
, tuple):
264 if k
[0] not in pdict
:
267 pdict
[k
[0]] = max(k
[1], pdict
[k
[0]])
268 csrc
.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k
[0]), k
[1], javascript_quote(v
)))
272 for k
, v
in pdict
.items():
273 src
.append("catalog['%s'] = [%s];\n" % (javascript_quote(k
), ','.join(["''"]*(v
+1))))
276 src
.append(InterPolate
)
277 src
.append(LibFormatHead
)
278 src
.append(get_formats())
279 src
.append(LibFormatFoot
)
281 return http
.HttpResponse(src
, 'text/javascript')