Fixed #4030 -- Added ability to translate language names. Thanks to Antti Kaihola and Ramiro Morales for the initial patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14894 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5fa1169f33
commit
9ab85e05e2
|
@ -0,0 +1,380 @@
|
|||
LANG_INFO = {
|
||||
'ar': {
|
||||
'bidi': True,
|
||||
'code': 'ar',
|
||||
'name': 'Arabic',
|
||||
'name_local': u'\u0627\u0644\u0639\u0631\u0628\u064a\u0651\u0629',
|
||||
},
|
||||
'bg': {
|
||||
'bidi': False,
|
||||
'code': 'bg',
|
||||
'name': 'Bulgarian',
|
||||
'name_local': u'\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438',
|
||||
},
|
||||
'bn': {
|
||||
'bidi': False,
|
||||
'code': 'bn',
|
||||
'name': 'Bengali',
|
||||
'name_local': u'\u09ac\u09be\u0982\u09b2\u09be',
|
||||
},
|
||||
'bs': {
|
||||
'bidi': False,
|
||||
'code': 'bs',
|
||||
'name': 'Bosnian',
|
||||
'name_local': u'bosanski',
|
||||
},
|
||||
'ca': {
|
||||
'bidi': False,
|
||||
'code': 'ca',
|
||||
'name': 'Catalan',
|
||||
'name_local': u'catal\xe0',
|
||||
},
|
||||
'cs': {
|
||||
'bidi': False,
|
||||
'code': 'cs',
|
||||
'name': 'Czech',
|
||||
'name_local': u'\u010desky',
|
||||
},
|
||||
'cy': {
|
||||
'bidi': False,
|
||||
'code': 'cy',
|
||||
'name': 'Welsh',
|
||||
'name_local': u'Cymraeg',
|
||||
},
|
||||
'da': {
|
||||
'bidi': False,
|
||||
'code': 'da',
|
||||
'name': 'Danish',
|
||||
'name_local': u'Dansk',
|
||||
},
|
||||
'de': {
|
||||
'bidi': False,
|
||||
'code': 'de',
|
||||
'name': 'German',
|
||||
'name_local': u'Deutsch',
|
||||
},
|
||||
'el': {
|
||||
'bidi': False,
|
||||
'code': 'el',
|
||||
'name': 'Greek',
|
||||
'name_local': u'\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac',
|
||||
},
|
||||
'en': {
|
||||
'bidi': False,
|
||||
'code': 'en',
|
||||
'name': 'English',
|
||||
'name_local': u'English',
|
||||
},
|
||||
'en-gb': {
|
||||
'bidi': False,
|
||||
'code': 'en-gb',
|
||||
'name': 'British English',
|
||||
'name_local': u'British English',
|
||||
},
|
||||
'es': {
|
||||
'bidi': False,
|
||||
'code': 'es',
|
||||
'name': 'Spanish',
|
||||
'name_local': u'espa\xf1ol',
|
||||
},
|
||||
'es-ar': {
|
||||
'bidi': False,
|
||||
'code': 'es-ar',
|
||||
'name': 'Argentinian Spanish',
|
||||
'name_local': u'espa\xf1ol de Argentina',
|
||||
},
|
||||
'et': {
|
||||
'bidi': False,
|
||||
'code': 'et',
|
||||
'name': 'Estonian',
|
||||
'name_local': u'eesti',
|
||||
},
|
||||
'eu': {
|
||||
'bidi': False,
|
||||
'code': 'eu',
|
||||
'name': 'Basque',
|
||||
'name_local': u'Basque',
|
||||
},
|
||||
'fa': {
|
||||
'bidi': True,
|
||||
'code': 'fa',
|
||||
'name': 'Persian',
|
||||
'name_local': u'\u0641\u0627\u0631\u0633\u06cc',
|
||||
},
|
||||
'fi': {
|
||||
'bidi': False,
|
||||
'code': 'fi',
|
||||
'name': 'Finnish',
|
||||
'name_local': u'suomi',
|
||||
},
|
||||
'fr': {
|
||||
'bidi': False,
|
||||
'code': 'fr',
|
||||
'name': 'French',
|
||||
'name_local': u'Fran\xe7ais',
|
||||
},
|
||||
'fy-nl': {
|
||||
'bidi': False,
|
||||
'code': 'fy-nl',
|
||||
'name': 'Frisian',
|
||||
'name_local': u'Frisian',
|
||||
},
|
||||
'ga': {
|
||||
'bidi': False,
|
||||
'code': 'ga',
|
||||
'name': 'Irish',
|
||||
'name_local': u'Gaeilge',
|
||||
},
|
||||
'gl': {
|
||||
'bidi': False,
|
||||
'code': 'gl',
|
||||
'name': 'Galician',
|
||||
'name_local': u'galego',
|
||||
},
|
||||
'he': {
|
||||
'bidi': True,
|
||||
'code': 'he',
|
||||
'name': 'Hebrew',
|
||||
'name_local': u'\u05e2\u05d1\u05e8\u05d9\u05ea',
|
||||
},
|
||||
'hi': {
|
||||
'bidi': False,
|
||||
'code': 'hi',
|
||||
'name': 'Hindi',
|
||||
'name_local': u'Hindi',
|
||||
},
|
||||
'hr': {
|
||||
'bidi': False,
|
||||
'code': 'hr',
|
||||
'name': 'Croatian',
|
||||
'name_local': u'Hrvatski',
|
||||
},
|
||||
'hu': {
|
||||
'bidi': False,
|
||||
'code': 'hu',
|
||||
'name': 'Hungarian',
|
||||
'name_local': u'Magyar',
|
||||
},
|
||||
'id': {
|
||||
'bidi': False,
|
||||
'code': 'id',
|
||||
'name': 'Indonesian',
|
||||
'name_local': u'Bahasa Indonesia',
|
||||
},
|
||||
'is': {
|
||||
'bidi': False,
|
||||
'code': 'is',
|
||||
'name': 'Icelandic',
|
||||
'name_local': u'\xcdslenska',
|
||||
},
|
||||
'it': {
|
||||
'bidi': False,
|
||||
'code': 'it',
|
||||
'name': 'Italian',
|
||||
'name_local': u'italiano',
|
||||
},
|
||||
'ja': {
|
||||
'bidi': False,
|
||||
'code': 'ja',
|
||||
'name': 'Japanese',
|
||||
'name_local': u'\u65e5\u672c\u8a9e',
|
||||
},
|
||||
'ka': {
|
||||
'bidi': False,
|
||||
'code': 'ka',
|
||||
'name': 'Georgian',
|
||||
'name_local': u'\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8',
|
||||
},
|
||||
'km': {
|
||||
'bidi': False,
|
||||
'code': 'km',
|
||||
'name': 'Khmer',
|
||||
'name_local': u'Khmer',
|
||||
},
|
||||
'kn': {
|
||||
'bidi': False,
|
||||
'code': 'kn',
|
||||
'name': 'Kannada',
|
||||
'name_local': u'Kannada',
|
||||
},
|
||||
'ko': {
|
||||
'bidi': False,
|
||||
'code': 'ko',
|
||||
'name': 'Korean',
|
||||
'name_local': u'\ud55c\uad6d\uc5b4',
|
||||
},
|
||||
'lt': {
|
||||
'bidi': False,
|
||||
'code': 'lt',
|
||||
'name': 'Lithuanian',
|
||||
'name_local': u'Lithuanian',
|
||||
},
|
||||
'lv': {
|
||||
'bidi': False,
|
||||
'code': 'lv',
|
||||
'name': 'Latvian',
|
||||
'name_local': u'latvie\u0161u',
|
||||
},
|
||||
'mk': {
|
||||
'bidi': False,
|
||||
'code': 'mk',
|
||||
'name': 'Macedonian',
|
||||
'name_local': u'\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438',
|
||||
},
|
||||
'ml': {
|
||||
'bidi': False,
|
||||
'code': 'ml',
|
||||
'name': 'Malayalam',
|
||||
'name_local': u'Malayalam',
|
||||
},
|
||||
'mn': {
|
||||
'bidi': False,
|
||||
'code': 'mn',
|
||||
'name': 'Mongolian',
|
||||
'name_local': u'Mongolian',
|
||||
},
|
||||
'nb': {
|
||||
'bidi': False,
|
||||
'code': 'nb',
|
||||
'name': 'Norwegian Bokmal',
|
||||
'name_local': u'Norsk (bokm\xe5l)',
|
||||
},
|
||||
'nl': {
|
||||
'bidi': False,
|
||||
'code': 'nl',
|
||||
'name': 'Dutch',
|
||||
'name_local': u'Nederlands',
|
||||
},
|
||||
'nn': {
|
||||
'bidi': False,
|
||||
'code': 'nn',
|
||||
'name': 'Norwegian Nynorsk',
|
||||
'name_local': u'Norsk (nynorsk)',
|
||||
},
|
||||
'no': {
|
||||
'bidi': False,
|
||||
'code': 'no',
|
||||
'name': 'Norwegian',
|
||||
'name_local': u'Norsk',
|
||||
},
|
||||
'pa': {
|
||||
'bidi': False,
|
||||
'code': 'pa',
|
||||
'name': 'Punjabi',
|
||||
'name_local': u'Punjabi',
|
||||
},
|
||||
'pl': {
|
||||
'bidi': False,
|
||||
'code': 'pl',
|
||||
'name': 'Polish',
|
||||
'name_local': u'polski',
|
||||
},
|
||||
'pt': {
|
||||
'bidi': False,
|
||||
'code': 'pt',
|
||||
'name': 'Portuguese',
|
||||
'name_local': u'Portugu\xeas',
|
||||
},
|
||||
'pt-br': {
|
||||
'bidi': False,
|
||||
'code': 'pt-br',
|
||||
'name': 'Brazilian Portuguese',
|
||||
'name_local': u'Portugu\xeas Brasileiro',
|
||||
},
|
||||
'ro': {
|
||||
'bidi': False,
|
||||
'code': 'ro',
|
||||
'name': 'Romanian',
|
||||
'name_local': u'Rom\xe2n\u0103',
|
||||
},
|
||||
'ru': {
|
||||
'bidi': False,
|
||||
'code': 'ru',
|
||||
'name': 'Russian',
|
||||
'name_local': u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439',
|
||||
},
|
||||
'sk': {
|
||||
'bidi': False,
|
||||
'code': 'sk',
|
||||
'name': 'Slovak',
|
||||
'name_local': u'slovensk\xfd',
|
||||
},
|
||||
'sl': {
|
||||
'bidi': False,
|
||||
'code': 'sl',
|
||||
'name': 'Slovenian',
|
||||
'name_local': u'Sloven\u0161\u010dina',
|
||||
},
|
||||
'sq': {
|
||||
'bidi': False,
|
||||
'code': 'sq',
|
||||
'name': 'Albanian',
|
||||
'name_local': u'Albanian',
|
||||
},
|
||||
'sr': {
|
||||
'bidi': False,
|
||||
'code': 'sr',
|
||||
'name': 'Serbian',
|
||||
'name_local': u'\u0441\u0440\u043f\u0441\u043a\u0438',
|
||||
},
|
||||
'sr-latn': {
|
||||
'bidi': False,
|
||||
'code': 'sr-latn',
|
||||
'name': 'Serbian Latin',
|
||||
'name_local': u'srpski (latinica)',
|
||||
},
|
||||
'sv': {
|
||||
'bidi': False,
|
||||
'code': 'sv',
|
||||
'name': 'Swedish',
|
||||
'name_local': u'Svenska',
|
||||
},
|
||||
'ta': {
|
||||
'bidi': False,
|
||||
'code': 'ta',
|
||||
'name': 'Tamil',
|
||||
'name_local': u'\u0ba4\u0bae\u0bbf\u0bb4\u0bcd',
|
||||
},
|
||||
'te': {
|
||||
'bidi': False,
|
||||
'code': 'te',
|
||||
'name': 'Telugu',
|
||||
'name_local': u'\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41',
|
||||
},
|
||||
'th': {
|
||||
'bidi': False,
|
||||
'code': 'th',
|
||||
'name': 'Thai',
|
||||
'name_local': u'Thai',
|
||||
},
|
||||
'tr': {
|
||||
'bidi': False,
|
||||
'code': 'tr',
|
||||
'name': 'Turkish',
|
||||
'name_local': u'T\xfcrk\xe7e',
|
||||
},
|
||||
'uk': {
|
||||
'bidi': False,
|
||||
'code': 'uk',
|
||||
'name': 'Ukrainian',
|
||||
'name_local': u'\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430',
|
||||
},
|
||||
'vi': {
|
||||
'bidi': False,
|
||||
'code': 'vi',
|
||||
'name': 'Vietnamese',
|
||||
'name_local': u'Vietnamese',
|
||||
},
|
||||
'zh-cn': {
|
||||
'bidi': False,
|
||||
'code': 'zh-cn',
|
||||
'name': 'Simplified Chinese',
|
||||
'name_local': u'\u7b80\u4f53\u4e2d\u6587',
|
||||
},
|
||||
'zh-tw': {
|
||||
'bidi': False,
|
||||
'code': 'zh-tw',
|
||||
'name': 'Traditional Chinese',
|
||||
'name_local': u'\u7e41\u9ad4\u4e2d\u6587',
|
||||
}
|
||||
}
|
|
@ -18,6 +18,34 @@ class GetAvailableLanguagesNode(Node):
|
|||
context[self.variable] = [(k, translation.ugettext(v)) for k, v in settings.LANGUAGES]
|
||||
return ''
|
||||
|
||||
class GetLanguageInfoNode(Node):
|
||||
def __init__(self, lang_code, variable):
|
||||
self.lang_code = Variable(lang_code)
|
||||
self.variable = variable
|
||||
|
||||
def render(self, context):
|
||||
lang_code = self.lang_code.resolve(context)
|
||||
context[self.variable] = translation.get_language_info(lang_code)
|
||||
return ''
|
||||
|
||||
class GetLanguageInfoListNode(Node):
|
||||
def __init__(self, languages, variable):
|
||||
self.languages = Variable(languages)
|
||||
self.variable = variable
|
||||
|
||||
def get_language_info(self, language):
|
||||
# ``language`` is either a language code string or a sequence
|
||||
# with the language code as its first item
|
||||
if len(language[0]) > 1:
|
||||
return translation.get_language_info(language[0])
|
||||
else:
|
||||
return translation.get_language_info(str(language))
|
||||
|
||||
def render(self, context):
|
||||
langs = self.languages.resolve(context)
|
||||
context[self.variable] = [self.get_language_info(lang) for lang in langs]
|
||||
return ''
|
||||
|
||||
class GetCurrentLanguageNode(Node):
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
|
@ -109,6 +137,55 @@ def do_get_available_languages(parser, token):
|
|||
raise TemplateSyntaxError("'get_available_languages' requires 'as variable' (got %r)" % args)
|
||||
return GetAvailableLanguagesNode(args[2])
|
||||
|
||||
def do_get_language_info(parser, token):
|
||||
"""
|
||||
This will store the language information dictionary for the given language
|
||||
code in a context variable.
|
||||
|
||||
Usage::
|
||||
|
||||
{% get_language_info for LANGUAGE_CODE as l %}
|
||||
{{ l.code }}
|
||||
{{ l.name }}
|
||||
{{ l.name_local }}
|
||||
{{ l.bidi|yesno:"bi-directional,uni-directional" }}
|
||||
"""
|
||||
args = token.contents.split()
|
||||
if len(args) != 5 or args[1] != 'for' or args[3] != 'as':
|
||||
raise TemplateSyntaxError("'%s' requires 'for string as variable' (got %r)" % (args[0], args[1:]))
|
||||
return GetLanguageInfoNode(args[2], args[4])
|
||||
|
||||
def do_get_language_info_list(parser, token):
|
||||
"""
|
||||
This will store a list of language information dictionaries for the given
|
||||
language codes in a context variable. The language codes can be specified
|
||||
either as a list of strings or a settings.LANGUAGES style tuple (or any
|
||||
sequence of sequences whose first items are language codes).
|
||||
|
||||
Usage::
|
||||
|
||||
{% get_language_info_list for LANGUAGES as langs %}
|
||||
{% for l in langs %}
|
||||
{{ l.code }}
|
||||
{{ l.name }}
|
||||
{{ l.name_local }}
|
||||
{{ l.bidi|yesno:"bi-directional,uni-directional" }}
|
||||
{% endfor %}
|
||||
"""
|
||||
args = token.contents.split()
|
||||
if len(args) != 5 or args[1] != 'for' or args[3] != 'as':
|
||||
raise TemplateSyntaxError("'%s' requires 'for sequence as variable' (got %r)" % (args[0], args[1:]))
|
||||
return GetLanguageInfoListNode(args[2], args[4])
|
||||
|
||||
def language_name(lang_code):
|
||||
return translation.get_language_info(lang_code)['name']
|
||||
|
||||
def language_name_local(lang_code):
|
||||
return translation.get_language_info(lang_code)['name_local']
|
||||
|
||||
def language_bidi(lang_code):
|
||||
return translation.get_language_info(lang_code)['bidi']
|
||||
|
||||
def do_get_current_language(parser, token):
|
||||
"""
|
||||
This will store the current language in the context.
|
||||
|
@ -269,7 +346,13 @@ def do_block_translate(parser, token):
|
|||
counter)
|
||||
|
||||
register.tag('get_available_languages', do_get_available_languages)
|
||||
register.tag('get_language_info', do_get_language_info)
|
||||
register.tag('get_language_info_list', do_get_language_info_list)
|
||||
register.tag('get_current_language', do_get_current_language)
|
||||
register.tag('get_current_language_bidi', do_get_current_language_bidi)
|
||||
register.tag('trans', do_translate)
|
||||
register.tag('blocktrans', do_block_translate)
|
||||
|
||||
register.filter(language_name)
|
||||
register.filter(language_name_local)
|
||||
register.filter(language_bidi)
|
||||
|
|
|
@ -11,7 +11,7 @@ __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext',
|
|||
'get_partial_date_formats', 'check_for_language', 'to_locale',
|
||||
'get_language_from_request', 'templatize', 'ugettext', 'ugettext_lazy',
|
||||
'ungettext', 'ungettext_lazy', 'pgettext', 'pgettext_lazy',
|
||||
'npgettext', 'npgettext_lazy', 'deactivate_all']
|
||||
'npgettext', 'npgettext_lazy', 'deactivate_all', 'get_language_info']
|
||||
|
||||
# Here be dragons, so a short explanation of the logic won't hurt:
|
||||
# We are trying to solve two problems: (1) access settings, in particular
|
||||
|
@ -117,3 +117,10 @@ def _string_concat(*strings):
|
|||
"""
|
||||
return u''.join([force_unicode(s) for s in strings])
|
||||
string_concat = lazy(_string_concat, unicode)
|
||||
|
||||
def get_language_info(lang_code):
|
||||
from django.conf.locale import LANG_INFO
|
||||
try:
|
||||
return LANG_INFO[lang_code]
|
||||
except KeyError:
|
||||
raise KeyError("Unknown language code %r." % lang_code)
|
||||
|
|
|
@ -274,7 +274,7 @@ The result of a ``ugettext_lazy()`` call can be used wherever you would use a
|
|||
unicode string (an object with type ``unicode``) in Python. If you try to use
|
||||
it where a bytestring (a ``str`` object) is expected, things will not work as
|
||||
expected, since a ``ugettext_lazy()`` object doesn't know how to convert
|
||||
itself to a bytestring. You can't use a unicode string inside a bytestring,
|
||||
itself to a bytestring. You can't use a unicode string inside a bytestring,
|
||||
either, so this is consistent with normal Python behavior. For example::
|
||||
|
||||
# This is fine: putting a unicode proxy into a unicode string.
|
||||
|
@ -379,6 +379,26 @@ Using this decorator means you can write your function and assume that the
|
|||
input is a proper string, then add support for lazy translation objects at the
|
||||
end.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
Localized names of languages
|
||||
============================
|
||||
|
||||
The ``get_language_info()`` function provides detailed information about
|
||||
languages::
|
||||
|
||||
>>> from django.utils.translation import get_language_info
|
||||
>>> li = get_language_info('de')
|
||||
>>> print li['name'], li['name_local'], li['bidi']
|
||||
German Deutsch False
|
||||
|
||||
The ``name`` and ``name_local`` attributes of the dictionary contain the name of
|
||||
the language in English and in the language itself, respectively. The ``bidi``
|
||||
attribute is True only for bi-directional languages.
|
||||
|
||||
The source of the language information is the ``django.conf.locale`` module.
|
||||
Similar access to this information is available for template code. See below.
|
||||
|
||||
.. _specifying-translation-strings-in-template-code:
|
||||
|
||||
Specifying translation strings: In template code
|
||||
|
@ -518,6 +538,49 @@ string, so they don't need to be aware of translations.
|
|||
translator might translate the string ``"yes,no"`` as ``"ja,nein"``
|
||||
(keeping the comma intact).
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
You can also retrieve information about any of the available languages using
|
||||
provided template tags and filters. To get information about a single language,
|
||||
use the ``{% get_language_info %}`` tag::
|
||||
|
||||
{% get_language_info for LANGUAGE_CODE as lang %}
|
||||
{% get_language_info for "pl" as lang %}
|
||||
|
||||
You can then access the information::
|
||||
|
||||
Language code: {{ lang.code }}<br />
|
||||
Name of language: {{ lang.name_local }}<br />
|
||||
Name in English: {{ lang.name }}<br />
|
||||
Bi-directional: {{ lang.bidi }}
|
||||
|
||||
You can also use the ``{% get_language_info_list %}`` template tag to retrieve
|
||||
information for a list of languages (e.g. active languages as specified in
|
||||
:setting:`LANGUAGES`). See :ref:`the section about the set_language redirect
|
||||
view <set_language-redirect-view>` for an example of how to display a language
|
||||
selector using ``{% get_language_info_list %}``.
|
||||
|
||||
In addition to :setting:`LANGUAGES` style nested tuples,
|
||||
``{% get_language_info_list %}`` supports simple lists of language codes.
|
||||
If you do this in your view:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return render_to_response('mytemplate.html', {
|
||||
'available_languages': ['en', 'es', 'fr'],
|
||||
}, RequestContext(request))
|
||||
|
||||
you can iterate over those languages in the template::
|
||||
|
||||
{% get_language_info_list for available_languages as langs %}
|
||||
{% for lang in langs %} ... {% endfor %}
|
||||
|
||||
There are also simple filters available for convenience:
|
||||
|
||||
* ``{{ LANGUAGE_CODE|language_name }}`` ("German")
|
||||
* ``{{ LANGUAGE_CODE|language_name_local }}`` ("Deutsch")
|
||||
* ``{{ LANGUAGE_CODE|bidi }}`` (False)
|
||||
|
||||
.. _Django templates: ../templates_python/
|
||||
|
||||
Specifying translation strings: In JavaScript code
|
||||
|
@ -579,7 +642,7 @@ With this, you specify the packages as a list of package names delimited by '+'
|
|||
signs in the URL. This is especially useful if your pages use code from
|
||||
different apps and this changes often and you don't want to pull in one big
|
||||
catalog file. As a security measure, these values can only be either
|
||||
``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
|
||||
``django.conf`` or any package from the :setting:`INSTALLED_APPS` setting.
|
||||
|
||||
Using the JavaScript translation catalog
|
||||
----------------------------------------
|
||||
|
@ -636,6 +699,8 @@ This isn't as fast as string interpolation in Python, so keep it to those
|
|||
cases where you really need it (for example, in conjunction with ``ngettext``
|
||||
to produce proper pluralizations).
|
||||
|
||||
.. _set_language-redirect-view:
|
||||
|
||||
The ``set_language`` redirect view
|
||||
==================================
|
||||
|
||||
|
@ -654,7 +719,7 @@ The view expects to be called via the ``POST`` method, with a ``language``
|
|||
parameter set in request. If session support is enabled, the view
|
||||
saves the language choice in the user's session. Otherwise, it saves the
|
||||
language choice in a cookie that is by default named ``django_language``.
|
||||
(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
|
||||
(The name can be changed through the :setting:`LANGUAGE_COOKIE_NAME` setting.)
|
||||
|
||||
After setting the language choice, Django redirects the user, following this
|
||||
algorithm:
|
||||
|
@ -673,8 +738,9 @@ Here's example HTML template code:
|
|||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="/next/page/" />
|
||||
<select name="language">
|
||||
{% for lang in LANGUAGES %}
|
||||
<option value="{{ lang.0 }}">{{ lang.1 }}</option>
|
||||
{% get_language_info_list for LANGUAGES as languages %}
|
||||
{% for language in languages %}
|
||||
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" value="Go" />
|
||||
|
|
|
@ -7,12 +7,14 @@ import pickle
|
|||
|
||||
from django.conf import settings
|
||||
from django.template import Template, Context
|
||||
from django.test import TestCase
|
||||
from django.utils.formats import get_format, date_format, time_format, localize, localize_input, iter_format_modules
|
||||
from django.utils.importlib import import_module
|
||||
from django.utils.numberformat import format as nformat
|
||||
from django.utils.safestring import mark_safe, SafeString, SafeUnicode
|
||||
from django.utils.translation import ugettext, ugettext_lazy, activate, deactivate, gettext_lazy, pgettext, npgettext, to_locale
|
||||
from django.utils.importlib import import_module
|
||||
from django.utils.translation import (ugettext, ugettext_lazy, activate,
|
||||
deactivate, gettext_lazy, pgettext, npgettext, to_locale,
|
||||
get_language_info)
|
||||
from django.utils.unittest import TestCase
|
||||
|
||||
|
||||
from forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm
|
||||
|
@ -709,3 +711,12 @@ class TestModels(TestCase):
|
|||
c.save()
|
||||
c.name = SafeString(u'Iñtërnâtiônàlizætiøn1'.encode('utf-8'))
|
||||
c.save()
|
||||
|
||||
|
||||
class TestLanguageInfo(TestCase):
|
||||
def test_localized_language_info(self):
|
||||
li = get_language_info('de')
|
||||
self.assertEqual(li['code'], 'de')
|
||||
self.assertEqual(li['name_local'], u'Deutsch')
|
||||
self.assertEqual(li['name'], 'German')
|
||||
self.assertEqual(li['bidi'], False)
|
||||
|
|
|
@ -1150,6 +1150,14 @@ class Templates(unittest.TestCase):
|
|||
# translation of singular form in russian (#14126)
|
||||
'i18n27': ('{% load i18n %}{% blocktrans count number as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %}', {'number': 1, 'LANGUAGE_CODE': 'ru'}, u'1 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442'),
|
||||
|
||||
# retrieving language information
|
||||
'i18n28': ('{% load i18n %}{% get_language_info for "de" as l %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}', {}, 'de: German/Deutsch bidi=False'),
|
||||
'i18n29': ('{% load i18n %}{% get_language_info for LANGUAGE_CODE as l %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}', {'LANGUAGE_CODE': 'fi'}, 'fi: Finnish/suomi bidi=False'),
|
||||
'i18n30': ('{% load i18n %}{% get_language_info_list for langcodes as langs %}{% for l in langs %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}; {% endfor %}', {'langcodes': ['it', 'no']}, u'it: Italian/italiano bidi=False; no: Norwegian/Norsk bidi=False; '),
|
||||
'i18n31': ('{% load i18n %}{% get_language_info_list for langcodes as langs %}{% for l in langs %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}; {% endfor %}', {'langcodes': (('sl', 'Slovenian'), ('fa', 'Persian'))}, u'sl: Slovenian/Sloven\u0161\u010dina bidi=False; fa: Persian/\u0641\u0627\u0631\u0633\u06cc bidi=True; '),
|
||||
'i18n32': ('{% load i18n %}{{ "hu"|language_name }} {{ "hu"|language_name_local }} {{ "hu"|language_bidi }}', {}, u'Hungarian Magyar False'),
|
||||
'i18n33': ('{% load i18n %}{{ langcode|language_name }} {{ langcode|language_name_local }} {{ langcode|language_bidi }}', {'langcode': 'nl'}, u'Dutch Nederlands False'),
|
||||
|
||||
### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
|
||||
|
||||
'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),
|
||||
|
|
Loading…
Reference in New Issue