我最初使用App Engine网站上显示的示例在App Engine上实现了Jinja2:https://developers.google.com/appengine/docs/python/gettingstartedpython27/templates其中jinja2直接导入:
import jinja2
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainPage(webapp2.RequestHandler):
def get(self):
greetings = 'somestring'
template_values = {
'greetings': greetings,
}
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values))
但我目前正在使用Simpleauth(https://github.com/crhym3/simpleauth),它遵循Nick Johnson在此处描述的实现:http://blog.notdot.net/2011/11/Migrating-to-Python-2-7-part-2-Webapp-and-templates其中jinja2是从webapp2_extras导入的:
import os
import webapp2
from webapp2_extras import jinja2
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_template(self, filename, **template_args):
self.response.write(self.jinja2.render_template(filename, **template_args))
class IndexHandler(BaseHandler):
def get(self):
self.render_template('index.html', name=self.request.get('name'))
其中哪一种是使用jinja2的首选方法?(它们似乎不能很好地结合使用,并且更愿意标准化最佳选项。)
答案 0 :(得分:4)
我有同样的问题,但这里的答案并不能让我满意。
我认为这是关于封装与性能的关系。对于小型应用程序,您可以拥有全局,没问题。所以第一个解决方案就好了。它可以让您轻松解决一个简单的问题,而无需花费额外的费用来学习框架的细节。
对于更大的应用程序,您可能希望封装并为对象带来一些顺序。基本上,您构建了一个框架,一个可扩展的基础架构。但这就是webapp2应该给你的东西。
背后的基本问题: 如果你决定将一个单例类型的对象设置为一个实例化并作为逻辑的一部分释放的类(如官方示例中的webapp2.RequestHandler类),那么在最后一个类实例时将释放该引用对象(jinja2)已经消失了......你可能会得到很多自由和重新分配。因此,有一个链接到某个对象(webapp2.registry)以防止删除即使在其他地方没有被引用也是很好的。它就像全局一样,但没有规范全局命名空间,并且可以通过webapp2.get_app()。registry从任何地方访问它。它也是缓存。然后,使用cached_property,您只需另一层缓存。
简而言之:如果您想要封装,最好为您的应用添加缓存以保持高效
在这种情况下,您可以使用webapp2_extra jinja2,在每个模块中,您都可以访问相同的jinja环境:
jinja2.get_jinja2().environment
答案 1 :(得分:3)
我猜他们几乎是一样的。另外webapp2_extras.jinja2的作用是缓存jinja2.Environment()初始化(对于请求持续时间)。另外,您可以利用webapp2的配置/注册表系统。
查看get_jinja2() source你会发现它只是jinja2.Environment()的一个方便的包装器,带有一些默认的环境args和启用的扩展(例如i18n)。
答案 2 :(得分:1)
第一种方法是一个非常基本的例子。
第二种(使用BaseHandler)是首选方法。在这里你把webapp2共享方法。这些方法可以由派生类使用,在这里你可以使用想要覆盖的webapp2方法,如dispatch。
答案 3 :(得分:1)
TL; DR:使用选项#2
如果你不使用i18n,那么它并不重要。但在现实世界中的人说英语不同的语言,有与GAE Jinja2的国际化一个棘手的问题:线程(即threadsafe: true
app.yaml中)是在默认情况下和性能很重要,但最国际化的Jinja2您可以在Web上找到的文档不是线程安全的。由于您不希望将语言环境显式传递给每个jinja2宏,因此需要将其保存在线程局部变量中。这是webapp2_extras.jinja2
正确执行的操作。