如何在Bottle中使用jinja2国际化(与babel一起)
我认为在使用 jinja2 和 bottle 的时候,只需要用 jinja2_template 代替 template 就可以了,比如这样写: bottle.jinja2_template("mytemplate", dict(name=value, name2=value2))。
不过,如果需要使用 i18n(国际化)这个 jinja 扩展,应该怎么指定呢?
....install_gettext_translations(
这个是自动完成的吗?
bottle.jinja2_template("mytemplate", dict(name=value, name2=value2), template_lookup=['templates'],'template_settings'= {'extensions':['jinja2.ext.i18n'],'autoescape': True }))
谢谢。
经过进一步思考,我觉得可能需要在 Jinja2Template 类中重写 prepare 方法,以添加 env.install_gettext_translations( ???
如果我手动做 ....install_gettext_translations( 的话,可能是:
tenv = Environment(extensions=['jinja2.ext.i18n'])
tenv.install_gettext_translations(gettransobj())
import gettext
import locale
def gettransobj():
loc = locale.getlocale()
# change to reflect where your mo files are
mofilename = "res/messages_%s.mo" % locale.getdefaultlocale()[0][0:2]
try:
trans = gettext.GNUTranslations(open( mofilename, "rb" ) )
except IOError:
trans = gettext.NullTranslations()
return trans
或者对于 babel 翻译对象,类似这样:
.....install_gettext_translations(gettransobj(), newstyle=True)
import babel
import locale
def gettransobj():
loc = locale.getlocale()
mofilename = "res/messages_%s.mo" % locale.getdefaultlocale()[0][0:2]
trans = babel.support.Translations(open( mofilename, "rb" ) )
如果这段代码大致正确,不太确定该放在哪里?我对 jinja2 不是很熟悉。是只需要在程序顶部写一次,还是每次调用 bottle.jinja2_template 时都要写?
另外,如果有人需要使用 babel 进行提取,可以看看 jinja2.ext.babel_extract。
另一种方法是通过类似这样的方式获取翻译对象:
return gettext.translation(domain, localedir=localedir,languages=languages, codeset='utf-8')
1 个回答
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,但其实很多时候,解决办法就在于理解这些工具是如何工作的。
比如说,当你在使用一个库的时候,可能会发现它的某些功能没有按照你的预期工作。这时候,你可以查看这个库的文档,看看有没有相关的说明或者示例代码。文档通常会告诉你如何正确使用这个库,避免常见的错误。
另外,社区的力量也很重要。像StackOverflow这样的平台上,有很多开发者分享他们的经验和解决方案。如果你遇到问题,可以在上面搜索一下,看看有没有人遇到过类似的情况,或者直接提问,寻求帮助。
总之,编程的过程中,遇到问题是很正常的,关键是要保持耐心,善于寻找资料和向他人请教。这样,你会逐渐掌握更多的知识,变得越来越熟练。
from jinja2 import FileSystemBytecodeCache, Environment
bcc = FileSystemBytecodeCache('/tmp', '%s.cache')
template_settings = {'filters': {
'tojson': json_util.dumps
},
'bytecode_cache': bcc,
'extensions': ['jinja2.ext.i18n'],
'languages': ['en_US']
}
import bottle
from bottle import Jinja2Template
from babel.support import Translations
TEMPLATE_PATH = bottle.TEMPLATE_PATH
DEBUG = bottle.DEBUG
TEMPLATES = {}
class Jinja2BabelTemplate(Jinja2Template):
def prepare(self, filters=None, tests=None,
languages=['en_US'],
globals={}, **kwargs):
from jinja2 import Environment, FunctionLoader
self.env = Environment(loader=FunctionLoader(self.loader), **kwargs)
#BABEL: this is where we load and install our translations from babel
translations = Translations.load('translations', languages)
self.env.install_gettext_translations(translations)
if filters: self.env.filters.update(filters)
if tests: self.env.tests.update(tests)
if globals: self.env.globals.update(globals)
if self.source:
self.tpl = self.env.from_string(self.source)
else:
self.tpl = self.env.get_template(self.filename)
def jinja_template(*args, **kwargs):
tpl = args[0] if args else None
adapter = Jinja2BabelTemplate
lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)
languages = kwargs.pop('languages', None)
tplid = (id(languages), tpl,)
if tplid not in TEMPLATES or DEBUG:
settings = kwargs.pop('template_settings', {})
if languages: settings.update({'languages': languages})
if isinstance(tpl, adapter):
TEMPLATES[tplid] = tpl
if settings: TEMPLATES[tplid].prepare(**settings)
elif "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl:
TEMPLATES[tplid] = adapter(source=tpl, lookup=lookup, **settings)
else:
TEMPLATES[tplid] = adapter(name=tpl, lookup=lookup, **settings)
if not TEMPLATES[tplid]:
abort(500, 'Template (%s) not found' % tpl)
for dictarg in args[1:]: kwargs.update(dictarg)
return TEMPLATES[tplid].render(kwargs)
template = functools.partial(jinja_template,
template_settings=template_settings)
#and now you should be able to use the template function above with different languages
@get('/home')
def home():
data = {}
return template('home.html', data, languages=['en_US'])