/ / Sprache in jinja Vorlage wechseln - django, Vorlagen, Internationalisierung, jinja2, babel

Sprache in jinja Vorlage wechseln - django, Vorlagen, Internationalisierung, jinja2, babel

Ich migriere eine mehrsprachige Django-Anwendung von Djangos Template-Engine zu Jinja2. In den Templates wechsle ich zur Zeit die aktive Sprache pro Objekt mit Djangos "s language Vorlagen-Tag das heißt:

{% 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>

Wir benützen auch i18n_patterns Die URLs jedes Objekts sind also auch sprachspezifisch.

Ich bleibe dran, wie ich dies in Jinja umwandeln kann. Ich kann Djangos i18n Template-Tags nicht verwenden und kann für Jinja nichts Entsprechendes finden.

Ich schaute auch auf Babel um beim Extrahieren von Nachrichten aus den Vorlagen zu helfen. Daher wäre eine Lösung, die sowohl mit Babel als auch mit Django arbeitet, vorzuziehen.

Antworten:

2 für die Antwort № 1

Ich habe dieses Code-Snippet, um zwischen den Sprachen in jinja2 zu wechseln.

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

in 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",
]
},
},]

und dann können Sie dies überall in Ihren Vorlagen verwenden {{ _("Hello World") }}


2 für die Antwort № 2

Es stellt sich heraus, dass es ziemlich einfach ist, dies zu tun, indem man eine benutzerdefinierte jinja2-Erweiterung schreibt (ich habe dies auf der Grundlage von Beispiel in der jinja2 Dokumentation):

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)

Mit dieser Erweiterung ist der Wechsel der aktiven Übersetzungssprache ziemlich genau so wie in Django:

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

Der einzige Nachteil ist, dass es bei der Verwendung von Django als Gettext-Provider und Babel als Nachrichtenextraktor wichtig ist, Babel zu sagen, dass er die Nachrichtendomäne festlegen soll django beim Laufen init/update/compile_catalog.