首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Jinja中包含文件,然后应用模板进行过滤。

在Jinja中包含文件,然后应用模板进行过滤。
EN

Stack Overflow用户
提问于 2020-02-28 00:49:26
回答 1查看 2.7K关注 0票数 1

摘要

我有一个Jinja2模板,我正在使用Ansible运行它。

我希望我的模板加载另一个文件,作为模板(即评估{{ var }}),然后过滤,然后将结果粘贴到顶层模板。

我想我快到了,我只需要找到一个Jinja2过滤器,它接受一个字符串并将其解析为一个模板。

米维

在这个例子中,让我们假设我要应用的过滤器只是为了使文件大写。(很明显,这个例子非常简单,我可以在一个模板文件中完成。但我真正的用例更复杂。)

顶层模板main.yaml.j2

代码语言:javascript
运行
复制
---
something:
   blah:
      x: {{ y }}
      {%- set names = [ 'John', 'Amy' ] %}
      z: >
        {{ lookup('file', './other-file.j2') | upper | indent(4*2) }}

other-file.j2

代码语言:javascript
运行
复制
{%- for name in names %}
Hello {{ name }}
{%- endfor %}

用这个可操作的剧本运行它:

代码语言:javascript
运行
复制
---
- hosts: localhost
  connection: local
  tasks:
  - name: generate template
    template:
      src: "main.yaml.j2"
      dest: "output.yaml.j2"
      trim_blocks: False
    register: templating
    vars:
      y: 5

期望输出

代码语言:javascript
运行
复制
---
something:
   blah:
      x: 5
      z: >
        HELLO JOHN
        HELLO AMY

实际输出

代码语言:javascript
运行
复制
---
something:
   blah:
      x: 5
      z: >
        {%- FOR NAME IN NAMES %}
        HELLO {{ NAME }}
        {%- ENDFOR %}

最佳猜测

我想我快到了。我只需要一个过滤器,它将Jinja2模板应用于文本。

例如:

代码语言:javascript
运行
复制
{{ lookup('file', './other-file.j2') | template | upper | indent(4*2) }}

(但template并不是真正的过滤器。也许还有别的名字?)

我还试过什么

代码语言:javascript
运行
复制
{{ include './other-file.j2' | upper | indent(4*2) }}

不起作用。

致命: 127.0.0.1:失败!=> {“已更改”:false,"msg":"AnsibleError:模板错误,而模板字符串:预期的令牌‘结束打印语句’,得到'string'.字符串:---\nsomething:\n blah:\n x: {{ y }}\n {%- set names = [ 'John', 'Amy' ] %}\n z: >\n {{ include './other-file.j2' | upper | indent(4*2) }}"}

代码语言:javascript
运行
复制
{% include './other-file.j2' | upper | indent(4*2) %}

TemplateNotFound://其他-FILE.J2“

不起作用。

用例

对于上下文,我的用例是我有一个Jinja2模板生成AWS CloudFormation模板。我试着用YAML而不是JSON来做这一切。(因为YAML可以有注释,而且您不必担心列表中的最后一项是否带有后缀逗号,而且通常更容易读、写和调试。)一些CloudFormation资源需要粘贴到YAML文件中的文本JSON。(如CloudWatch仪表板体)。因此,我希望在YAML中有另一个文件,Jinja2将其转换为json,并将其粘贴到我的整体YAML模板中。我希望使用for循环生成这个仪表板,并传入变量。我想要一个单独的

EN

回答 1

Stack Overflow用户

发布于 2020-02-28 03:32:00

而不是file插件

代码语言:javascript
运行
复制
lookup('file', './other-file.j2')

使用template 插件

代码语言:javascript
运行
复制
lookup('template', './other-file.j2')

注意,变量{% set names = ['John', 'Amy'] %}的作用域是模板main.yaml.j2。如果在模板other-file.j2中使用此变量,则命令lookup('template', './other-file.j2')将与错误崩溃:

"AnsibleUndefinedVariable:‘名称’是未定义的“

溶液

在剧本的范围内声明变量。例如

代码语言:javascript
运行
复制
  - template:
      src: "main.j2"
      dest: "output.txt"
    vars:
      names: ['John', 'Amy']

main.j2

代码语言:javascript
运行
复制
{{ lookup('template', './other-file.j2') }}

other-file.j2

代码语言:javascript
运行
复制
{% for name in names %}
Hello {{ name }}
{% endfor %}

代码语言:javascript
运行
复制
shell> cat output.txt 
Hello John
Hello Amy
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60443820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档