2017-07-03 71 views
7

我正在將多語言Django應用程序從Django的模板引擎遷移到Jinja2。在我的模板切換當前使用Django's language template tag即:在忍者模板中切換語言

{% 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所以每個對象的網址是特定語言。

我被困在如何將其轉換爲Jinja。我無法使用Django的i18n模板標籤,也無法找到與Jinja等價的東西。

我還在尋找Babel來幫助從模板中提取消息。因此,與Babel以及Django協同工作的解決方案將是首選。

+0

你有沒有看到它是如何在'django-jinja'應用程序中實現的? –

+0

我假設你的意思是[這個django-jinja](https://github.com/niwinz/django-jinja)?我無法在那裏找到'language'模板標籤的實現。 – jaap3

+0

你有沒有試過這種語法? http://jinja.pocoo.org/docs/2.9/templates/#i18n – HassenPy

回答

3

事實證明,這是相當簡單的通過編寫自定義擴展的Jinja2做到這一點在任何地方使用這個(我基於這個在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) 

With這個擴展到位切換活動翻譯語言幾乎是一模一樣,你會怎麼做在Django:

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

唯一需要注意的是,使用Django作爲一個gettext的供應商和巴貝爾的消息提取時,這一點很重要告訴Babel在運行init/update/compile_catalog時將消息域設置爲django

3

我有這段代碼在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 
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', 
     ] 
    }, 
},] 

然後你就可以在你的模板{{ _('Hello World') }}