是否可以编写一个Jinja2扩展,在渲染时可以访问模板上下文?我想编写一个访问上下文变量的扩展,并根据该变量输出一些数据.我找不到有关如何编写此类扩展的足够信息.
现在,我有这个:
class CsrfExtension(jinja2.ext.Extension): r""" Adds a {% csrf %} tag to Jinja. """ tags = set(['csrf']) template = '' def parse(self, parser): token = next(parser.stream) lineno = token.lineno return self.call_method('_render_csrf', lineno=lineno) def _render_csrf(self, value, name, *args, **kwargs): csrf_token = somehow_get_variable('csrf_token') return jinja2.Markup(self.template % csrf_token)
但在 foo.jinja
This is a Test
{% csrf %}
我明白了
SyntaxError at / invalid syntax (foo.jinja, line 7)
我以为我会得到一个NameError,因为somehow_get_variable()
没有定义.我需要知道a)如何从当前上下文中获取变量,以及b)如何正确编写扩展.
还有,为什么7号线?该{% csrf %}
标签是第5行甚至当我修剪foo.jinja
到只有一个符合{% csrf %}
它的标签,它说,7号线.
找到了.看起来像Jinja从Jinja AST(?)生成Python代码并且转换失败,因此导致了SyntaxError.jinja2.nodes.ContextReference()
可用于获取渲染上下文.
class CsrfExtension(jinja2.ext.Extension): r""" Adds a {% csrf %} tag to Jinja. """ tags = set(['csrf', 'csrf_token']) template = u'' def parse(self, parser): lineno = next(parser.stream).lineno ctx_ref = jinja2.nodes.ContextReference() node = self.call_method('_render_csrf', [ctx_ref], lineno=lineno) return jinja2.nodes.CallBlock(node, [], [], [], lineno=lineno) def _render_csrf(self, context, caller): csrf_token = context['csrf_token'] return jinja2.Markup(self.template % unicode(csrf_token)) csrf = CsrfExtension