django1/django/views/i18n.py

191 lines
5.6 KiB
Python

import re
import os
import gettext as gettext_module
from django.utils import httpwrappers
from django.utils.translation import check_for_language, activate, to_locale, get_language
from django.utils.text import javascript_quote
from django.conf import settings
def set_language(request):
"""
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the GET paramters.
"""
lang_code = request.GET['language']
next = request.GET.get('next', None)
if not next:
next = request.META.get('HTTP_REFERER', None)
if not next:
next = '/'
response = httpwrappers.HttpResponseRedirect(next)
if check_for_language(lang_code):
if hasattr(request, 'session'):
request.session['django_language'] = lang_code
else:
response.set_cookie('django_language', lang_code)
return response
NullSource = """
/* gettext identity library */
function gettext(msgid) {
return msgid;
}
function ngettext(singular, plural, count) {
if (count == 1) {
return singular;
} else {
return plural;
}
}
function gettext_noop(msgid) {
return msgid;
}
"""
LibHead = """
/* gettext library */
var catalog = new Array();
"""
LibFoot = """
function gettext(msgid) {
var value = catalog[msgid];
if (typeof(value) == 'undefined') {
return msgid;
} else {
if (typeof(value) == 'string') {
return value;
} else {
return value[0];
}
}
}
function ngettext(singular, plural, count) {
value = catalog[singular];
if (typeof(value) == 'undefined') {
if (count == 1) {
return singular;
} else {
return plural;
}
} else {
return value[pluralidx(count)];
}
}
function gettext_noop(msgid) {
return msgid;
}
"""
SimplePlural = """
function pluralidx(count) {
if (count == 1) {
return 0;
} else {
return 1;
}
}
"""
InterPolate = r"""
function interpolate(fmt, obj, named) {
if (named) {
return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])});
} else {
return fmt.replace(/%s/, function(match){return String(obj.shift())});
}
}
"""
def javascript_catalog(request, domain='djangojs', packages=None):
"""
Returns the selected language catalog as a javascript library.
Receives the list of packages to check for translations in the
packages parameter either from an infodict or as a +-delimited
string from the request. Default is 'django.conf'.
Additionally you can override the gettext domain for this view,
but usually you don't want to do that, as JavaScript messages
go to the djangojs domain. But this might be needed if you
deliver your JavaScript source from Django templates.
"""
if request.GET:
if request.GET.has_key('language'):
if check_for_language(request.GET['language']):
activate(request.GET['language'])
if packages is None:
packages = ['django.conf']
if type(packages) in (str, unicode):
packages = packages.split('+')
packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
default_locale = to_locale(settings.LANGUAGE_CODE)
locale = to_locale(get_language())
t = {}
paths = []
for package in packages:
p = __import__(package, {}, {}, [''])
path = os.path.join(os.path.dirname(p.__file__), 'locale')
paths.append(path)
#!!! add loading of catalogs from settings.LANGUAGE_CODE and request.LANGUAGE_CODE!
try:
catalog = gettext_module.translation(domain, path, [default_locale])
except IOError, e:
catalog = None
if catalog is not None:
t.update(catalog._catalog)
if locale != default_locale:
for path in paths:
try:
catalog = gettext_module.translation(domain, path, [locale])
except IOError, e:
catalog = None
if catalog is not None:
t.update(catalog._catalog)
src = [LibHead]
plural = None
for l in t[''].split('\n'):
if l.startswith('Plural-Forms:'):
plural = l.split(':',1)[1].strip()
if plural is not None:
# this should actually be a compiled function of a typical plural-form:
# 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;
plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1]
src.append('function pluralidx(n) {\n return %s;\n}\n' % plural)
else:
src.append(SimplePlural)
csrc = []
pdict = {}
for k, v in t.items():
if k == '':
continue
if type(k) in (str, unicode):
csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v)))
elif type(k) == tuple:
if not pdict.has_key(k[0]):
pdict[k[0]] = k[1]
else:
pdict[k[0]] = max(k[1], pdict[k[0]])
csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v)))
else:
raise TypeError, k
csrc.sort()
for k,v in pdict.items():
src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1))))
src.extend(csrc)
src.append(LibFoot)
src.append(InterPolate)
src = ''.join(src)
return httpwrappers.HttpResponse(src, 'text/javascript')