2017-07-03 95 views
7

Przeprowadzam migrację wielojęzycznej aplikacji Django z silnika szablonu Django do wersji Jinja2. W szablonach Obecnie przełączyć aktywny język na podstawie jednej obiektu przy użyciu Django's language template tag tj .:Przełącz język w szablonie jinja

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

Używamy również i18n_patterns więc adresy URL każdego obiektu są specyficzne dla języka, jak również.

Utknąłem, jak przekonwertować to na Jinja. Nie mogę używać znaczników szablonu i18n Django i nie mogę znaleźć czegoś podobnego do Jinji.

Szukałem również Babel, aby pomóc w wyodrębnianiu wiadomości z szablonów. Dlatego preferowane byłoby rozwiązanie współpracujące z Babelem i Django.

+0

Czy widziałeś, jak jest zaimplementowany w aplikacji 'django-jinja'? –

+0

Zakładam, że masz na myśli [to django-jinja] (https://github.com/niwinz/django-jinja)? Nie mogę znaleźć tam implementacji znacznika szablonu 'language'. – jaap3

+0

wypróbowałeś tę składnię? http://jinja.pocoo.org/docs/2.9/templates/#i18n – HassenPy

Odpowiedz

3

Okazuje się, że to dość proste do zrobienia tego przez pisanie rozszerzenia niestandardowe jinja2 (Oparłem to na example in the 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) 

Z To rozszerzenie w miejscu przełączania aktywnego język tłumaczenia jest prawie dokładnie tak, jak chcesz to zrobić w Django:

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

Jedynym zastrzeżeniem jest to, że przy użyciu Django jako dostawcy gettext i Babel jako wyciąg wiadomości ważne aby powiedzieć Babelowi, aby ustawić domenę wiadomości na django podczas uruchamiania init/update/compile_catalog.

3

Mam ten fragment kodu, aby przełączać się między językami w 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 

w 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', 
     ] 
    }, 
},] 

a następnie można użyć w dowolnym miejscu w szablonach {{ _('Hello World') }}