SaltStack: conditional include: Error if empty - salt-stack

I have a conditional include which looks like this:
include:
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
This works in most cases.
But it fails if CONDITION-A and CONDITION-B are false.
How to handle this?

I use this pattern now:
include:
- dummy
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
dummy.sls:
dummy-no-op:
test.nop
Not nice, but works.
Better (simpler, more obvious) answers are welcome.
Docs for test.nop

This is also ugly, but you could wrap the entire include block in an if condtion that check if either CONDITION-A or CONDITION-B is true:
{% if CONDITION-A or CONDITION-B %}
include:
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
{% endif %}
This way jinja will remove the include block if both conditions are false

Related

Is there a "do nothing" or "pass" statement in saltstack? [duplicate]

I have a conditional include which looks like this:
include:
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
This works in most cases.
But it fails if CONDITION-A and CONDITION-B are false.
How to handle this?
I use this pattern now:
include:
- dummy
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
dummy.sls:
dummy-no-op:
test.nop
Not nice, but works.
Better (simpler, more obvious) answers are welcome.
Docs for test.nop
This is also ugly, but you could wrap the entire include block in an if condtion that check if either CONDITION-A or CONDITION-B is true:
{% if CONDITION-A or CONDITION-B %}
include:
{% if CONDITION-A %}
- foo.bar
{% endif %}
{% if CONDITION-B %}
- blu.bla
{% endif %}
{% endif %}
This way jinja will remove the include block if both conditions are false

Twig use one value in different for loop

Since I'm using a SaaS platform I don't have much space to do things differently.
I have two for loops in Twig:
{% for option in product.options %}
{{ option.title }}
{% if option.values %}
{% for value in option.values %}
{{ value.title }}
{% endfor %}
{% endif %}
{% endfor %}
{% for variant in product.variants %}
{{ variant.stock.level }}
{% endfor %}
What I try to do is to use variant.stock.level value inside the product.options for loop to show some HTML. This value always match the corresponding index value of the other for loop. I also think that's the only way to do this.
So what I mean is.....Let's say both for loops contain 3 elements.
Option1
Option2
Option3
Variant1
Variant2
Variant3
So option1 needs to have the value from variant1.
For the end result I need to know what the value of eg Variant1 is to show some HTML like so:
{% for value in option.values %}
{% check if value from corresponding variant is greater then 0 %}
<li class="on-stock">{{ value.title }}</li>
{% else %}
<li class="out-of-stock">{{ value.title }}</li>
{% endif %}
{% endfor %}
I don't know no other way to explain this :) Any help appreciated....
You are looking for attribute.
The attribute function can be used to access a "dynamic" attribute of a variable
Since the indexes are the same, you can use loop.index0
Example for your case
{% if attribute(option.variants, loop.index0) > 0 %}
// some stuff
{% endif %}
I'm not sure if I understood you correctly but you may use key from first loop to access product.variants with the same index.
{% for key, option in product.options %}
{{ option.title }}
{% if option.values %}
{% for value in option.values %}
{{ value.title }}
{% endfor %}
{% endif %}
{{ product.variants[key].stock.level }}
{% endfor %}

Can't get global variables in twig to work

So I have Twig running on top of Symfony 2.7. In the output html I'd like to have a few modules of text and in the last module I want some summary from all the previous ones (some data from all the previous modules' Entities) and I figured I'd append these summaries to a global variable while generating modules themselves to avoid a second loop. The code I'm using:
{% extends 'base.html.twig' %}
{% set list = '' %} {# HERE I SET A GLOBAL VAR #}
{% block body %}
<section>
<h2>{% trans %}MODULES{% endtrans %}</h2>
{% for m in plan.Modules %}
{{- block('module') -}}
{{ list }} {# HERE JUST FOR TESTING - IT'S EMPTY #}
{% endfor %}
</section>
{{ list }} {# HERE I WANT IT DISPLAYED, YET IT'S EMPTY :( #}
{% endblock %}
{% block module %}
<h3>{{ m.Module.title }}</h3>
{# HERE SOME MODULE TEXT I GET FROM COMPLICATED RELATIONS #}
{% if m.Module.list %}
{% set temp %}
{{ m.Module.shortTitle }}<br/>
{% endset %}
{% set list = list~temp %}
{% for l in m.Module.list %}
{% set temp %}
{{ l }}
{% endset %}
{% set list = list~temp %}
{% endif %}
{% endfor %}
{% endif %}
{{ list }} {# HERE IT'S WORKING #}
{% endblock %}
Any ideas?

Symfony : "if" does not work in a twig template

I'm trying to validate the size of an array before print a value, but the if instruction doesn't work. Always pass thought the if.
This is my code:
{% set size = custodian.phoneNumbers|length %}
{% if size > 3 %}
{% block phone_number3 %}{{phoneNumbers[2].phoneNumber }}{% endblock %}
{% endif %}
size is equal to 2
I try with this code and does not work as well.
{% set size = true %}
{% if size == false %}
{{size}}
{% endif %}
Please help!!!
Thanks in advance.
I found the answers myself
The block should be outside of the if.
{% block phone_type3 %}
{% if size >= 3 %}
{{ custodian.phoneNumbers[2].phoneType.value }}:
{% else %}
:
{% endif %}
{% endblock %}
{% block phone_number3 %}
{% if size >= 3 %}
<b>{{ custodian.phoneNumbers[2].phoneNumber }}</b>
{% endif %}
{% endblock %}

Twig and autoescaping

I'm learning Symfony2. Currently, I'm trying to render a form label in a twig template. The label includes an html tag, that is not rendered correctly in my twig file.
Here follows the piece of code where the form field is created:
$builder->add('zipcode', 'integer', array(
'label' => '<abbr title="Zone Improvement Plan">CAP</abbr> code',
));
In the twig file I render the field label as follows:
{{ form_label(form.zipcode) }}
I tried the raw, escape, e filters, but the results provided in my html page is always the string
<abbr title="Zone Improvement Plan">CAP</abbr> code
and not the corresponding HTML code!
Any suggestion?
Thanks in advance!
Later I found the solution.
The solution is to disable the autoescape within the label block provided by Symfony at path:
symfony / src / Symfony / Bridge / Twig / Resources / views / Form / form_div_layout.html.twig
So, in your twig file you have to put the following lines outside the form:
{% form_theme form _self %}
{% block generic_label %}
{% spaceless %}
{% if required %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %}
{% endif %}
<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>{% autoescape false %}{{ label|trans }}{% endautoescape %}</label>
{% endspaceless %}
{% endblock %}
From JeanValjean himself :
{% autoescape false %}{{ form.zipcode.vars.label | trans }}{% endautoescape %}
And to generalize this behaviour to your whole app, you can override the form block for labels :
{% block generic_label %}
{% spaceless %}
{% if required %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %}
{% endif %}
<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>
{% autoescape false %}{{ label|trans }}{% endautoescape %}
</label>
{% endspaceless %}
{% endblock %}
To disable the autoespace filter just to render a variable is not the best thing because when you read the code it's not really clear.
So, instead of :
{% autoescape false %}{{ label|trans }}{% endautoescape %}
You can use :
{{ label|trans|raw }}

Resources