django - template - Cambiar el idioma en la plantilla de jinja
plantillas django (2)
Estoy migrando una aplicación Django multilingüe desde el motor de plantillas de Django a Jinja2. En las plantillas actualmente cambio el idioma activo por objeto usando la etiqueta de la plantilla del language
de Django, es decir:
{% 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>
También usamos i18n_patterns
para que las URL de cada objeto también sean específicas del idioma.
Estoy atascado en cómo convertir esto a Jinja. No puedo usar las etiquetas de plantilla i18n de Django y no puedo encontrar algo equivalente para Jinja.
También estaba mirando a Babel para ayudarme a extraer mensajes de las plantillas. Entonces, se preferiría una solución que funcione tanto con Babel como con Django.
Tengo este fragmento de código para cambiar entre idiomas en 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
en 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'',
]
},
},]
y luego puedes usar esto en cualquier lugar de tus plantillas {{ _(''Hello World'') }}
Resulta que es bastante simple hacerlo escribiendo una extensión jinja2 personalizada (he basado esto en el ejemplo en los documentos jinja2 ):
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)
Con esta extensión en su lugar, cambiar el idioma de traducción activo es más o menos exactamente como lo harías en Django:
{% language ''en'' %}{{ _(''Hello World''){% endlanguage %}
La única advertencia es que al usar Django como un proveedor de gettext y Babel como un extractor de mensajes, es importante decirle a Babel que configure el dominio del mensaje en django
cuando ejecute init/update/compile_catalog
.