如何创建 jinja2 扩展?

发布于 2024-08-06 05:57:17 字数 240 浏览 7 评论 0原文

我尝试为 jinja2 进行扩展。我写了这样的代码:

http://dumpz.org/12996/

但我收到异常: “NoneType”对象不可迭代。哪里有bug? 这应该返回parse。另外什么应该接受并返回_media

I try to make extension for jinja2. I has written such code:

http://dumpz.org/12996/

But I receive exception: 'NoneType' object is not iterable. Where is a bug?
That should return parse. Also what should accept and return _media?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

走过海棠暮 2024-08-13 05:57:17

您正在使用 CallBlock,这表明您希望您的扩展程序充当块。例如,

{% mytest arg1 arg2 %}
stuff
in
here
{% endmytest %}

nodes.CallBlock 期望您向其传递代表扩展主体(内部语句)的节点列表。目前,这是您传递 None 的地方 - 因此您的错误。

解析完参数后,您需要继续解析块的主体。幸运的是,这很容易。您可以简单地执行:

body = parser.parse_statements(['name:endmytest'], drop_needle=True)  

然后返回一个新节点。 CallBlock 接收一个要调用的方法(在本例中为 _mytestfunc),该方法为您的扩展提供逻辑。

body = parser.parse_statements(['name:endmytest'], drop_needle=True)  
return nodes.CallBlock(self.call_method('_mytestfunc', args),[], [], body).set_lineno(lineno)

或者,如果您不希望您的扩展成为块标记,例如

{% mytest arg1 arg2 %}

您不应该使用nodes.CallBlock,您应该只使用nodes.Call,这不接受主体参数。所以只需这样做:

return self.call_method('_mytestfunc', args)  

self.call_method 只是一个方便的包装函数,可以为您创建一个 Call 节点。

我花了几天时间编写 Jinja2 扩展,这很棘手。没有太多文档(除了代码)。 coffin GitHub 项目此处提供了一些扩展示例。

You're using a CallBlock, which indicates that you want your extension to act as a block. E.g.

{% mytest arg1 arg2 %}
stuff
in
here
{% endmytest %}

nodes.CallBlock expects that you pass it a list of nodes representing the body (the inner statements) for your extension. Currently this is where you're passing None - hence your error.

Once you've parsed your arguments, you need to proceed to parse the body of the block. Fortunately, it's easy. You can simply do:

body = parser.parse_statements(['name:endmytest'], drop_needle=True)  

and then return a new node. The CallBlock receives a method to be called (in this case _mytestfunc) that provides the logic for your extension.

body = parser.parse_statements(['name:endmytest'], drop_needle=True)  
return nodes.CallBlock(self.call_method('_mytestfunc', args),[], [], body).set_lineno(lineno)

Alternatively, if you don't want your extension to be a block tag, e.g.

{% mytest arg1 arg2 %}

you shouldn't use nodes.CallBlock, you should just use nodes.Call instead, which doesn't take a body parameter. So just do:

return self.call_method('_mytestfunc', args)  

self.call_method is simply a handy wrapper function that creates a Call node for you.

I've spent a few days writing Jinja2 extensions and it's tricky. There's not much documentation (other than the code). The coffin GitHub project has a few examples of extensions here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文