Ticket #12848: native_languages_v2.diff

File native_languages_v2.diff, 9.0 KB (added by Benny Daon, 14 years ago)

A better fix - includes docs and tests

  • django/core/context_processors.py

    diff --git a/django/core/context_processors.py b/django/core/context_processors.py
    index a5f29df..d812ded 100644
    a b RequestContext.  
    1010from django.conf import settings
    1111from django.middleware.csrf import get_token
    1212from django.utils.functional import lazy
     13from django.utils.translation import get_language_names
    1314
    1415def auth(request):
    1516    """
    def debug(request):  
    5758    return context_extras
    5859
    5960def i18n(request):
     61    """ Returns context variables helpful for i18n and l10n """
    6062    from django.utils import translation
    61 
    6263    context_extras = {}
    63     context_extras['LANGUAGES'] = settings.LANGUAGES
     64    context_extras['LANGUAGES'] = get_language_names()
    6465    context_extras['LANGUAGE_CODE'] = translation.get_language()
    6566    context_extras['LANGUAGE_BIDI'] = translation.get_language_bidi()
    66 
    6767    return context_extras
    6868
    6969def media(request):
  • django/templatetags/i18n.py

    diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py
    index 10ac900..346e413 100644
    a b from django.template import TemplateSyntaxError, TokenParser, Library  
    55from django.template import TOKEN_TEXT, TOKEN_VAR
    66from django.utils import translation
    77from django.utils.encoding import force_unicode
     8from django.utils.translation import get_language_names
    89
    910register = Library()
    1011
    class GetAvailableLanguagesNode(Node):  
    1415
    1516    def render(self, context):
    1617        from django.conf import settings
    17         context[self.variable] = [(k, translation.ugettext(v)) for k, v in settings.LANGUAGES]
     18        context[self.variable] = get_language_names()
    1819        return ''
    1920
    2021class GetCurrentLanguageNode(Node):
  • django/utils/translation/__init__.py

    diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
    index 6d81726..c64195b 100644
    a b __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext',  
    1010        'get_language', 'get_language_bidi', 'get_date_formats',
    1111        'get_partial_date_formats', 'check_for_language', 'to_locale',
    1212        'get_language_from_request', 'templatize', 'ugettext', 'ugettext_lazy',
    13         'ungettext', 'deactivate_all']
     13        'ungettext', 'deactivate_all', 'get_language_names']
    1414
    1515# Here be dragons, so a short explanation of the logic won't hurt:
    1616# We are trying to solve two problems: (1) access settings, in particular
    def templatize(src):  
    9595def deactivate_all():
    9696    return real_deactivate_all()
    9797
     98def get_language_names():
     99    return real_get_language_names()
     100
    98101def _string_concat(*strings):
    99102    """
    100103    Lazy variant of string concatenation, needed for translations that are
  • django/utils/translation/trans_real.py

    diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
    index b528f8e..4fdd775 100644
    a b _active = {}  
    2020# The default translation is based on the settings file.
    2121_default = None
    2222
     23# The translation of LANGUAGES is cached
     24_language_names = False
     25
    2326# This is a cache for normalized accept-header languages to prevent multiple
    2427# file lookups when checking the same locale on repeated requests.
    2528_accepted = {}
    def get_partial_date_formats():  
    547550        month_day_format = settings.MONTH_DAY_FORMAT
    548551    return year_month_format, month_day_format
    549552
     553def get_language_names():
     554    """
     555    Returns an array of language names where each language translated
     556    to its native language.
     557    """
     558    from django.conf import settings
     559    global _language_names
     560    if _language_names:
     561        return _language_names
     562    else:
     563        languages = []
     564        current_language = get_language()
     565        for lang, english_name in settings.LANGUAGES:
     566            activate(lang)
     567            languages.append((lang, ugettext(english_name)))
     568        _language_names = languages
     569        if current_language != get_language():
     570            activate(current_language)
     571        '''
     572        deactivate()
     573        for lang, english_name in settings.LANGUAGES:
     574            activate(lang)
     575            languages.append((lang, ugettext(english_name)))
     576            deactivate()
     577        _language_names = languages
     578        '''
     579        return languages
  • docs/topics/i18n/deployment.txt

    diff --git a/docs/topics/i18n/deployment.txt b/docs/topics/i18n/deployment.txt
    index 1a4f5fa..f2bf15a 100644
    a b Notes:  
    116116      set ``LANGUAGES`` to a list of languages. For example::
    117117
    118118          LANGUAGES = (
    119             ('de', _('German')),
    120             ('en', _('English')),
     119            ('de', 'German'),
     120            ('en', 'English'),
    121121          )
    122122
    123123      This example restricts languages that are available for automatic
    124124      selection to German and English (and any sublanguage, like de-ch or
    125125      en-us).
    126126
    127     * If you define a custom ``LANGUAGES`` setting, as explained in the
    128       previous bullet, it's OK to mark the languages as translation strings
    129       -- but use a "dummy" ``ugettext()`` function, not the one in
    130       ``django.utils.translation``. You should *never* import
    131       ``django.utils.translation`` from within your settings file, because that
    132       module in itself depends on the settings, and that would cause a circular
    133       import.
    134 
    135       The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
    136       settings file::
    137 
    138           ugettext = lambda s: s
    139 
    140           LANGUAGES = (
    141               ('de', ugettext('German')),
    142               ('en', ugettext('English')),
    143           )
    144 
    145       With this arrangement, ``django-admin.py makemessages`` will still find
    146       and mark these strings for translation, but the translation won't happen
    147       at runtime -- so you'll have to remember to wrap the languages in the
    148       *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
    149 
    150127    * The ``LocaleMiddleware`` can only select languages for which there is a
    151128      Django-provided base translation. If you want to provide translations
    152129      for your application that aren't already in the set of translations
  • docs/topics/i18n/internationalization.txt

    diff --git a/docs/topics/i18n/internationalization.txt b/docs/topics/i18n/internationalization.txt
    index 7ae8d18..b604df7 100644
    a b Other tags  
    429429Each ``RequestContext`` has access to three translation-specific variables:
    430430
    431431    * ``LANGUAGES`` is a list of tuples in which the first element is the
    432       :term:`language code` and the second is the language name (translated into
    433       the currently active locale).
     432      :term:`language code` and the second is the language name in English
     433      (magically translated into its native language).
    434434
    435435    * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
    436436      Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`.)
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index 5902e8d..6b37277 100644
    a b class Templates(unittest.TestCase):  
    391391                        output = self.render(test_template, vals)
    392392                        end = datetime.now()
    393393                        if end-start > timedelta(seconds=0.2):
    394                             failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name))
     394                            # give it another try allowing caching to spee things up
     395                            start = datetime.now()
     396                            output = self.render(test_template, vals)
     397                            end = datetime.now()
     398                            if end-start > timedelta(seconds=0.2):
     399                                failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name))
    395400                    except ContextStackException:
    396401                        failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name))
    397402                        continue
    class Templates(unittest.TestCase):  
    10821087            'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'),
    10831088
    10841089            # usage of the get_available_languages tag
    1085             'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'),
     1090            'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.1 }}{% endifequal %}{% endfor %}', {}, u'Deutsch'),
    10861091
    10871092            # translation of constant strings
    10881093            'i18n13': ('{{ _("Password") }}', {'LANGUAGE_CODE': 'de'}, 'Passwort'),
Back to Top