rougail/docs/tutorial/calculation.rst
2025-09-18 17:17:02 +02:00

258 lines
7.1 KiB
ReStructuredText

Calculation with a jinja type
===============================
.. objectives:: Objectives
In this section we will learn how to create new ways of calculation.
Up to now, our only way of dynamically (that is, during the runtime) calculating
a value is to point on another variable's value. But this is not the only way.
A jinja calculated variable's hidden property
------------------------------------------------
We can hide or disable some variables or families with other techniques than
pointing on a variable's value.
Let's reason on the previous HTTPS proxy configuration's manual mode:
.. code-block:: yaml
manual:
use_for_https:
description: Also use this proxy for HTTPS
default: true
https_proxy:
type: family
description: HTTPS Proxy
hidden:
variable: manual.use_for_https
This is extracted from the proxy's manual configuration we discussed before.
We see here that there is an `https_proxy` family that is going to be hidden
depending on the value of another variable:
.. code-block:: yaml
https_proxy:
type: family
hidden:
variable: manual.use_for_https
Now we could write it like that:
.. code-block:: yaml
manual:
use_for_https:
description: Also use this proxy for HTTPS
default: true
https_proxy:
description: HTTPS Proxy
type: family
hidden:
type: jinja
jinja: |
{% if rougail.manual.use_for_https %}
the HTTPS Proxy family is hidden
{% endif %}
Yes, it's done in a more complicated (but more powerful) way.
Let's explain this a little:
We have replaced this simple hidden property declaration:
.. code-block:: yaml
hidden:
variable: manual.use_for_https
by this (more complicated) hidden property declaration:
.. code-block:: yaml
hidden:
type: jinja
jinja: |
{% if rougail.manual.use_for_https %}
the HTTPS Proxy family is hidden
{% endif %}
The fact is that it has same result, but here we have more possibilities.
The hidden process is done by a calculation.
Another jinja calculation type sample
---------------------------------------
We can now hide or disable some variables or families with other techniques than
pointing on a variable's value.
Let's reason upon the proxy's manual configuration we discussed before.
We have the :file:`dict/02-proxy_manual.yml` structure file:
.. code-block:: yaml
:caption: the :file:`structfile/02-proxy_manual.yml` file
---
version: '1.1'
manual:
description: Manual proxy configuration
type: family
disabled:
type: jinja
jinja: |
{% if rougail.proxy.proxy_mode != 'Manual proxy configuration' %}
the proxy mode is not manual
{% endif %}
.. questions:: Question
**question**: OK then. What happens when you select the "Manual proxy configuration"?
Here if the user selects the "Manual proxy configuration" proxy mode,
the the `manual` family will be disabled. This is what the jinja code says.
Let's explain it more precisely.
.. note:: The "the proxy mode is not manual" output is be used in the log outputs
for example while
Why Jinja?
---------------
.. questions:: What about this `Jinja` type?
If the :term:`Jinja` template returns some text, then the family will be `disabled`. Otherwise it is accessible.
Deactivating a family means that we will not be able to access it as well as the variables or families included in this family.
.. note:: If the Jinja template does not return any text, the variable will be **enabled**.
Here we are using the Jinja condition statement.
.. glossary::
Jinja
`Jinja <https://jinja.palletsprojects.com>`_ is a template engine.
we are using Jinja in a classical way, that is, Jinja allows us to handle different cases,
for example with the `if` statement.
What can be calculated?
---------------------------
We have seen that the `disabled` or `hidden` properties could be calculated.
The default values can be calculated too.
.. todo:: montrer un exemple de valeur par défaut calculées (type jinja)
.. todo:: montrer aussi ici des exemples de calculs de valeurs variables, ce qui est un des usages principaux de jinja
Using jinja in a dynamic family declaration
-----------------------------------------------
Let's come back to the previous section's :ref:`dynamic family example <conditional_hidden_family>`\ .
In a dynamic family, as seen before, you have the possibility to name your identifier. In the classic declaration,
the identifier's variable is named "identifier" by default. Sounds logical:
.. code-block:: yaml
"{{ identifier }}_proxy":
description: "{{ identifier }} Proxy"
dynamic:
- HTTPS
- SOCKS
dynamic:
- HTTPS
- SOCKS
Here the identifer's variable takes the value of the `dynamic` family parameter.
We have another possibility:
.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_050/firefox/20-manual.yml
:language: yaml
:caption: firefox/20-proxy.yml
..
manual:
use_for_https:
description: Also use this proxy for HTTPS
default: true
"{{ identifier }}_proxy":
description: "{{ identifier }} Proxy"
dynamic:
- HTTPS
- SOCKS
hidden:
jinja: |
{% if my_identifier == 'HTTPS' and manual.use_for_https %}
HTTPS is same has HTTP
{% endif %}
params:
my_identifier:
type: identifier
description: |
in HTTPS case if "manual.use_for_https" is set to True
address:
description: "{{ identifier }} address"
default:
variable: manual.http_proxy.address
port:
description: "{{ identifier }} port"
default:
variable: manual.http_proxy.port
version:
description: SOCKS host version used by proxy
choices:
- v4
- v5
default: v5
disabled:
type: identifier
when: 'HTTPS'
Here in the `hidden` property we have the possibility to name an identifier:
.. code-block:: yaml
params:
my_identifier:
type: identifier
Here, the identifer is named `my_identifier`, in a jinja calculation:
.. code-block:: yaml
hidden:
jinja: |
{% if my_identifier == 'HTTPS' and manual.use_for_https %}
HTTPS is same has HTTP
{% endif %}
params:
my_identifier:
type: identifier
description: |
in HTTPS case if "manual.use_for_https" is set to True
.. keypoints:: Key points
Here we have come to the possibility of making any kind of calculations based on the state of the :term:`configuration`.
This is an important feature to manage the stateful aspect of a configuration.