可以编译或还原 Jinja2 AST 的一部分吗?
例如,是否可以从jinja2.environment
调用函数或方法?或 jinja2.compiler.generate
或者从模板中提取的节点列表中的一些等价物?
例如,给定一个模板y.html
:
avant-tag
{% xyz %}
tag content {{ 3 + 5 }}
{% endxyz %}
apres-tag
和一个扩展y.py
:
# -*- coding: utf-8 -*-
from jinja2 import nodes, Environment, FileSystemLoader
from jinja2.ext import Extension
class YExtension(Extension):
tags = set(['y'])
def __init__(self, environment):
super(YExtension, self).__init__(environment)
def parse(self, parser):
tag = parser.stream.next()
body = parser.parse_statements(['name:endy'], drop_needle=True)
return nodes.Const("<!-- slurping: %s -->" % str(body))
env = Environment(
loader = FileSystemLoader('.'),
extensions = [YExtension],
)
print env.get_template('x.html').render()
运行 python y.py
会产生预期的输出:
avant-tag
<!-- slurping: [Output(nodes=[TemplateData(data=u'\n tag-content '),
Add(left=Const(value=3), right=Const(value=5)),
TemplateData(data=u'\n ')])] -->
sous-tag
在parse
方法中,如何可以:
- 将
body
编译为unicode(即tag-content 8
);或者,或者, - 将
body
恢复为其原始来源(即tag-content {{ 3 + 5 }}
)。
作为背景,这个问题与之前的两个问题有关:
感谢阅读。
布莱恩
最佳答案
在 parse()
方法中还不能编译成 unicode,因为此时您没有可用的上下文。您当然可以绕过它,但这可能不是最好的方法。
请注意,parse()
步骤通常只在 html 文件上执行一次,之后它将使用解析的字节码来呈现模板。解析步骤的结果可以在给定的环境中呈现。
你根本没有那里可用的上下文,并且在那里获取上下文......非常困难;)
然而,要获得原始来源...没有黑客攻击也不会容易得多,但黑客攻击也不算太糟糕;)
class YExtension(Extension):
tags = set(['y'])
def preprocess(self, source, name, filename=None):
# insert some code here that replaces '{% xyz %}foo bar{% endxyz %}'
# with something like: '{% xyz %}foo bar{% raw %}foo bar{% endraw %}{% endxyz %}'
return source
之后,您可以从 {% raw %}
节点读取作为 value
的文本。之后一定要将其删除,否则它将显示在您的模板中。
关于python - 编译 Jinja2 AST 的小节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4309266/