Calculated properties
==========================

Synopsis
------------

Calculated properties allow you to add or remove properties to a :term:`variable` or a :term:`family` depending on the context.

Here is the list of editable properties:

.. list-table::
   :widths: 15 15 25
   :header-rows: 1

   * - Attribute applying to
     - Property's name
     - Comment

   * - Variable

       Family
     - hidden
     - Hides a variable or a family, in this case it is not accessible in `read-write` mode,
       but remains accessible in a calculation or in `read-only` mode.

       .. seealso:: :ref:`hidden access control <hidden>`.

   * - Variable

       Family
     - disabled
     - Deactivates a variable or family, in this case it is never accessible.

       .. seealso:: :ref:`disabled access control <disabled>`.

   * - Variable
     - frozen
     - A frozen variable is a variable that the :term:`operator` cannot change the value.

   * - Variable
     - mandatory
     - The variable expects a value other than `null` (or `None` in Python) or `[]` for multiple variables.

       .. seealso:: for non multiple variables we call it a :ref:`nullable variable <nullable_variable>`.

   * - Variable
     - empty
     - The multiple variable allow the value `null` (or `None` in Python)

       .. seealso:: we call it a :ref:`nullable variable <nullable_variable>`.

A property can be calculated. In this case we have two possibilities:

- calculation via Jinja (see also the tutorial with a real world sample :doc:`variable jinja <../tutorial/jinja>`)
- calculation via a variable (see also the tutorial with a real world sample :doc:`variable calculation <../tutorial/properties>`)

Parameters
---------------

Variable parameters
~~~~~~~~~~~~~~~~~~~

.. list-table::
   :header-rows: 1

   * - Parameter
     - Comment
     - Sample

   * - type

       `string`
     - Calculation type.

       This parameter is optional. It is deduced from the presence of the parameter "variable" in a calculation.
     - variable

   * - variable

       `string`

       `mandatory`
     - Name of the associated variable.

       It's better to use :term:`relative path` notation.
     - _.my_variable

   * - when/when_not
     - Compare the value of the variable define in `variable` attribute.

       If the related variable is the boolean typed variable, the default value is `true`
     - See the tutorial with a real world sample :doc:`when_not <../tutorial/properties>`)

   * - propertyerror

       `boolean` or `transitive`
     - If access to the variable is not possible due to a property
       (for example `disabled`) by default an error is returned.
       The overall coherence is not guaranteed.
       If the parameter is `false`, the calculated value is `false` in this condition.
       If the parameter is `transitive`, the calculated is `true` if the variable raise propertyerror
       or `false` otherwise.

       Default value: `true`
     - transitive

       false

   * - optional

       `boolean`
     - The variable in calculation may not exist. This generates an error. Overall coherence is not guaranteed.
       To avoid this set the optional parameter to `true`. In this case, if variable in calculation is not exists, the variable is always accessible.
     - true

   * - default

       `boolean`
     - If optional parameter is set to `true` and the variable in calculation is not exist, the variable is accessible.
       If you do not want this behavior, set this parameter to `false`.
     - false

   * - description

       `string`
     - Rougail engine create a description like "when the variable "xxxx" has the value "yyyy".
       You can personnalize here the calculation description
     -

Jinja parameters
~~~~~~~~~~~~~~~~

.. list-table::
   :header-rows: 1

   * - Parameter
     - Comment
     - Sample

   * - type

       `string`
     - The calculation type.

       This parameter is optional. It is deduced from the presence of the parameter "jinja" in calculation.
     - jinja

   * - jinja

       `string`

       `mandatory`
     - Jinja template. For a multiple variable, each line represents a value.

       It's better to use :term:`relative path` notation in Jinja template.
     - .. code-block:: jinja

         {% if _.my_variable %}
           {{ _.my_variable }}
         {% endif %}

   * - params

       `dict`
     - Additional parameters passed to the Jinja template

       See below to have params possibility.
     - See the tutorial with a real world sample :doc:`params <../tutorial/jinja>`)

   * - return_type

       `string`
     - Jinja template could return two type of value:

       - `string` (default): that means the Jinja template return an error message that explain why we don't have access to this variable
       - `boolean`: the Jinja template return "true" or "false". The value true means that the properties is present.

     - See the tutorial with a real world sample :doc:`return_type <../tutorial/jinja>`)

   * - description

       `string`
       `recommanded`
     - Rougail engine cannot deduce what you want to do in Jinja template. You have to describe it for documentation purpose.
       If return_type parameter is `boolean`, this description is used in error message.
     - See the tutorial with a real world sample :doc:`description <../tutorial/jinja>`)

In the case of a Jinja type calculation, it is possible to have parameters (`params`).

There are two types of parameter:

- the standard parameters (string, boolean, integer, null), in this case just do: "key: value"

- advanced settings:

   - parameter via a variable
   - parameter via information
   - parameter via an identifier: in the case of a variable in a :term:`dynamically built family`
   - parameter via an index: in the case of a variable in a :term:`sequence`
   - parameter via the current :term:`namespace`

Parameters for variable type `param`
''''''''''''''''''''''''''''''''''''

.. list-table::
   :header-rows: 1

   * - Parameter
     - Comments
     - Sample

   * - type

       `string`
     - Parameter's type
     - variable

   * - variable

       `string`

       `mandatory`
     - Variable's name

       It's better to use :term:`relative path` notation.
     - _.my_variable

   * - propertyerror

       `boolean`
     - If access to the variable is not possible due to a property (for example `disabled`) by default an error is returned. If the parameter is false, the parameter is not passed to the Jinja template.

       Default value: `true`
     - false

   * - optional

       `boolean`
     - The variable may not exist depending on YAML file imports. If the optional parameter is true, the parameter will simply be deleted if the variable does not exist.
       Default value: `false`
     - true

   * - whole

       `boolean`
     - In :term:`sequence` family, only the value of the variable in the current element is propose.
       This parameter allow you to have all values for all elements.

       Default value: `false`.
     - true

Parameters for information type `param`
'''''''''''''''''''''''''''''''''''''''

.. list-table::
   :header-rows: 1

   * - Parameter
     - Comments
     - Sample

   * - information

       `string`

       `mandatory`
     - Name of the information whose value we want to retrieve.
     - doc

   * - variable

       `string`
     - Variable's name. If not specified, the information is retrieve in :term:`Tiramisu` Config.

       It's better to use :term:`relative path` notation.
     - _.my_variable
