0

Below is my code. I'm getting a syntax error but in Python there is no such issue

{% for stud in  [dict(item.split("=") for item in item.split(",")) for item in item.split(";")] %}
  print {"hi"}
{% endfor %}

Exception:

Syntax error in jinja2 template: expected token ',', got 'for'

Sample Input:

studId=ValueA,studName=valueB;studId=ValueC,studName=ValueD

Sample code used in Python:

item = "studId=ValueA,studName=valueB;studId=ValueC,studName=ValueD"


for stud in [dict(item.split("=") for item in item.split(",")) for item in item.split(";")]:
  print(stud['studName'])

Sample output:

valueB
ValueD
wovano
  • 4,543
  • 5
  • 22
  • 49
josh
  • 11
  • 4
  • 1
    jinja isn't python, you can't expect to use python code within it – Sayse Oct 18 '21 at 12:59
  • *It would be helpful if you can provide sample input and desired output*. For example, `item = 'key1=val1;key2=val2'` seems to be a sample input in this case. – rv.kvetch Oct 18 '21 at 13:01
  • noted. can you please kindly advice how it can be done. I am new to it – josh Oct 18 '21 at 13:01
  • 1
    @rv.kvetch, I have updated my question with sample input, sample output and sample code in python – josh Oct 18 '21 at 13:05

1 Answers1

0

At least from what I noticed, jinja doesn't seem to support list comprehensions.

A workaround I've tested with is to pass in a function which performs a list comprehension to Jinja2, which can then be used to render the template:

import jinja2


item = "studId=ValueA,studName=valueB;studId=ValueC,studName=ValueD"


def get_values(values):
    return [dict(v.split("=") for v in v.split(",")) for v in values.split(";")]


ts = """\
{% for value in get_values(values) -%}
  {{ value.studName }}
{% endfor %}\
"""

fields = {'get_values': get_values, 'values': item}

rendered = jinja2.Template(ts).render(**fields)

Output:

>>> rendered
'valueB\nValueD\n'
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53
  • so there is no other options – josh Oct 18 '21 at 14:39
  • well, you could look around and maybe try Googling for a workaround. I know it could work if you convert your list comprehension to a nested `for` loop, though. – rv.kvetch Oct 18 '21 at 14:44
  • can i know my jinja2 template how to call your code ya. i need pass value from jinja2 to your python – josh Oct 18 '21 at 14:54
  • @josh I didn't really understand that – rv.kvetch Oct 18 '21 at 15:08
  • Let me explain how it work. in my Ansible variable i will pass studIdf and studName to jinja2 template. If i want jinja2 call python script for every loop is it possible? python like a function return the value – josh Oct 18 '21 at 15:13
  • @josh I see, that definitely helps clarify the use case. I updated the answer above with info on how you can pass a Python function in to jinja2 when rendering the template. – rv.kvetch Oct 18 '21 at 15:26
  • cool. can i know this python code should it be in j2 or should place in separate file. besides this ts = referring to what ya. can share me some details how it will call the method get_values. should i put in same file or different file so that i know where to start n start research in calling the function get_values – josh Oct 18 '21 at 15:30
  • Hmm, the python code should be in a separate python module ideally, since I suppose Jinja might not understand list comprehensions. The `ts` is the template string that you pass in to Jinja. When `render` is called, Jinja will then perform string interpolation (roughly) and evaluate the template string, after replacing template variables in the `fields` mapping that you define. – rv.kvetch Oct 18 '21 at 15:33
  • jinja is quite funny, why didn't it just use python syntax? – theonlygusti Jan 15 '23 at 00:29