jinja2模板中使用set命令进行变量替换时的问题

时间:2019-01-22 11:53:46

标签: yaml jinja2

我有一个YAML文件,该文件的两个字典的默认值定义如下:

sample:
  high:
    name: high-volume
    alias: hi-vl

hi-vl:
  ab1:    
    add:
      range: 0
      range1: 0
    remove:
      range: -1
      range1: -1

要迭代并从jinja2模板获取值,我正在使用以下代码:

{% for key, value in sample.iteritems() %}
{% set al = value.alias %}
{% for key1, value1 in al.iteritems()  %}

执行此模板生成YAML文件时,出现错误:

"msg": "AnsibleUndefinedVariable: 'unicode object' has no attribute 'iteritems'"}

set变量正在将变量更改为unicode。 如果我在set语句中用直接value代替value.alias,则迭代工作正常。

我尝试使用to_yamltojson之类的过滤器,但它们会转换为字符串而不呈现为dict。

1 个答案:

答案 0 :(得分:0)

您可以使用Python将yaml转换为dict,创建jinja字符串,将jinja字符串加载到Template类中并进行渲染:

请考虑将Yaml存储在名为specs.yaml的文件中。我们首先将其打开并将其转换为字典:

import yaml
import json
from jinja2 import Template

with open('specs.yaml') as f:
  specs = f.read()
  specs_dict = yaml.load(specs) #get dict from yaml

print(json.dumps(test, indent=4)) #print pretty dict tree
#Output:

{
"sample": {
    "high": {
        "name": "high-volume",
        "alias": "hi-vl"
    }
},
"hi-vl": {
    "ab1": {
        "add": {
            "range": 0,
            "range1": 0
        },
        "remove": {
            "range": -1,
            "range1": -1
        }
    }
}
}

现在,我们可以定义jinja字符串并创建一个模板对象来呈现它。

#form jinja string
jinja_string = """{% for key, value in specs_dict['sample'].items() %}                              
{% set al = value['alias'] %}
{% for key, value in specs_dict[al].items() %}
{{key}}:{{value}}
{% endfor %}                        
{% endfor %}"""

# create template object and render it
template = Template(jinja_string)
print(template.render(specs_dict=specs_dict))
#Output:
ab1:{'add': {'range': 0, 'range1': 0}, 'remove': {'range': -1, 'range1':-1}}