Skip to content

Schéma et présentation des préférences ​

Voir préférences au runtime pour lire les valeurs. Le schéma décrit le formulaire du streamer ; il ne contient pas ses réglages enregistrés.

Source et compilation ​

Écris preferences.config.js, avec module.exports = { ... }. Le DEV HUB compile le JavaScript en config/preferences.config.json via transpile ou watch, puis synchronise les configurations du brouillon. Le backend valide le schéma. Le JSON compilé est régénéré : ne le corrige pas à la main.

L'objet suivant est un schéma complet. Dans le fichier JS, préfixe-le par module.exports =. Il est aussi du JSON valide, sans commentaires ni virgules finales.

json
{
  "type": "group",
  "appearance": { "wrap": "tabs" },
  "groupItems": {
    "theme": {
      "type": "group",
      "label": { "fr": "Apparence", "en": "Appearance" },
      "groupItems": {
        "color": {
          "type": "color",
          "label": { "fr": "Couleur", "en": "Color" },
          "default": "#9146FF"
        }
      }
    }
  }
}

La racine explicite type: 'group' permet d'utiliser appearance. La forme courte { theme: {...}, autreChamp: {...} } est aussi acceptée et devient un groupe racine. Les clés de champs ne doivent pas contenir de point. Réserve les clés techniques injectées par la plateforme (_version, _uuid, _index, _deleted, _isScalarCollection).

Un champ déclare type. Un groupe exige groupItems (objet de champs nommés), une collection exige collectionItems (une définition d'élément). Les types déterminent les options et la forme de la valeur.

Propriétés communes ​

PropriétéUsage
label, tooltipTexte simple ou objet localisé { fr, en }.
requiredChamp obligatoire ; généralement faux par défaut, vrai pour choice et multipleChoice. Certains types imposent leurs propres règles.
default, defaultsValeur initiale générale / par langue, selon les règles des défauts.
wuOptionsOptions propres au type ; ne pas y placer les propriétés communes.
hideIf, disableIf, requiredIfExpressions de formulaire.
conditionalLabelLibellé construit à partir de valeurs ; remplace label lorsqu'il est défini.
appearancePrésentation, décrite ci-dessous.
migrationConversion depuis la version publiée précédente ; contrat dédié.

flag est une option avancée des champs compatibles avec les arguments de lancement ; elle ne remplace pas le schéma d'arguments d'un trigger. Voir modes de lancement.

Présentation ​

Clé de appearanceValeurs / effet
wraplist ou tabs pour un groupe ou une collection.
tabsStyleunderline ou pills pour un groupe en onglets. Sans option : underline à la racine, pills dans les groupes imbriqués.
choicesStylecards ou select pour multipleChoice à choix statiques. Les cartes sont ignorées avec avertissement pour des choix dynamiques.
foldedDémarrer replié pour les groupes et éléments de collection affichés en liste.
hiddenMasquer dans le formulaire ; ce n'est pas une donnée secrète ni une suppression de valeur.
handleAfficher la poignée de pli/tri.
lineBreak, lineBreakTextSéparateur avant le champ, avec texte facultatif.
color, formAnciennes options dépréciées et ignorées ; ne plus les ajouter.

Libellés dynamiques ​

Dans un libellé, @self désigne la valeur du champ ; sur un groupe, @self.title désigne son enfant. @parent.title vise le groupe ancêtre selon les règles des chemins.

  • @self.mode->toString affiche le libellé du choix, alors que @self.mode rend sa clé.
  • @self.title->editable propose une édition rapide d'un champ string ou number.
  • ->get(clé) descend d'un niveau : index d'une collection (->get(0)) ou clé d'un groupe (->get(name)). Les appels s'enchaînent : @self.animals->get(0)->get(name).
  • Un groupe ou une collection est toujours rendu sous forme de texte. Pour une collection, ce texte est son nombre d'éléments non supprimés : @self.animals->toString affiche 2, et un switch sur ce chemin peut traiter "0", "1" puis _default.
  • Une expression ternaire peut traiter une valeur vide ; exemple ci-dessous.
  • conditionalLabel accepte, par langue, une liste de textes et de blocs { if: expression, then, else } ou { switch: chemin, case: { valeur: texte, _default: texte } }. Les blocs peuvent être imbriqués : une valeur de then, else ou d'un case peut elle-même être une liste de textes et de blocs. Les morceaux sont concaténés sans séparateur.
text
{{@self.title==?Sans titre:@self.title->toString}}

Exemple d'élément de groupe, à placer dans collectionItems :

json
{
  "type": "group",
  "conditionalLabel": {
    "fr": [
      { "if": ["@self.enabled", "==", true], "then": "Actif — ", "else": "Inactif — " },
      "@self.title->editable"
    ],
    "en": [
      { "if": ["@self.enabled", "==", true], "then": "Enabled — ", "else": "Disabled — " },
      "@self.title->editable"
    ]
  },
  "groupItems": {
    "enabled": { "type": "boolean", "default": true },
    "title": { "type": "string", "default": "Titre" }
  }
}

Libellé qui choisit selon un mode, puis selon le nombre d'éléments d'une collection, et lit un élément précis :

json
{
  "type": "group",
  "conditionalLabel": {
    "fr": [
      {
        "switch": "@self.mode",
        "case": {
          "single": "Un seul animal",
          "list": [
            {
              "switch": "@self.animals->toString",
              "case": {
                "0": "Aucun animal",
                "1": "Animal : @self.animals->get(0)->get(name)",
                "_default": "@self.animals->toString animaux, dont @self.animals->get(0)->get(name)"
              }
            }
          ],
          "_default": "@self.mode->toString"
        }
      }
    ]
  },
  "groupItems": {
    "mode": {
      "type": "choice",
      "default": "list",
      "wuOptions": { "choices": { "single": "Un animal", "list": "Liste d'animaux" } }
    },
    "animals": {
      "type": "collection",
      "collectionItems": {
        "type": "group",
        "groupItems": { "name": { "type": "string", "default": "Chat" } }
      },
      "default": [{ "name": "Chat" }]
    }
  }
}

Réutiliser un modèle ​

Pour du code source JS, réutilise les modules du bootstrap (par exemple modules/Model.js) selon leurs exports réels. Le format de préférences possède aussi ses propres modèles déclaratifs :

json
{
  "textModel": {
    "isModel": true,
    "type": "group",
    "groupItems": {
      "title": { "type": "string", "default": "Titre" },
      "size": { "type": "number", "default": 24 }
    }
  },
  "header": {
    "useModel": "textModel",
    "groupItems": {
      "title": { "label": { "fr": "Titre principal", "en": "Main title" } }
    }
  }
}

isModel: true retire la définition du formulaire. useModel fusionne le modèle avec les propriétés locales, prioritaires. Les objets sont fusionnés récursivement ; hideIf est remplacé en bloc. Un modèle peut en réutiliser un autre, mais garde des dépendances simples et sans cycle. Le résultat ci-dessus contient header.title et header.size, pas textModel.