30

I'm trying to retrieve entries from a python dictionary in jinja2, but the problem is I don't know what key I want to access ahead of time - the key is stored in a variable called s.course. So my problem is I need to double-substitute this variable. I don't want to use a for loop because that will go through the dictionary way more than is necessary. Here's a workaround that I created, but it's possible that the s.course values could change so obviously hard-coding them like this is bad. I want it to work essentially like this:

{% if s.course == "p11" %}
    {{course_codes.p11}}
{% elif s.course == "m12a" %}
    {{course_codes.m12a}}
{% elif s.course == "m12b" %}
    {{course_codes.m12b}}
{% endif %}

But I want it to look like this:

{{course_codes.{{s.course}}}}

Thanks!

tytk
  • 2,082
  • 3
  • 27
  • 39

3 Answers3

33

You can use course_codes.get(s.course):

>>> import jinja2
>>> env = jinja2.Environment()
>>> t = env.from_string('{{ codes.get(mycode) }}')
>>> t.generate(codes={'a': '123'}, mycode='a').next()
u'123'
R. Max
  • 6,624
  • 1
  • 27
  • 34
17

There is no need to use the dot notation at all, you can do:

"{{course_codes[s.course]}}"
Mike Vella
  • 10,187
  • 14
  • 59
  • 86
  • 3
    when i try to use like above it returning Could not parse the remainder: '[s.sample_type]' from 'samType[s.sample_type]' – Sundar G Aug 08 '20 at 12:09
7

I'm using Jinja with Salt, and I've found that something like the following works well:

{% for role in pillar.packages %}
  {% for package in pillar['packages'][role] %}
    install_{{ package }}:
      pkg.installed:
        - name: {{ package }}
  {% endfor %}
{% endfor %}

That is, use the more verbose [ ] syntax and leave the quotes out when you need to use a variable.

Poorkenny
  • 1,246
  • 11
  • 16
onlyanegg
  • 517
  • 7
  • 15