Author: jezdez
Date: 2010-12-12 17:02:45 -0600 (Sun, 12 Dec 2010)
New Revision: 14894

Modified:
   django/trunk/django/conf/locale/__init__.py
   django/trunk/django/templatetags/i18n.py
   django/trunk/django/utils/translation/__init__.py
   django/trunk/docs/topics/i18n/internationalization.txt
   django/trunk/tests/regressiontests/i18n/tests.py
   django/trunk/tests/regressiontests/templates/tests.py
Log:
Fixed #4030 -- Added ability to translate language names. Thanks to Antti 
Kaihola and Ramiro Morales for the initial patch.

Modified: django/trunk/django/conf/locale/__init__.py
===================================================================
--- django/trunk/django/conf/locale/__init__.py 2010-12-12 23:02:10 UTC (rev 
14893)
+++ django/trunk/django/conf/locale/__init__.py 2010-12-12 23:02:45 UTC (rev 
14894)
@@ -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',
+    }
+}

Modified: django/trunk/django/templatetags/i18n.py
===================================================================
--- django/trunk/django/templatetags/i18n.py    2010-12-12 23:02:10 UTC (rev 
14893)
+++ django/trunk/django/templatetags/i18n.py    2010-12-12 23:02:45 UTC (rev 
14894)
@@ -18,6 +18,34 @@
         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 @@
         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 @@
             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)

Modified: django/trunk/django/utils/translation/__init__.py
===================================================================
--- django/trunk/django/utils/translation/__init__.py   2010-12-12 23:02:10 UTC 
(rev 14893)
+++ django/trunk/django/utils/translation/__init__.py   2010-12-12 23:02:45 UTC 
(rev 14894)
@@ -11,7 +11,7 @@
         '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 @@
     """
     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)

Modified: django/trunk/docs/topics/i18n/internationalization.txt
===================================================================
--- django/trunk/docs/topics/i18n/internationalization.txt      2010-12-12 
23:02:10 UTC (rev 14893)
+++ django/trunk/docs/topics/i18n/internationalization.txt      2010-12-12 
23:02:45 UTC (rev 14894)
@@ -274,7 +274,7 @@
 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 @@
 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 @@
     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 @@
 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 @@
 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 @@
 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 @@
     {% 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" />

Modified: django/trunk/tests/regressiontests/i18n/tests.py
===================================================================
--- django/trunk/tests/regressiontests/i18n/tests.py    2010-12-12 23:02:10 UTC 
(rev 14893)
+++ django/trunk/tests/regressiontests/i18n/tests.py    2010-12-12 23:02:45 UTC 
(rev 14894)
@@ -7,12 +7,14 @@
 
 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 @@
         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)

Modified: django/trunk/tests/regressiontests/templates/tests.py
===================================================================
--- django/trunk/tests/regressiontests/templates/tests.py       2010-12-12 
23:02:10 UTC (rev 14893)
+++ django/trunk/tests/regressiontests/templates/tests.py       2010-12-12 
23:02:45 UTC (rev 14894)
@@ -1150,6 +1150,14 @@
             # 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')),

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to