variable template tag plantillas django templates internationalization jinja2 babel

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 .