Fix #12442: Add ability to request any translation of a string (#12443)

This commit is contained in:
Paul McLanahan 2022-12-07 13:55:38 -05:00 коммит произвёл GitHub
Родитель 0e1b8fbe96
Коммит 9e8b38e414
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 59 добавлений и 7 удалений

Просмотреть файл

@ -183,6 +183,13 @@ You could use that in a template like this:
For our purposes these are mostly useful for things that can change, but which shouldn't involve
retranslation of a string (e.g. URLs or email addresses).
You may also request any other translation of the string (or the original English string of course) regardless of the current locale.
.. code-block:: jinja
<h2>{{ ftl('welcome', locale='en', user='Dude') }}<h2>
This helper is available in Jinja templates and Python code in views. For use in a view you should
always call it in the view itself:

Просмотреть файл

@ -46,6 +46,8 @@ def render_to_string(template_name, context=None, request=None, using=None, ftl_
context["fluent_l10n"] = fluent_l10n([locale, "en"], ftl_files)
else:
context["fluent_l10n"] = fluent_l10n([locale, "en"], settings.FLUENT_DEFAULT_FILES)
context["fluent_files"] = ftl_files or settings.FLUENT_DEFAULT_FILES
return loader.render_to_string(template_name, context, request, using)
@ -128,8 +130,7 @@ def render(request, template, context=None, ftl_files=None, activation_files=Non
else:
context["fluent_l10n"] = fluent_l10n([locale, "en"], settings.FLUENT_DEFAULT_FILES)
# Every template gets its own .lang file, so figure out what it is
# and pass it in the context
context["fluent_files"] = ftl_files or settings.FLUENT_DEFAULT_FILES
context["template"] = template
context["template_source_url"] = template_source_url(template)

Просмотреть файл

@ -145,7 +145,10 @@ def l10nize(f):
# can not use += here because that mutates the original list
ftl_files = ftl_files + settings.FLUENT_DEFAULT_FILES
locale = kwargs.get("locale") or translation.get_language(True)
l10n = fluent_l10n([locale, "en"], ftl_files)
locales = [locale]
if locale != "en":
locales.append("en")
l10n = fluent_l10n(locales, ftl_files)
return f(l10n, *args, **kwargs)
return inner

Просмотреть файл

@ -11,12 +11,13 @@ from lib.l10n_utils import fluent
@library.global_function
@jinja2.pass_context
def ftl(ctx, message_id, fallback=None, **kwargs):
def ftl(ctx, message_id, fallback=None, locale=None, **kwargs):
"""Return the translated string.
:param ctx: the context from the template (automatically included)
:param str message_id: the ID of the message
:param str fallback: the ID of a message to use if message_id is not translated
:param str locale: If set the string returned will be from the given locale instead of the current one
:param kwargs: the other kwargs are passed to the translation as variables
:return: the translated string marked as safe
@ -24,7 +25,11 @@ def ftl(ctx, message_id, fallback=None, **kwargs):
<p>{{ ftl('greeting', name='The Dude') }}
"""
return Markup(fluent.translate(ctx["fluent_l10n"], message_id, fallback, **kwargs))
if locale:
return Markup(fluent.ftl(message_id, fallback, locale=locale, ftl_files=ctx["fluent_files"], **kwargs))
l10n = ctx["fluent_l10n"]
return Markup(fluent.translate(l10n, message_id, fallback, **kwargs))
@library.global_function

Просмотреть файл

@ -0,0 +1,7 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{{ ftl("fluent-title") }}:{{ ftl("fluent-title", locale="en") }}

Просмотреть файл

@ -0,0 +1,7 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{{ ftl("fluent-title") }}:{{ ftl("fluent-title", locale="fr") }}

Просмотреть файл

@ -131,6 +131,8 @@ class TestFluentViewTranslationUtils(TestCase):
def test_ftl_view_util(self):
assert fluent.ftl("fluent-title", locale="de", ftl_files="mozorg/fluent") == "Title in German"
assert fluent.ftl("fluent-title", locale="fr", ftl_files="mozorg/fluent") == "Title in French"
assert fluent.ftl("fluent-title", locale="en", ftl_files="mozorg/fluent") == "This is a test of the new Fluent L10n system"
def test_ftl_view_util_no_mutate_list(self):
"""Should not mutate the ftl_files list"""

Просмотреть файл

@ -6,16 +6,17 @@ from pathlib import Path
from unittest.mock import ANY, patch
from django.template import TemplateDoesNotExist
from django.test import RequestFactory
from django.test import RequestFactory, override_settings
from django_jinja.backend import Jinja2
from bedrock.mozorg.tests import TestCase
from lib.l10n_utils import render
from lib.l10n_utils import render, render_to_string
ROOT_PATH = Path(__file__).with_name("test_files")
ROOT = str(ROOT_PATH)
TEMPLATE_DIRS = [str(ROOT_PATH.joinpath("templates"))]
L10N_PATH = ROOT_PATH.joinpath("l10n")
jinja_env = Jinja2.get_default().env
@ -27,6 +28,25 @@ class TestNoLocale(TestCase):
render(request, "500.html")
@override_settings(FLUENT_PATHS=[L10N_PATH])
@patch.object(jinja_env.loader, "searchpath", TEMPLATE_DIRS)
class TestFtlTemplateHelper(TestCase):
def setUp(self):
self.rf = RequestFactory()
def test_english_locale(self):
req = self.rf.get("/en-US/")
req.locale = "de"
result = render_to_string("test-en-title.html", request=req, ftl_files="mozorg/fluent")
assert result.strip() == "Title in German:This is a test of the new Fluent L10n system"
def test_french_locale(self):
req = self.rf.get("/en-US/")
req.locale = "en-US"
result = render_to_string("test-fr-title.html", request=req, ftl_files="mozorg/fluent")
assert result.strip() == "This is a test of the new Fluent L10n system:Title in French"
@patch.object(jinja_env.loader, "searchpath", TEMPLATE_DIRS)
@patch("lib.l10n_utils.django_render")
class TestLocaleTemplates(TestCase):