2017-07-03 5 views
7

Ich migriere eine mehrsprachige Django-Anwendung von Djangos Template-Engine nach Jinja2. In den Vorlagen wechsle ich zur Zeit die aktive Sprache auf einer Basis pro Objekt Django's language template tag d.h .: mitSprache in Jinja-Vorlage wechseln

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

auch i18n_patterns so die Urls jedes Objekts sind sprachspezifisch und wir verwenden.

Ich bin fest, wie man dies zu Jinja konvertieren. Ich kann Djangos i18n Schablonen-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.

+0

Haben Sie gesehen, wie es in 'Django-jinja' App implementiert ist? –

+0

Ich nehme an, Sie meinen [diese Django-Jinja] (https://github.com/niwinz/django-jinja)? Ich finde dort keine Implementierung des Template-Tags 'language'. – jaap3

+0

haben Sie diese Syntax versucht? http://jinja.pocoo.org/docs/2.9/templates/#i18n – HassenPy

Antwort

3

Es stellt sich heraus, es ist ziemlich einfach, dies zu tun, indem Sie eine benutzerdefinierte jinja2 Verlängerung schriftlich (ich habe dies auf der Grundlage der 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) 

Mit Diese Erweiterung anstelle der aktiven Übersetzung Sprachumschaltung ziemlich genau ist mag, wie Sie es in Django tun würde:

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

Die einzige Einschränkung, dass, wenn Django als gettext-Provider und Babel als Nachricht Extraktor es ist wichtig, Babel zu sagen, die Nachrichtendomäne auf django festzulegen, wenn init/update/compile_catalog ausgeführt wird.

3

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 diese in Ihre Vorlagen in überall verwenden {{ _('Hello World') }}

Verwandte Themen