我试图使用Jinja2构建一个json文档,该文档有一个嵌套的脚本。该脚本包含{{<variables>}}
,我需要与非json字符一起替换。因此,脚本需要在之后使用json.dumps()
进行json转义。
str = '{
"nestedScript" : {% include "scripts/sc.ps1" | json %}
}'
escape
函数是不够的,因为成品包含有效的HTML字符,而不是JSON。
我在想:
str = '{
"nestedScript" : {{ include("scripts/sc.ps1") | json}} %}
}'
使用一些自定义过滤器或其他东西,但我似乎无法编写包含函数,这样它也可以在脚本中进行变量替换。到目前为止,这是我的脚本,我包括作为一个全局:
<标题>完整的示例文件夹结构:
.
└── templates
├── test.json
└── scripts
└── script.ps1
模板文件:
test.json = '{
"nestedScript" : {{ include("scripts/script.ps1") | json}}
}'
脚本:
loader = jinja2.FileSystemLoader("templates")
env = jinja2.Environment(loader=self.loader)
template = env.get_template("test.json")
template.render({
'service_name': 'worker',
'context_name': 'googlesellerratings',
})
结果:{
"nestedScript" : "echo {{service_name}}"
}
标题>
解决这个问题的方式感觉有点粗糙,所以我希望得到一些反馈。在实例化类时,我定义了一个名为include_script
的全局函数:
loader = jinja2.FileSystemLoader(templates_folder)
env = inja2.Environment(loader=self.loader)
env.globals['include_script'] = render_script_func(env)
render_script_func
返回一个函数,该函数从环境中检索上下文,并使用它来呈现我引用的文件:
def render_script_func(env):
def render_script(name):
ctx = env.globals['context']
tmpl = env.get_template(name)
raw = tmpl.render(ctx)
return json.dumps(raw)
return render_script
现在,在渲染之前,所要做的就是将渲染的上下文添加到全局context
对象:
template = env.get_template(template_name)
template.environment.globals["context"] = ctx
renderedData = template.render(ctx)
当模板使用{{ include_script("path/to/script") }}
时,脚本既被渲染,然后被json编码。
还是觉得有点不对,但就这样吧。
给定(不完整)示例,似乎您正在搜索filter
标记。
首先,脚本以实际可运行的形式,并根据json.dumps()
定义json
过滤器:
import json
import jinja2
loader = jinja2.FileSystemLoader('templates')
env = jinja2.Environment(loader=loader)
env.filters['json'] = json.dumps
template = env.get_template('test.json')
print(
template.render({
'service_name': 'worker',
'context_name': 'googlesellerratings',
})
)
丢失的PowerShell脚本,如果在JSON ("
)中使用会导致麻烦的字符:
echo "{{service_name}}"
现在test.json
模板的解决方案:
{
"nestedScript" : {% filter json %}{% include "scripts/script.ps1" %}{% endfilter %}
}
最后打印结果:
{
"nestedScript" : "echo "worker""
}