.. _family:

The families
=============

Synopsis
---------

.. glossary::

   family
   subfamily
   
       A family (or a subfamily) is simply a collection of variables that refer to
       the same business model category. It's just a variables container.
       Think of it as a container as well as a namespace.

.. attention:: A family without a subfamily or subvariable will be automatically deleted.

Naming
---------

It is with its name that we will be able to interact with the family.

.. seealso:: 

   A family is a variable. So have a look at the :ref:`variable naming convention <namingconvention>`.

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

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

   * - Parameter
     - Comments

   * - **description**, **_description**

       `string`
     - Description of the family.

       User information to understand the usefulness of the family.

       .. seealso:: tutorial with a real world sample :doc:`description parameter <../tutorial/family>`

   * - **help**, **_help**

       `string`
     - Additional help associated with the family.

       .. seealso:: tutorial with a real world sample :doc:`help parameter <../tutorial/document>` (the tutorial focuses on variable, but the principle is the same for a family)

   * - **mode**, **_mode**

       `string`
     - Family mode.

       The mode is a way of classifying the importance, the level of expertise required, or the access rights to a family.

       This parameter allows you to define the family mode, and also the default mode for variables or families included in this family.

       .. attention:: Mode is not configured by default. You have to define mode level before use this parameter.

       **Default value**: The default mode of a family is the smallest mode of the parent families, child variables, or child families that are contained in that family.

       .. seealso:: tutorial with a real world sample :doc:`mode parameter <../tutorial/modes>` (the tutorial focuses on variable, but the principle is the same for a family)

   * - **type**, **_type**

       `string`
     - possible values:

       - `family` (**default value**)
       - `dynamic`
       - `sequence`

   * - **hidden**, **_hidden**

       `boolean` or :term:`calculation`
     - Invisible family.

       Enables us to *hide* a family as well as the variables or families included in this family.

       This means that the family will no longer be visible in `read-write` mode, but only for calculations or in `read-only` mode.

       **Default value**: `false`

       .. seealso:: tutorial with a real world sample :doc:`hidden parameter <../tutorial/properties>`

   * - **disabled**, **_disabled**

       `boolean` or :term:`calculation`
     - Disabled family.

       Allows us to *deactivate* a family as well as the variables or families included in this family.

       This means that the family will no longer be visible to the user but also to a :term:`calculation`.

       **Default value**: `false`

       .. seealso:: tutorial with a real world sample :doc:`disabled parameter <../tutorial/properties>`

   * - **dynamic**, **_dynamic**

       :term:`calculation` or a list of :term:`calculation` or `string`
     - Dynamic identifiers.

       .. important:: This parameter is only available for dynamically built family. See the explanations about this below.

   * - **redefine**

       `boolean`
     - It is possible to define a family in one :term:`structure file` and change its behavior in a second :term:`structure file`. In this case you must explicitly redefine the family.

       **Default value**: `false`

   * - **exists**

       `boolean`
     - This parameter does two things:

         - creates a family if it does not exist in another :term:`structure file` (otherwise do nothing), in this case the value of the parameter must be `true`
         - in conjunction with the `redefine` parameter set to `true`, only modifies the behavior if it is pre-existing, in which case the parameter's value must be `false`.

       **Default value**: `null`


.. note::

   If a subfamily or a subvariable already has the name of a parameter it is possible to use the "_<parameter>" name.
   You can have a look at the tutorial with a real world sample :doc:`of parameter with "_" <../tutorial/underscore_parameter>`.

Short-hand declaration
----------------------------

Short-hand declaration is a way to declare a family in a single line.

To create a family, just add a key with it's name and variables as values:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1
    my_family:

      my_variable:
    ...

By default, the description of the family is the family name.
It's a best practice to description a family. Just add comment in same line of name, this comment is use as description:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1
    my_family:  # This is a great family

      my_variable:
    ...

But in short-hand notation, you can only define family name and description.

.. attention:: Any other parameters will be considered as a variable. Do not use short-hand in this case.

A family
---------

Here is a simple example:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1
    my_family:
      description: This is a great family
      help: This family is great because we have great variables inside

      my_variable:
    ...

.. seealso::

   You can have a look at the tutorial with a real world sample:

   - :doc:`family <../tutorial/family>`
   - :doc:`help parameter <../tutorial/document>` (the tutorial focuses on variable, but the principle is the same for a family)

A dynamically built family
-----------------------------

To create a :term:`dynamically built family`, you must create a fictitious family linked to a list of uniq identifiers.
This list could be hard coded or resulting from a calculation.

The name of this family is particular. You have to add `{{ identifier }}` string inside. It will be replace by each identifiers.

Here is an simple example:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1
    
    my_{{ identifier }}_family:
      description: 'A family for {{ identifier }}'
      dynamic:
        - one thing
        - another

      variable:
        description: 'A variable for {{ identifier }}'
    ...

This will dynamically create two families:

- "my_one_thing_family"
- "my_another_family"

.. seealso::

   You can have a look at the tutorial with a real world sample :doc:`dynamically built family <../tutorial/dynamic>`

.. _sequence_family:

Sequence of homogeneous elements
---------------------------------------

A family with `type` set to `sequence` is a sequence of homogeneous elements.

Let's start the explanation with a concrete example:

.. code-block:: yaml

   %YAML 1.2
   ---
   version: 1.1

   accounts:
     description: All accounts
     type: sequence

     login:
       description: Account login
       type: unix_user

     secret:
       description: Account secret
       type: secret
   ...

What is expected, it's something like:

.. code-block:: yaml

    ---
    accounts:
      - login: foo
        secret: 0hM%G0dW4a7ASecr3t
      - login: bar
        secret: NotGoodSecret

It's what we call a Sequence of homogeneous elements.

.. attention:: A sequence cannot contain other families.

.. seealso::

   You can have a look at the tutorial with a real world sample :doc:`Sequence of homogeneous elements <../tutorial/sequence>`

A custom type family
----------------------

In short, a custom type is nothing more than a kind of a template for a family.
Define a custom type family is much like defining families.

This custom type family can be used as many times as desired and customized as you wish.

.. seealso::

   You can have a look at the tutorial with a real world sample :doc:`family custom type <../tutorial/family>`
