1

I have jinja2 template which get data variables from yaml in the form of 'keys : value'.

The issue is when I run jinja2 template, it will print the line that has empty 'value'.

How can I do so that it will not print the line that is empty. Otherwise, it will appear None.

For example;

-Template

set first {{ABC}}
set second {{DEF}}
set third {{GHI}}

-yaml data

ABC : data1
DEF :
GHI : data3

If I run this, it will state that;

set first data1
set second None
set third data3

I don't want it to be this way. I want it to print;

set first data1
set third data3

How to do that?by preventing line from being added if the variable is undefined.

Thanks,

Updated script: -

TEMPLATE_FILE = { 'trial_1': 'trial.tcl' }
    for f,s in TEMPLATE_FILE.items():

    template = templateEnv.get_template( s )

    with open('tmp.yaml', 'rb') as stream:
        try:
            yaml_input_data = yaml.load(stream)
        except yaml.YAMLError as exc:
            pass
    print(yaml_input_data)

    for k, v in yaml_input_data.items():
        if v is None:
            yaml_input_data.pop(k)
    print(yaml_input_data)

    with open(f, 'w') as outfile:    
        outfile.writelines(template.render(yaml_input_data))
    print '\nWrote',f

Updated jinja2 template

{% for k, v in yaml_input_data.iteritems() %}
    {# use k, v #}
set first {{ABC}}
set second {{DEF}}
set third {{GHI}}
{% endfor %}
k-rd
  • 11
  • 1
  • 4
  • You are not using the variables `k` and `v`. This might help you understand how things work - http://stackoverflow.com/questions/19141073/rendering-a-python-dict-in-jinja2-werkzeug I would suggest studying basics how python interacts with Jinja and how to Jinja works. This is a good example which uses Flask, but concepts can be generalized - https://realpython.com/blog/python/primer-on-jinja-templating/ – Aditya Nov 18 '16 at 20:37

2 Answers2

1

You can use the Jinja2 conditional blocks.

{% if ABC %}
set first {{ABC}}
{% endif %}
{% if DEF %}
set second {{DEF}}
{% endif %}
{% if GHI %}
set third {{GHI}}
{% endif %}

This will verify that each value exists. If it doesn't exist, then the line is skipped, and nothing inside the given {%if%}{%endif%} block is written.

TheF1rstPancake
  • 2,318
  • 17
  • 17
0

You can use Jinja's {% if variable %} blocks - @Jalepeno112 answers it well for this question. However, if possible I would suggest parsing the YAML into a data structure like a dictionary in python and then using the data structure in the Jinja template.

This will give you the opportunity to clean the data in python and then send only the values that exist.

I am making an assumption here that the YAML is being passed via python to Jinja as you have also added python tag to the question.

Edit 1: There are multiple ways to achieve this but adding a simple example to show what I mean.

with open('tmp.yaml', 'r') as stream:
    try:
        yaml_input_data = yaml.load(stream)
    except yaml.YAMLError as exc:
        # handle error
        pass

print(yaml_input_data)
# {'ABC': 'data1', 'DEF': None, 'GHI': 'data3'}

for k, v in yaml_input_data.items():
    if v is None:
        yaml_input_data.pop(k)

# Now pass yaml_input_data to the Jinja template
print(yaml_input_data)
#{'ABC': 'data1', 'GHI': 'data3'}

Edit2: Can you change the Jinja template to something like this?

{% for k, v in yaml_input_data.iteritems() %}
    {# use k, v #}
{% endfor %}
Aditya
  • 610
  • 4
  • 11
  • Yup correct, I'm using Python as well by import jinja2 and yaml. So, how can I do that? – k-rd Nov 16 '16 at 04:02
  • @k-rd Added an example of what I wanted to suggest as edit 1 in the anwer – Aditya Nov 16 '16 at 04:25
  • Anyhow, it still display the variable in the template which correspond to the undefined 'key'. How can I get the output so that it just print the defined key only. Eg: set first data1 set third data3 – k-rd Nov 17 '16 at 09:16
  • @k-rd can you share your code? I think there is some bug in the code as the dictionary has been updated and no longer has the key it shouldn't be displayed in the template – Aditya Nov 17 '16 at 14:16
  • I added the code here. The key is not show in the template, but the variable in the template that correspond to the key is still display. If can, I do not want it to display the variable as well. – k-rd Nov 18 '16 at 01:36
  • @k-rd I added a suggestion for using the data in template, see if it helps – Aditya Nov 18 '16 at 03:37
  • I got this error message : jinja2.exceptions.UndefinedError: 'yaml_input_data' is undefined . Might be the only way is to do the 'if else' statement as Jalepeno112 said? If could, I want to avoid using that as I have lot more variable. Just wondering might have another way instead of that. – k-rd Nov 18 '16 at 04:24
  • Are you matching the right variable names? I am just making variable names up as I dont know your code. Use my snippet just as a reference and make sure variable names match up, this approach should work. I use this approach as it is dynamic and I dont want to change the template each time I change my YAML files. – Aditya Nov 18 '16 at 04:35
  • I modified the jinja2 template as above, is it correct as what you suggest? – k-rd Nov 18 '16 at 07:32