documentation + fallback on condition
This commit is contained in:
parent
0585ab0b11
commit
bd299e3d2b
@ -9,17 +9,8 @@ Rougail est un bibliothèque python3 qui permet de charger des dictionnaires (fi
|
||||
|
||||
## Les dictionnaires
|
||||
|
||||
Un dictionnaire est un fichier XML donc la structure est expliqué ci-dessous.
|
||||
|
||||
Un dictionnaire contient en ensemble de variable, utilisable à tout moment, notamment dans des templates.
|
||||
|
||||
Il est possible d'avoir plusieurs espace de nom pour classer les variables (appeler aussi "extra") mais il est aussi possible, à l'interieur de ce espace de nom de mettre des familles pour classer les variables.
|
||||
|
||||
Les familles et les variables peuvent être défini dans plusieurs dictionnaires. Ces dictionnaires s'aggrège alors. Il est possible de rajouter des familles des variables, des services, des éléments à un service et des contraintes.
|
||||
|
||||
Il est également possible de redéfinir des éléments pour changer les comportement d'une variable ou d'un service.
|
||||
|
||||
FIXME expliquer les noms des variables dans les extras
|
||||
- [Les dictionnaires](dictionary/rougail.md)
|
||||
- [Les dictionnaires extra](dictionary/extra.md)
|
||||
|
||||
### Les variables
|
||||
|
||||
@ -43,7 +34,3 @@ FIXME expliquer les noms des variables dans les extras
|
||||
## Les templates
|
||||
|
||||
- Type creole
|
||||
|
||||
|
||||
FIXME :
|
||||
- une variable avec nom unique sauf pour extra
|
||||
|
@ -38,6 +38,8 @@ Une fonction de vérification doit prendre en compte 2 aspects important :
|
||||
|
||||
À partir de maintenant seule None et des valeurs en minuscule seront autorisés.
|
||||
|
||||
Il est possible de définir des [paramètres](../param/README.md) à cette fonction.
|
||||
|
||||
## Vérification des valeurs avec avertissement
|
||||
|
||||
Dans la contrainte, il est possible de spécifier le niveau d'erreur et le mettre en avertissement :
|
||||
@ -49,5 +51,3 @@ Dans la contrainte, il est possible de spécifier le niveau d'erreur et le mettr
|
||||
```
|
||||
|
||||
Dans ce cas une valeur avec une majuscule sera accepté, mais un message d'avertissement apparaitra.
|
||||
|
||||
Il est possible de définir des [paramètres](../param/README.md) à cette fonction.
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Les conditions
|
||||
|
||||
## Un condition
|
||||
|
||||
Les conditions permettent d'ajouter ou de supprimer des propriétés à une [variable](../variable/README.md), une [famille](../family/README.md), un [fichier](../service/file.md), un [port](../service/port.md) ou une [ip](../service/ip.md) suivant le contexte.
|
||||
|
||||
Nous allons nous concentrer ici sur la condition hidden_if_in, mais [il existe d'autre conditions](conditions.md).
|
||||
@ -26,6 +28,8 @@ La [cible](../target/README.md) de la condition est ici "my_variable".
|
||||
|
||||
Donc ici la variable est caché à l'utilisateur si la variable "condition" est à True (le paramètre).
|
||||
|
||||
## Un condition avec plusieurs paramètres
|
||||
|
||||
Il est également possible de mettre plusieurs paramètre :
|
||||
|
||||
```
|
||||
@ -43,8 +47,30 @@ Il est également possible de mettre plusieurs paramètre :
|
||||
</constraints>
|
||||
```
|
||||
|
||||
FIXME
|
||||
<!ELEMENT condition ((target|param)+)>
|
||||
<!ATTLIST condition fallback (True|False) "False">
|
||||
<!ATTLIST condition force_condition_on_fallback (True|False) "False">
|
||||
<!ATTLIST condition force_inverse_condition_on_fallback (True|False) "False">
|
||||
## Une condition optionnelle
|
||||
|
||||
Il est possible de définir une condition avec une variable source qui n'existe pas dans toutes les contextes.
|
||||
|
||||
Dans ce cas, on met la condition en "optionnelle".
|
||||
|
||||
Si la variable source existe, la condition s'applique.
|
||||
|
||||
Si la variable source n'existe pas :
|
||||
|
||||
- si le nom fini en _if_in (par exemple hidden_if_in), l'action est forcée sans condition (les cibles sont hidden)
|
||||
- si le nom fini en _if_not_in (par exemple hidden_if_not_in), la condition est totalement ignorée
|
||||
|
||||
Ces deux comportements peuvent être changé à tout moment avec l'attribut "apply_on_fallback". Dans ce cas :
|
||||
|
||||
- si la valeur de "apply_on_fallback" est "True", l'action est forcée sans condition
|
||||
- si la valeur de "apply_on_fallback" est "False", la condition est totalement ignorée
|
||||
|
||||
Exemple :
|
||||
|
||||
```
|
||||
<condition name="hidden_if_in" source="condition" optional="True", apply_on_fallback="False">
|
||||
<param>yes</param>
|
||||
<param>maybe</param>
|
||||
<target>my_variable</target>
|
||||
</condition>
|
||||
```
|
||||
|
12
doc/dictionary/extra.md
Normal file
12
doc/dictionary/extra.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Les dictionnaires extra
|
||||
|
||||
Un extra est un espace de nom différent. L'idée et de pouvoir classer les variables par thématique.
|
||||
|
||||
Les espaces de nom extra doivent être déclaré au moment [de la configuration de Rougail](../dev/config.md).
|
||||
|
||||
Dans cet espace de nom :
|
||||
|
||||
- des variables et des familles peuvent avoir le même nom dans différentes familles
|
||||
- la valeur d'un cible, source, leader ou follower des contraintes doivent être avec un chemin complet
|
||||
- on ne peut pas déclarer des services dans cet espace de nom
|
||||
- dans un template il faut utiliser des chemins complet (%%my_extra.my_family.my_variable ou %%my_extra.my_family.leader.follower pour une variable suiveuse)
|
22
doc/dictionary/rougail.md
Normal file
22
doc/dictionary/rougail.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Les dictionnaires
|
||||
|
||||
## Un dictionnaire ?
|
||||
|
||||
Un dictionnaire est un fichier XML donc la structure est décrite dans cette documentation.
|
||||
|
||||
Un dictionnaire contient en ensemble de variable chargé dans Tiramisu, utilisable à tout moment, notamment dans des templates.
|
||||
|
||||
Les familles, les variables et les contraintes peuvent être défini dans plusieurs dictionnaires. Ces dictionnaires s'aggrège alors.
|
||||
|
||||
Il est également possible de redéfinir des éléments pour changer les comportement d'une variable ou d'un service.
|
||||
|
||||
## L'espace de nom par défaut
|
||||
|
||||
L'espace de nom par défaut s'appelle "rougail" ([ce nom est personnalisable](../dev/config.md)).
|
||||
|
||||
Cet espace de nom est un peu particulier :
|
||||
|
||||
- le nom des variables et des familles doivent être unique pour l'ensemble de cet espace (même si ces variables ou familles sont dans des familles différentes)
|
||||
- la valeur d'un cible, source, leader ou follower des contraintes peuvent être avec nom de la variable ou de la famille ou leurs chemins complet
|
||||
- on peut déclarer des services dans cet espace de nom
|
||||
- dans un template on peut utiliser cette variable sans le chemin complet (%%my_variable) ou avec (%%rougail.my_family.my_variable)
|
@ -112,9 +112,7 @@ Il est possible de définir une [condition](../condition/README.md) de type "dis
|
||||
</service>
|
||||
</services>
|
||||
<variables>
|
||||
<family name="general">
|
||||
<variable name="condition" type="boolean"/>
|
||||
</family>
|
||||
<variable name="condition" type="boolean"/>
|
||||
</variables>
|
||||
<constraints>
|
||||
<condition name="disabled_if_in" source="condition">
|
||||
|
@ -1,15 +1,72 @@
|
||||
# La gestion d'une IP
|
||||
|
||||
## La balise ip
|
||||
## La balise IP
|
||||
|
||||
La gestion des IP se fait dans un conteneur de [service](service.md).
|
||||
|
||||
FIXME
|
||||
La déclaration de l'attribut permet d'associer une IP autorisé à accéder au service.
|
||||
|
||||
<!ELEMENT ip (#PCDATA)>
|
||||
<!ATTLIST ip iplist CDATA #IMPLIED >
|
||||
<!ATTLIST ip ip_type (NetworkOption|variable) "NetworkOption">
|
||||
<!ATTLIST ip interface_type (UnicodeOption|variable) "UnicodeOption">
|
||||
<!ATTLIST ip interface CDATA #REQUIRED>
|
||||
<!ATTLIST ip netmask_type (NetmaskOption|variable) "NetmaskOption">
|
||||
<!ATTLIST ip netmask CDATA "255.255.255.255">
|
||||
Il est nécessaire, au minimum, de spécifier son adresse IP et l'interface :
|
||||
|
||||
```
|
||||
<ip interface="ens3">192.168.0.1</ip>
|
||||
```
|
||||
|
||||
L'IP peut être un variable :
|
||||
|
||||
```
|
||||
<ip interface="ens3" ip_type="variable">variable_ip</ip>
|
||||
```
|
||||
|
||||
## La gestion d'un réseau
|
||||
|
||||
L'adresse IP peut être un réseau :
|
||||
|
||||
```
|
||||
<ip interface="ens3" netmask="255.255.255.0">192.168.0.0</ip>
|
||||
```
|
||||
|
||||
Le masque de réseau peut être un variable :
|
||||
|
||||
```
|
||||
<ip interface="ens3" netmask_type="variable" netmask="variable_netmask" ip_type="variable">variable_ip</ip>
|
||||
```
|
||||
|
||||
## L'interface
|
||||
|
||||
Il est possible de spécifier le nom de l'interface si on la connait :
|
||||
|
||||
```
|
||||
<ip interface="ens3">192.168.0.1</ip>
|
||||
```
|
||||
|
||||
Mais il est possible de calculer automatiquement cette valeur :
|
||||
|
||||
```
|
||||
<ip interface="auto">192.168.0.1</ip>
|
||||
```
|
||||
|
||||
Dans ce cas l'interface est déduite à partir de la table de routage.
|
||||
|
||||
## Désactiver la génération d'une IP
|
||||
|
||||
Il est possible de définir une [condition](../condition/README.md) de type "disabled_if_in" ou "disabled_if_not_in" sur une balise IP :
|
||||
|
||||
```
|
||||
<services>
|
||||
<service name="test">
|
||||
<ip interface="ens3" iplist="test_ip">192.168.0.1</ip>
|
||||
</service>
|
||||
</services>
|
||||
<variables>
|
||||
<variable name="condition" type="boolean"/>
|
||||
</variables>
|
||||
<constraints>
|
||||
<condition name="disabled_if_in" source="condition">
|
||||
<param>False</param>
|
||||
<target type="iplist">test_ip</target>
|
||||
</condition>
|
||||
</constraints>
|
||||
```
|
||||
|
||||
Dans ce cas, tous les IP avec un attribut iplist à "test_ip" seront désactivé si la variable "condition" est False.
|
||||
|
@ -1,5 +1,5 @@
|
||||
# La cible
|
||||
|
||||
- [De type variable)](../target/variable.md)
|
||||
- [De type famille)](../target/family.md)
|
||||
- [De type variable](../target/variable.md)
|
||||
- [De type famille](../target/family.md)
|
||||
- [De type \*list](../target/list.md)
|
||||
|
@ -58,6 +58,30 @@ Il est possible d'en définit d'autres :
|
||||
</constraints>
|
||||
```
|
||||
|
||||
## Définition des variables meneuse et suiveuse dans un dictionnaire extra
|
||||
|
||||
Voici un exemple de définition d'une variable meneuse et de deux variables meneuses dans un espace de nom "example" :
|
||||
|
||||
```
|
||||
<variables>
|
||||
<family name="family">
|
||||
<variable name="leader" multi='True'/>
|
||||
<variable name="follower1"/>
|
||||
<variable name="follower2" multi='True'/>
|
||||
</family>
|
||||
</variables>
|
||||
<constraints>
|
||||
<group leader="example.family.leader">
|
||||
<follower>example.family.follower1</follower>
|
||||
<follower>example.family.follower2</follower>
|
||||
</group>
|
||||
</constraints>
|
||||
```
|
||||
|
||||
Le chemin de la variable meneuse est traditionnel, par contre le chemin des variables suiveuses n'est pas le chemin définitif de la variable.
|
||||
|
||||
Le chemin d'une variable suiveuse est normalement "example.family.leader.follower1" mais la variable n'est pas encore une variable suiveuse à ce moment là du traitement. C'est pour cela qu'il ne faut, uniquement dans les groupes, mettre le nom de la variable meneuse dans le chemin.
|
||||
|
||||
## Ajout d'une nouvelle variable suiveuse
|
||||
|
||||
Pour ajouter, dans un nouveau dictionnaire, une variable suiveuse à notre groupe, rien de plus simple, il suffit de redéfinir un groupe avec cette (ou ces) nouvelle variable :
|
||||
|
@ -219,4 +219,20 @@ Ces variables sont généralement des variables obligatoires. En effet ces varia
|
||||
|
||||
Une [variable meneuse ou suiveuse](leadership.md) ne peut pas avoir la propriété auto_freeze.
|
||||
|
||||
FIXME <!ATTLIST variable test CDATA #IMPLIED>
|
||||
## Information "test"
|
||||
|
||||
L'attribut "test" est un attribut spécial qui permet aux concepteurs d'un dictionnaire d'influancer le robot de test en précisant de valeurs utile à tester.
|
||||
|
||||
Concrêtement, le contenu de cet attribut est enregister dans une "information" de l'option Tiramisu correspondante.
|
||||
|
||||
Exemple :
|
||||
|
||||
```
|
||||
<variable name="my_variable" test="yes"/>
|
||||
```
|
||||
|
||||
Il est possible de préciser plusieurs valeurs avec le séparateur "|" :
|
||||
|
||||
```
|
||||
<variable name="my_variable" test="yes|no"/>
|
||||
```
|
||||
|
@ -52,7 +52,7 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
|
||||
self.target_is_uniq = False
|
||||
self.only_variable = False
|
||||
self.convert_target(self.objectspace.space.constraints.condition)
|
||||
self.check_condition_fallback()
|
||||
self.check_condition_optional()
|
||||
self.convert_condition_source()
|
||||
self.convert_param(self.objectspace.space.constraints.condition)
|
||||
self.check_source_target()
|
||||
@ -106,19 +106,18 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
|
||||
f'{condition.source.path}')
|
||||
raise DictConsistencyError(msg, 11, condition.xmlfiles)
|
||||
|
||||
def check_condition_fallback(self):
|
||||
"""a condition with a fallback **and** the source variable doesn't exist
|
||||
def check_condition_optional(self):
|
||||
"""a condition with a optional **and** the source variable doesn't exist
|
||||
"""
|
||||
remove_conditions = []
|
||||
for idx, condition in enumerate(self.objectspace.space.constraints.condition):
|
||||
# fallback
|
||||
if condition.fallback is False or \
|
||||
if condition.optional is False or \
|
||||
self.objectspace.paths.path_is_defined(condition.source):
|
||||
continue
|
||||
if condition.name in ['disabled_if_in', 'mandatory_if_in', 'hidden_if_in']:
|
||||
apply_action = not condition.force_condition_on_fallback
|
||||
if hasattr(condition, 'apply_on_fallback'):
|
||||
apply_action = condition.apply_on_fallback
|
||||
else:
|
||||
apply_action = condition.force_inverse_condition_on_fallback
|
||||
apply_on_fallback = condition.name.endswith('_if_in'):
|
||||
remove_conditions.append(idx)
|
||||
if apply_action:
|
||||
self.force_actions_to_variable(condition)
|
||||
|
@ -32,7 +32,7 @@ from ..utils import normalize_family
|
||||
from ..error import DictConsistencyError
|
||||
# a CreoleObjSpace's attribute has some annotations
|
||||
# that shall not be present in the exported (flatened) XML
|
||||
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
|
||||
ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace',
|
||||
'remove_condition', 'path', 'instance_mode', 'index',
|
||||
'level', 'remove_fill', 'xmlfiles', 'type', 'reflector_name',
|
||||
'reflector_object',)
|
||||
|
@ -197,15 +197,11 @@ class VariableAnnotator(Walk): # pylint: disable=R0903
|
||||
"""Convert variable tests value
|
||||
"""
|
||||
for variable in self.get_variables():
|
||||
self._convert_test(variable)
|
||||
|
||||
def _convert_test(self,
|
||||
variable,
|
||||
) -> None:
|
||||
if not hasattr(variable, 'information'):
|
||||
variable.information = self.objectspace.information(variable.xmlfiles)
|
||||
if hasattr(variable, 'test'):
|
||||
if not hasattr(variable, 'test'):
|
||||
continue
|
||||
if variable.test:
|
||||
if not hasattr(variable, 'information'):
|
||||
variable.information = self.objectspace.information(variable.xmlfiles)
|
||||
values = variable.test.split('|')
|
||||
new_values = []
|
||||
for value in values:
|
||||
@ -221,6 +217,8 @@ class VariableAnnotator(Walk): # pylint: disable=R0903
|
||||
"""Convert variable help
|
||||
"""
|
||||
for variable in self.get_variables():
|
||||
if not hasattr(variable, 'information'):
|
||||
variable.information = self.objectspace.information(variable.xmlfiles)
|
||||
self._convert_help(variable)
|
||||
|
||||
@staticmethod
|
||||
|
@ -121,9 +121,8 @@
|
||||
<!ELEMENT condition ((target|param)+)>
|
||||
<!ATTLIST condition name (disabled_if_in|disabled_if_not_in|hidden_if_in|hidden_if_not_in|mandatory_if_in|mandatory_if_not_in) #REQUIRED>
|
||||
<!ATTLIST condition source CDATA #REQUIRED>
|
||||
<!ATTLIST condition fallback (True|False) "False">
|
||||
<!ATTLIST condition force_condition_on_fallback (True|False) "False">
|
||||
<!ATTLIST condition force_inverse_condition_on_fallback (True|False) "False">
|
||||
<!ATTLIST condition optional (True|False) "False">
|
||||
<!ATTLIST condition apply_on_fallback (True|False) #IMPLIED>
|
||||
|
||||
<!ELEMENT param (#PCDATA)>
|
||||
<!ATTLIST param type (string|number|nil|boolean|variable|information|suffix) "string">
|
||||
|
@ -16,7 +16,7 @@
|
||||
</family>
|
||||
</variables>
|
||||
<constraints>
|
||||
<condition name="disabled_if_not_in" source="unknown" fallback="True">
|
||||
<condition name="disabled_if_not_in" source="unknown" optional="True">
|
||||
<param>no</param>
|
||||
<target type="variable">disable_variable</target>
|
||||
<target type="filelist">afilllist</target>
|
||||
|
@ -15,13 +15,13 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition name="disabled_if_not_in" source="unknown" force_inverse_condition_on_fallback="True" fallback="True">
|
||||
<condition name="disabled_if_not_in" source="unknown" apply_on_fallback="True" optional="True">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
<target type="variable">mode_conteneur_actif2</target>
|
||||
<target type="filelist">afilllist</target>
|
||||
</condition>
|
||||
<condition name="disabled_if_not_in" source="activer_client_ldap" fallback="True">
|
||||
<condition name="disabled_if_not_in" source="activer_client_ldap" optional="True">
|
||||
<param>non</param>
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
</condition>
|
||||
|
@ -20,7 +20,7 @@
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
<target type="variable">mode_conteneur_actif2</target>
|
||||
</condition>
|
||||
<condition name="disabled_if_in" source="activer_client_ldap" fallback="True">
|
||||
<condition name="disabled_if_in" source="activer_client_ldap" optional="True">
|
||||
<param>non</param>
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
</condition>
|
||||
|
@ -20,7 +20,7 @@
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
<target type="variable">mode_conteneur_actif2</target>
|
||||
</condition>
|
||||
<condition name="disabled_if_in" source="activer_client_ldap" fallback="True" force_condition_on_fallback="True">
|
||||
<condition name="disabled_if_in" source="activer_client_ldap" optional="True" apply_on_fallback="False">
|
||||
<param>non</param>
|
||||
<target type="variable">mode_conteneur_actif</target>
|
||||
</condition>
|
||||
|
@ -19,7 +19,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition name="disabled_if_in" source="activer_clam" fallback="True">
|
||||
<condition name="disabled_if_in" source="activer_clam" optional="True">
|
||||
<param>non</param>
|
||||
<target type="filelist">afilllist</target>
|
||||
</condition>
|
||||
|
@ -18,7 +18,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
|
@ -18,7 +18,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
|
@ -7,7 +7,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
|
@ -15,7 +15,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
|
@ -15,7 +15,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable" optional="True">mode_conteneur_actif2</target>
|
||||
</condition>
|
||||
|
@ -15,7 +15,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="hidden_if_in" source="condition">
|
||||
<condition optional="True" name="hidden_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
<target type="variable">mode_conteneur_actif1</target>
|
||||
</condition>
|
||||
|
@ -18,7 +18,7 @@
|
||||
</variables>
|
||||
|
||||
<constraints>
|
||||
<condition fallback="True" name="disabled_if_in" source="condition">
|
||||
<condition optional="True" name="disabled_if_in" source="condition">
|
||||
<param>oui</param>
|
||||
</condition>
|
||||
</constraints>
|
||||
|
@ -16,7 +16,7 @@
|
||||
</family>
|
||||
</variables>
|
||||
<constraints>
|
||||
<condition name="hidden_if_in" source="activer_clam" fallback="True">
|
||||
<condition name="hidden_if_in" source="activer_clam" optional="True">
|
||||
<param>non</param>
|
||||
<target type="filelist">afilllist</target>
|
||||
</condition>
|
||||
|
Loading…
Reference in New Issue
Block a user