Переключить язык в шаблоне jinja

Я переношу многоязычное приложение Django с механизма шаблонов Django на Jinja2. В шаблонах я в настоящее время переключаю активный язык для каждого объекта, используя Тег шаблона Django language, например:

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

Мы также используем i18n_patterns. поэтому URL-адреса каждого объекта также зависят от языка.

Я застрял в том, как преобразовать это в Jinja. Я не могу использовать теги шаблона Django i18n и не могу найти что-то эквивалентное для Jinja.

Я также искал Babel, чтобы помочь с извлечением сообщений из шаблонов. Таким образом, решение, которое работает с Babel, а также с Django, было бы предпочтительнее.


person jaap3    schedule 03.07.2017    source источник
comment
Вы видели, как это реализовано в приложении django-jinja?   -  person Sergei Zherevchuk    schedule 03.07.2017
comment
Я предполагаю, что вы имеете в виду этот django-jinja? Я не могу найти там реализацию тега шаблона language.   -  person jaap3    schedule 03.07.2017
comment
вы пробовали этот синтаксис? jinja.pocoo.org/docs/2.9/templates/#i18n   -  person HassenPy    schedule 06.07.2017
comment
Бит перевода не проблема. Я ищу способ переключения между активным языком для каталога сообщений во время рендеринга шаблона. Таким образом, в части шаблона используются, например, немецкие переводы, в то время как в некоторых частях того же шаблона используются английские переводы.   -  person jaap3    schedule 06.07.2017


Ответы (2)


У меня есть этот фрагмент кода для переключения между языками в 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

в настройках.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',
        ]
    },
},]

а затем вы можете использовать это где угодно в своих шаблонах {{ _('Hello World') }}

person heykarimoff    schedule 08.07.2017

Оказывается, это довольно просто сделать, написав собственное расширение jinja2 (я взял его за основу пример в документации 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)

С этим расширением переключение активного языка перевода очень похоже на то, как вы делаете это в Django:

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

Единственное предостережение заключается в том, что при использовании Django в качестве провайдера gettext и Babel в качестве средства извлечения сообщений важно указать Babel установить домен сообщения на django при запуске init/update/compile_catalog.

person jaap3    schedule 10.07.2017