Jinja2:包括脚本,替换{{variable}}和json编码结果



我试图使用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""
}

最新更新