Fixed #16516 -- Relaxed the blocktrans rendering a little by falling back to the default language if resolving one of the arguments fails, raising a KeyError. Thanks, Claude Paroz and Aymeric Augustin.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16723 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
2b4341d532
commit
16bb9c594c
|
@ -128,7 +128,12 @@ class BlockTranslateNode(Node):
|
||||||
result = re.sub(u'%(?!\()', u'%%', result)
|
result = re.sub(u'%(?!\()', u'%%', result)
|
||||||
data = dict([(v, _render_value_in_context(context.get(v, ''), context)) for v in vars])
|
data = dict([(v, _render_value_in_context(context.get(v, ''), context)) for v in vars])
|
||||||
context.pop()
|
context.pop()
|
||||||
return result % data
|
try:
|
||||||
|
result = result % data
|
||||||
|
except KeyError:
|
||||||
|
with translation.override(None):
|
||||||
|
result = self.render(context)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class LanguageNode(Node):
|
class LanguageNode(Node):
|
||||||
|
|
|
@ -115,7 +115,10 @@ class override(object):
|
||||||
self.old_language = get_language()
|
self.old_language = get_language()
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
activate(self.language)
|
if self.language is not None:
|
||||||
|
activate(self.language)
|
||||||
|
else:
|
||||||
|
deactivate_all()
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
if self.deactivate:
|
if self.deactivate:
|
||||||
|
|
|
@ -532,15 +532,18 @@ For a complete discussion on the usage of the following see the
|
||||||
useful when we want delayed translations to appear as the original string
|
useful when we want delayed translations to appear as the original string
|
||||||
for some reason.
|
for some reason.
|
||||||
|
|
||||||
.. function:: override(language)
|
.. function:: override(language, deactivate=False)
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
A Python context manager that uses
|
A Python context manager that uses
|
||||||
:func:`django.utils.translation.activate` to fetch the translation object
|
:func:`django.utils.translation.activate` to fetch the translation object
|
||||||
for a given language, installing it as the translation object for the
|
for a given language, installing it as the translation object for the
|
||||||
current thread and deinstalls it again on exit with
|
current thread and reinstall the previous active language on exit.
|
||||||
:func:`django.utils.translation.deactivate`.
|
Optionally it can simply deinstall the temporary translation on exit with
|
||||||
|
:func:`django.utils.translation.deactivate` if the deactivate argument is
|
||||||
|
True. If you pass None as the language argument, a NullTranslations()
|
||||||
|
instance is installed while the context is active.
|
||||||
|
|
||||||
.. function:: get_language()
|
.. function:: get_language()
|
||||||
|
|
||||||
|
|
|
@ -512,6 +512,13 @@ You can use multiple expressions inside a single ``blocktrans`` tag::
|
||||||
.. note:: The previous more verbose format is still supported:
|
.. note:: The previous more verbose format is still supported:
|
||||||
``{% blocktrans with book|title as book_t and author|title as author_t %}``
|
``{% blocktrans with book|title as book_t and author|title as author_t %}``
|
||||||
|
|
||||||
|
.. versionchanged:: 1.4
|
||||||
|
|
||||||
|
If resolving one of the block arguments fails, blocktrans will fall back to
|
||||||
|
the default language by deactivating the currently active language
|
||||||
|
temporarily with the :func:`~django.utils.translation.deactivate_all`
|
||||||
|
function.
|
||||||
|
|
||||||
This tag also provides for pluralization. To use it:
|
This tag also provides for pluralization. To use it:
|
||||||
|
|
||||||
* Designate and bind a counter value with the name ``count``. This value will
|
* Designate and bind a counter value with the name ``count``. This value will
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,21 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django tests\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2010-02-14 17:33+0100\n"
|
||||||
|
"PO-Revision-Date: 2011-01-21 21:37-0300\n"
|
||||||
|
"Last-Translator: Claude\n"
|
||||||
|
"Language-Team: fr <fr@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
|
||||||
|
#: template.html:3
|
||||||
|
msgid "My name is %(person)s."
|
||||||
|
msgstr "Mon nom est %(personne)s."
|
|
@ -9,6 +9,7 @@ from threading import local
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.template import Template, Context
|
from django.template import Template, Context
|
||||||
from django.test import TestCase, RequestFactory
|
from django.test import TestCase, RequestFactory
|
||||||
|
from django.test.utils import override_settings
|
||||||
from django.utils.formats import (get_format, date_format, time_format,
|
from django.utils.formats import (get_format, date_format, time_format,
|
||||||
localize, localize_input, iter_format_modules, get_format_modules)
|
localize, localize_input, iter_format_modules, get_format_modules)
|
||||||
from django.utils.importlib import import_module
|
from django.utils.importlib import import_module
|
||||||
|
@ -27,6 +28,8 @@ from commands.tests import *
|
||||||
from patterns.tests import *
|
from patterns.tests import *
|
||||||
from test_warnings import DeprecationWarningTests
|
from test_warnings import DeprecationWarningTests
|
||||||
|
|
||||||
|
here = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
class TranslationTests(TestCase):
|
class TranslationTests(TestCase):
|
||||||
|
|
||||||
def test_override(self):
|
def test_override(self):
|
||||||
|
@ -34,6 +37,9 @@ class TranslationTests(TestCase):
|
||||||
with translation.override('pl'):
|
with translation.override('pl'):
|
||||||
self.assertEqual(get_language(), 'pl')
|
self.assertEqual(get_language(), 'pl')
|
||||||
self.assertEqual(get_language(), 'de')
|
self.assertEqual(get_language(), 'de')
|
||||||
|
with translation.override(None):
|
||||||
|
self.assertEqual(get_language(), settings.LANGUAGE_CODE)
|
||||||
|
self.assertEqual(get_language(), 'de')
|
||||||
deactivate()
|
deactivate()
|
||||||
|
|
||||||
def test_lazy_objects(self):
|
def test_lazy_objects(self):
|
||||||
|
@ -67,7 +73,7 @@ class TranslationTests(TestCase):
|
||||||
def test_pgettext(self):
|
def test_pgettext(self):
|
||||||
# Reset translation catalog to include other/locale/de
|
# Reset translation catalog to include other/locale/de
|
||||||
extended_locale_paths = settings.LOCALE_PATHS + (
|
extended_locale_paths = settings.LOCALE_PATHS + (
|
||||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),
|
os.path.join(here, 'other', 'locale'),
|
||||||
)
|
)
|
||||||
with self.settings(LOCALE_PATHS=extended_locale_paths):
|
with self.settings(LOCALE_PATHS=extended_locale_paths):
|
||||||
from django.utils.translation import trans_real
|
from django.utils.translation import trans_real
|
||||||
|
@ -129,6 +135,18 @@ class TranslationTests(TestCase):
|
||||||
self.assertEqual(to_language('en_US'), 'en-us')
|
self.assertEqual(to_language('en_US'), 'en-us')
|
||||||
self.assertEqual(to_language('sr_Lat'), 'sr-lat')
|
self.assertEqual(to_language('sr_Lat'), 'sr-lat')
|
||||||
|
|
||||||
|
@override_settings(LOCALE_PATHS=(os.path.join(here, 'other', 'locale'),))
|
||||||
|
def test_bad_placeholder(self):
|
||||||
|
"""
|
||||||
|
Error in translation file should not crash template rendering
|
||||||
|
(%(person)s is translated as %(personne)s in fr.po)
|
||||||
|
"""
|
||||||
|
from django.template import Template, Context
|
||||||
|
with translation.override('fr'):
|
||||||
|
t = Template('{% load i18n %}{% blocktrans %}My name is {{ person }}.{% endblocktrans %}')
|
||||||
|
rendered = t.render(Context({'person': 'James'}))
|
||||||
|
self.assertEqual(rendered, 'My name is James.')
|
||||||
|
|
||||||
|
|
||||||
class FormattingTests(TestCase):
|
class FormattingTests(TestCase):
|
||||||
|
|
||||||
|
@ -636,7 +654,7 @@ class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.old_locale_paths = settings.LOCALE_PATHS
|
self.old_locale_paths = settings.LOCALE_PATHS
|
||||||
settings.LOCALE_PATHS += (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'other', 'locale'),)
|
settings.LOCALE_PATHS += (os.path.join(here, 'other', 'locale'),)
|
||||||
super(LocalePathsResolutionOrderI18NTests, self).setUp()
|
super(LocalePathsResolutionOrderI18NTests, self).setUp()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
Loading…
Reference in New Issue