0

I would like to pass in variables from python to jinja2 when rendering templates.

'with_remediation' is a boolean/varilable that I would like to pass into the jinja2 template for evaluation.

Here is how the jinja2 template file looks like:


{% if with_remediations %}
no hostname
{% endif %}

hostname {{ nodes.hostname }}

In my rendering function, I have these lines of code:

with_remediation = True
baseline = env.get_template(template)
config = baseline.render(nodes = node_object[index],with_remediation)

When I execute code, I get the following error:

    config = baseline.render(nodes = node_object[index],with_remediation)
SyntaxError: non-keyword arg after keyword arg

However, if I specify the boolean directly into the function call:

config = baseline.render(nodes = node_object[index],with_remediation=True)

It runs without errors but not the expected output.

Here is the output when executed:

switch
/templates/cisco/ios/switch/test.jinja2

Push configs? [y/N]: y
config term
Enter configuration commands, one per line.  End with CNTL/Z.
switch(config)#
switch(config)#
switch(config)#
switch(config)#
switch(config)#hostname switch
switch(config)#end
switch#

The expected result should be:

switch
/templates/cisco/ios/switch/test.jinja2

Push configs? [y/N]: y
config term
Enter configuration commands, one per line.  End with CNTL/Z.
switch(config)#
switch(config)#no hostname
switch(config)#
switch(config)#
switch(config)#hostname switch
switch(config)#end
switch#

Why is it not executing the {% if with_remediations %} section since it holds true?

  • 1
    because you passed in `with_remediation` not `with_remediations` note the "s" on the end. – jordanm Nov 08 '19 at 19:52
  • Also, the reason you got the first error is that jinja expects [keyword arguments](https://stackoverflow.com/questions/1419046/normal-arguments-vs-keyword-arguments) for the `render()` function. If you have multiple variables that you want to pass to the template you can collect them in a dict and pass to the `render()` function. – arghol Nov 08 '19 at 20:03
  • Thanks for the catch @jordanm. I fixed that and now it's running the {% if with_remediation %} part. However, I cannot simply pass in the variable like what arghol mentioned. May you please give me an example of how to pass one varilable vs. multiple variables into render()? I don't quite understand... – superloopnetworks Nov 08 '19 at 20:08
  • `kwargs = {'with_remediations': True, 'nodes': node_object[index]}; baseline.render(**kwargs)` – jordanm Nov 08 '19 at 20:09
  • Thanks jordanm. @arghol Did you have a different method of passing variable in? – superloopnetworks Nov 08 '19 at 20:43
  • @jordanm, If I use that way, then 'with_remediations' is always set to "true".. Hence, I wanted to make it a variable because depending on which function that call this render function, with_remediations is either true or false. – superloopnetworks Nov 08 '19 at 20:45
  • I was able to fix it by doing this: config = baseline.render(nodes = node_object[index],with_remediation=with_remediation) – superloopnetworks Nov 08 '19 at 20:53
  • Thanks everyone! – superloopnetworks Nov 08 '19 at 21:02

1 Answers1

0
{% if with_remediations %}
Works when condition is true //Any Statement
{% else %}
no hostname //Any Statement
{% endif %}

def demo():
boo=True`
  return render_template("demo.html",with_remediations=boo)
Jayesh Babu
  • 1,389
  • 2
  • 20
  • 34
  • 2
    could you add some explanation about what's going on here? also the first paragraph looks to be HTML template and the second is Python code, but it's not formatted in a way that makes that clear – Sam Mason Nov 11 '19 at 14:09
  • @SamMason Jayesh has it correct. Essentially I was just passing 'boo' into render_template() function without specifying with_remediation=boo. Please check my comments above. – superloopnetworks Nov 11 '19 at 21:41