当前位置:  开发笔记 > 编程语言 > 正文

可以访问Context的Jinja Extension

如何解决《可以访问Context的JinjaExtension》经验,为你挑选了1个好方法。

是否可以编写一个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号线.



1> Niklas R..:

找到了.看起来像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

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有