How to set variable if another variable defined in one line? - django

I'm using this code to set variable and then check if this variable is 1:
{% if pillar['setup_user'] is defined %}
{% set var_setup_user = pillar['setup_user'] %}
{% else %}
{% set var_setup_user = 1 %}
{% endif %}
{% if var_setup_user == 1 %}
setup-user:
cmd.run:
- name: |
...
- shell: /bin/bash
- user: root
{% endif %}
Is there a way to check this in one or maybe two lines?
Thank you

{% set var_setup_user = pillar['setup_user']|d(1) %}
d is the alias for default filter.

Does a normal ternary operator work?
{% set var_setup_user = pillar['setup_user'] if pillar['setup_user'] is defined else 1 %}

Related

Apply if-else statement on a dictionary using django-templates

In a django - webapp I am classifying between two classes of images i.e. Ants and Bees
I have returned the dictionary to the templates(index.html)
context={
'ant':("%.2f" % predictions[0]),
'bee': ("%.2f" % predictions[1]),
}
when applying this
{% for key , value in pred.items %}
<p>{{key}}: {{value}}%</p>
{% endfor %}
i got this which is pretty much what i wanted to display now i want to display the one with greater probability how do i do it ?
I cannot access elements of the dictionary inside if else statement , though i tried doing this
{% for key, value in pred.items %}
{% if value.0 > value.1 %}
<p>Result : {{value.0}}</p>
{% elif value.0 < value.1 %}
<p>Result: {{key}}</p>
{% endif %}
{% endfor %}
Since your data structure does not look very dynamic and flexible, you could do it the following static way:
Result:
{% if pred.ant > pred.bee %}
Ant: {{ pred.ant }}
{% elif pred.ant < pred.bee %}
Bee: {{ pred.bee }}
{% else %}
Ant: {{ pred.ant }}
Bee: {{ pred.bee }}
{% endif %}

Drupal 8.x: How to pass a variable from child Twig template to parent? [duplicate]

I would like to include the same variables in different templates
vars_catchphrase.twig
{% set catchphrase_size = '' %}
{% if var.tile_catchphrase|length <= 4 %}
{% set catchphrase_size = 'size-lg' %}
{% elseif var.tile_catchphrase|length >= 5 and var.tile_catchphrase|length <= 8 %}
{% set catchphrase_size = 'size-md' %}
{% elseif var.tile_catchphrase|length >= 9 and var.tile_catchphrase|length <= 12 %}
{% set catchphrase_size = 'size-sm' %}
{% elseif var.tile_catchphrase|length >= 13 %}
{% set catchphrase_size = 'size-xs' %}
{% endif %}
I tried to include with this (because the context is sometime different) :
{% include 'vars_catchphrase.twig' with { 'var' : post } %}
When the context is different from post I use another one :
{% include 'vars_catchphrase.twig' with { 'var' : item } %}
example.twig
{% for item in list %}
{% include 'vars_catchphrase.twig' with { 'var' : item } %}
<p class="catchphrase {{ catchphrase_size }}">{{ item.title }}</p>
{% endfor %}
The variable is empty. Can I have some help please ?
Templates you include have their own variable scope, this means variables defined inside this template will not be known out the template. This said, included templates also can't alter the parent's context (by default), this is due to twig passing the context array by value, not by reference.
foo.twig
{% set foo = 'foo' %}
{% include 'bar.twig' %}
{{ foo }}
bar.twig
{% set foo = 'bar' %}
The example above will still output foo
In order to solve your problem, I'd suggest adding a custom filter to twig
<?php
$twig->addFilter(new \Twig\TwigFilter('catchphrase_size', function($value) {
switch(true) {
case strlen($value->tile_catchphrase) >= 13: return 'size-xs';
case strlen($value->tile_catchphrase) >= 9: return 'size-sm';
case strlen($value->tile_catchphrase) >= 5: return 'size-md';
default: return 'size-lg';
}
});
This way you can use the filter where ever,
{% for item in list %}
<p class="catchphrase {{ item|catchphrase_size }}">{{ item.title }}</p>
{% endfor %}

condition template in ansible

I have this template (set_ip.j2):
{% if '{{ansible_env.SSH_CONNECTION.split(' ')[2]}}' == '{{ ip_ssh }}' %}
address = {{ ip_db }}
name='db1'
{% endif %}
but this condition not work! I want address and name set by this value in the config file.
Never ever use nested expressions in Jinja2:
{% if ansible_env.SSH_CONNECTION.split(' ')[2] == ip_ssh %}
address = {{ ip_db }}
name='db1'
{% endif %}

Change variable in Ansible template based on group

I've got an Ansible inventory file a bit like this:
[es-masters]
host1.my-network.com
[es-slaves]
host2.my-network.com
host3.my-network.com
[es:children]
es-masters
es-slaves
I also have a Jinja2 template file that needs a certain value set to "true" if a host belongs to the "es-masters" group.
I'm sure that there's a simple way of doing it but after some Googling and reading the documentation, I've drawn a blank.
I'm looking for something simple and programmatic like this to go in the Jinja2 template:
{% if hostvars[host][group] == "es-masters" %}
node_master=true
{% else %}
node_master=false
{% endif %}
Any ideas?
You do it the other way around.
You check if the identifier (hostname or IP or whatever is in your inventory) is in the defined group. Not if the group is in the hostvars.
{% if ansible_fqdn in groups['es-masters'] %}
node_master=true
{% else %}
node_master=false
{% endif %}
But, what you better should do is this:
Provide default in template
# role_name/templates/template.j2
node_master={{ role_name_node_master | default(true) }}
Than override in group_vars
# group_vars/es-masters.yml
role_name_node_master: false
If your inventory does not identify hosts with ansible_fqdn, ansible_hostname, etc., you can also use group_names to check if the current host has "es-masters" as one of its groups.
{% if 'es-masters' in group_names %}
node_master=true
{% else %}
node_master=false
{% endif %}
See https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#accessing-information-about-other-hosts-with-magic-variables
To avoid error with non existing group you should check first if the group exists:
{% if 'es-masters' in group_names and ansible_fqdn in groups['es-masters'] %}
node_master=true
{% else %}
node_master=false
{% endif %}
{% if ansible_fqdn in groups['es-masters'] %}
{% set node_master=true %}
{% else %}
{% set node_master=false %}
{% endif %}
maybe like this? change the var which named node_master, rather than use a txt

Variable subtraction in django templates

It is able to write {{ myval.add:5 }}, {{ myval|add:value }} and even {{ myval|add:-5 }}.
However, I can't find out what I should type to add value * -1 like {{ myval|add:-value }}. This doesn't work, sadly.
You need to use double quotes:
{{ myval|add:"-5" }}
This subtracts five from myval.
The built-in Django template tags/filters aren't all-encompassing, but it's super easy to write your own custom template tags: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
You could make your own subtract template tag pretty easily:
#register.filter
def subtract(value, arg):
return value - arg
Use django-mathfilters from PyPI: https://pypi.python.org/pypi/django-mathfilters
To install :
$ pip install django-mathfilters
Then add mathfilters in your INSTALLED_APPS.
In template:
{% load mathfilters %}
<ul>
<li>8 + 3 = {{ 8|add:3 }}</li>
<li>13 - 17 = {{ 13|sub:17 }}</li>
{% with answer=42 %}
<li>42 * 0.5 = {{ answer|mul:0.5 }}</li>
{% endwith %}
{% with numerator=12 denominator=3 %}
<li>12 / 3 = {{ numerator|div:denominator }}</li>
{% endwith %}
<li>|-13| = {{ -13|abs }}</li>
</ul>
I recently started working with Django and stumbled upon this one as well: I needed a very simple template loop that stops printing after n times and shows a "more" link to toggle the rest of the items.
With great interest I read the struggle of people trying to understand why this is not being added to the Django default filters (since before 2013). I didn't feel like creating a custom template tag and I kind of found a way to subtract 2 variables using strings and add in combination with with and stringformat
Let's say I have a list of items where I want to print the first 2 and hide the rest, showing how many hidden items are there, eg.
John, Anna and 5 others like this (when given a list of 7 items)
As long as the number of visible items is harcoded in the template (eg. 2), it's possible to add the negative 2 |add:"-2", but I wanted the number of visible items to be a variable as well. The Math-filter library as suggested above doesn't seem up to date (I haven't tested it with Django 2.x).
The trick seems to be to use the add helper to concat the strings "-" with the integer as string, so it can be coerced back to a negative integer in a any consecutive calls to the add helper. This doesn't work however if the value is not a string, so that's where the stringformat helper comes in.
With string value
template posts.html (note how visible is explicitely passed as string - alternative below)
{% for post in posts %}
<h4>{{ post.title }}</h4>
...
{% include 'show_likes.html' with likes=post.likes visible="3" %}
{% endfor %}
template show_likes.html (note the add:0 to make the boolean operator work)
{% with show=visible|default:"2" %}
{% for like in likes %}
{% if forloop.counter <= show|add:0 %}
{% if not forloop.first %},{% endif %}
{{ like.username }}
{% endif %}
{% endfor %}
{% if likes|length > show|add:0 %}
{% with rest="-"|add:show %}
and {{ likes|length|add:rest }} more
{% endwith %}
{% endif %}
like this
{% endwith %}
Alternative with integer
You could just convert your integer to a string in the calling template using |stringformat:"d"
If however the number of visible items you want to show is an integer, you'll have to add a call to stringformat:"d" to have it converted to string
template posts.html
{% for post in posts %}
<h4>{{ post.title }}</h4>
...
{% include 'show_likes.html' with likes=post.likes visible=3 %}
{% endfor %}
template show_likes.html
{% with show=visible|default:2 %}
{% with show_str=show|stringformat:"d" %}
{% for like in likes %}
{% if forloop.counter <= show %}
{% if not forloop.first %},{% endif %}
{{ like.username }}
{% endif %}
{% endfor %}
{% if likes|length > show|add:0 %}
{% with rest="-"|add:show_str %}
and {{ likes|length|add:rest }} more
{% endwith %}
{% endif %}
{% endwith %}
{% endwith %}
Since I'm a very beginner with Django and Python, I'm pretty sure this approach is far worse than actually creating a custom helper! So I'm not suggesting anyone should be using this. This was just my attempt on trying to solve this with the available template helpers and without any custom stuff.
Hope this helps
Lo primero es multiplicar por -1 para convertirlo en una valor negativo y guardarlo en una variable y posterior a usar la suma
The first thing is to multiply by -1 to turn it into a negative value
and save it in a variable and then use the add
{% widthratio val2 1 -1 as result %}
{{result|add:val1}}
After search I found that I can make {% with var=value %} with filters to make the arithmetic operations "with other variables or not"
For example: I have x = 5 and y = 3 and need to add the y's value to x value, all what I need is these steps:
1- Create variable x : {% with x=5 %}
2- Create variable y : {% with y=3 %}
3- In my HTML tags, say <h1>, write that : <h1>{{ x|add:y }}</h1>
4- Close the y's with : {% endwith %}
5- Close the x's with : {% endwith %}
Hope it works with you, it worked with me.
{% with i=3 %}
{% with x=1 %}
<h1>{{i|add:x}}</h1> <!-- result is 4 -->
{% endwith %}
{% endwith %}