/ / Alternar idioma no modelo jinja - django, templates, internacionalização, jinja2, babel

Alternar idioma no modelo jinja - django, templates, internacionalização, jinja2, babel

Eu estou migrando uma aplicação multi-lingual do Django do motor de templates do Django para o Jinja2. Nos modelos eu atualmente mudo o idioma ativo em uma base por objeto usando Django "s language tag de modelo ou seja:

{% load i18n %}
<h1>{% trans "Page title" %}</h1>
<ul>
{% for obj in object_list %}
{% language obj.language_code %}
<li><a href="{{ obj.get_absolute_url }}">{% trans "view" %}: {{ obj.title }}</a>
{% endlanguage %}
{% endfor %}
</ul>

Nós também usamos i18n_patterns Assim, as URLs de cada objeto também são específicas da linguagem.

Eu estou preso em como converter isso para Jinja. Eu não posso usar tags de modelo i18n do Django e não consigo encontrar algo equivalente para Jinja.

Eu também estava olhando Babel para ajudar a extrair mensagens dos modelos. Portanto, uma solução que funcione com o Babel e com o Django seria a preferida.

Respostas:

2 para resposta № 1

Eu tenho esse trecho de código para alternar entre os idiomas em jinja2.

def change_lang(request, lang=None, *args, **kwargs):
"""
Get active page"s url by a specified language, it activates
Usage: {{ change_lang(request, "en") }}
"""

path = request.path
url_parts = resolve(path)

url = path
cur_language = get_language()
try:
activate(lang)
url = reverse(url_parts.view_name, kwargs=url_parts.kwargs)
finally:
activate(cur_language)

return "%s" % url

em settings.py

TEMPLATES = [
{
"BACKEND": "django_jinja.backend.Jinja2",
"DIRS": [
os.path.join(BASE_DIR, "templates/jinja"),
],
"OPTIONS": {
# Match the template names ending in .html but not the ones in the admin folder.
"match_extension": ".html",
"match_regex": r"^(?!admin/).*",
"newstyle_gettext": True,
"extensions": [
"jinja2.ext.do",
"jinja2.ext.loopcontrols",
"jinja2.ext.with_",
"jinja2.ext.i18n",
"jinja2.ext.autoescape",
"django_jinja.builtins.extensions.CsrfExtension",
"django_jinja.builtins.extensions.CacheExtension",
"django_jinja.builtins.extensions.TimezoneExtension",
"django_jinja.builtins.extensions.UrlsExtension",
"django_jinja.builtins.extensions.StaticFilesExtension",
"django_jinja.builtins.extensions.DjangoFiltersExtension",
],
"globals": {
"change_lang": "drug.utils.change_lang"
},
"bytecode_cache": {
"name": "default",
"backend": "django_jinja.cache.BytecodeCache",
"enabled": False,
},
"autoescape": True,
"auto_reload": DEBUG,
"translation_engine": "django.utils.translation",
"context_processors": [
"dashboard.context_processors.auth",
# "django.template.context_processors.debug",
"django.template.context_processors.i18n",
# "django.template.context_processors.media",
# "django.template.context_processors.static",
# "django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
]
}
},
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
os.path.join(BASE_DIR, "templates"),
],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
},]

e então você pode usar isso em qualquer lugar em seus modelos {{ _("Hello World") }}


2 para resposta № 2

Acontece que é bastante simples fazer isso escrevendo uma extensão jinja2 personalizada (eu baseei isso no exemplo no jinja2 docs):

from django.utils import translation
from jinja2.ext import Extension, nodes

class LanguageExtension(Extension):
tags = {"language"}

def parse(self, parser):
lineno = next(parser.stream).lineno
# Parse the language code argument
args = [parser.parse_expression()]
# Parse everything between the start and end tag:
body = parser.parse_statements(["name:endlanguage"], drop_needle=True)
# Call the _switch_language method with the given language code and body
return nodes.CallBlock(self.call_method("_switch_language", args), [], [], body).set_lineno(lineno)

def _switch_language(self, language_code, caller):
with translation.override(language_code):
# Temporarily override the active language and render the body
output = caller()
return output

# Add jinja2"s i18n extension
env.add_extension("jinja2.ext.i18n")
# Install Django"s translation module as the gettext provider
env.install_gettext_translations(translation, newstyle=True)
# Add the language extension to the jinja2 environment
environment.add_extension(LanguageExtension)

Com esta extensão, trocar a linguagem de tradução ativa é exatamente como você faria no Django:

{% language "en" %}{{ _("Hello World"){% endlanguage %}

A única ressalva é que ao usar o Django como um provedor gettext e Babel como um extrator de mensagens, é importante dizer ao Babel para definir o domínio da mensagem para django quando correndo init/update/compile_catalog.