Aller au contenu

#Les types de réglage

Un réglage est une entrée du tableau settings d’un schéma. Son type dit de quelle nature est la valeur, son id sous quel nom on la lit en Liquid, et son label comment on l’appelle. Webcosa en admet treize, les mêmes que Shopify, moins ceux qui n’auraient pas de sens sur un site vitrine.

Cette page les passe tous en revue, avec pour chacun sa déclaration complète et la façon de lire sa valeur.

#Avant tout : ce que le type fait, et ce qu’il ne fait pas

Attention

Le type n’a aucun effet au moment du rendu. section.settings.<id> rend exactement la valeur JSON enregistrée, quelle qu’elle soit. Déclarer "type": "number" ne convertit rien, ne valide rien et ne refuse rien : si le JSON porte la chaîne "douze", c’est "douze" que Liquid verra.

Le type est une déclaration d’intention. Il dit à qui écrit les valeurs — et au panneau de réglages, le jour où il existera — quelle forme la valeur doit prendre.

Aujourd’hui, les valeurs s’écrivent à la main : dans templates/*.json pour les sections d’une page, dans config/settings_data.json pour les réglages globaux et les sections de la coquille. On les édite dans l’éditeur de code du CMS, ou depuis sa machine avec le CLI. Il n’existe pas encore de panneau qui les affiche champ par champ.

Le seul effet mécanique d’un réglage est son default : les valeurs par défaut du schéma sont posées sous les valeurs enregistrées. Voir Le bloc schema.

#Les treize types

TypeValeur attenduePorte une valeur
textchaîne courteoui
textareachaîne multiligneoui
richtextchaîne de HTMLoui
numbernombre libreoui
rangenombre bornéoui
checkboxbooléenoui
selectune valeur d’une listeoui
radioune valeur d’une listeoui
colorcouleur hexadécimaleoui
imageadresse d’imageoui
urladresseoui
headernon
paragraphnon

Les deux derniers ne portent pas de valeur : ils structurent le panneau. Ils n’ont donc pas besoin d’id, et rien ne les lit en Liquid.

#Les clés communes

typechaînerequis

L’un des treize ci-dessus. Un type inconnu est ignoré, jamais rejeté.

idchaînerequis

Le nom sous lequel la valeur est lue : section.settings.<id>. Obligatoire pour tous les types sauf header et paragraph. En minuscules avec des tirets bas, par convention — c’est ce que font les quatre thèmes.

labelchaîne

Le nom lisible du réglage.

default

La valeur de départ. C’est la seule clé que le rendu lit vraiment, avec id.

infochaîne

Une phrase d’explication. Sous-utilisé, et c’est dommage : c’est la seule occasion de dire l’effet d’un réglage là où on le remplit.

placeholderchaîne

Le texte grisé d’un champ vide. Déclaré au format, admis à l’installation, et sans aucun effet au rendu — comme info, unit, min, max et step, il attend le panneau de réglages. À ne pas confondre avec default : un placeholder ne devient jamais une valeur.


#text — une chaîne courte

Le type le plus utilisé, et de loin : les quatre thèmes en déclarent plus de deux cent cinquante. Titres, surtitres, libellés de boutons, numéros de téléphone.

Déclarationjson
{
  "type": "text",
  "id": "cta_label",
  "label": "Bouton",
  "default": "Nous contacter"
}
Lectureliquid
{%- if section.settings.cta_label != blank -%}
  <a class="bouton" href="{{ section.settings.cta_href }}">
    {{ section.settings.cta_label }}
  </a>
{%- endif -%}

Le HTML n’est pas échappé automatiquement, ici comme partout dans Liquid. Pour du contenu saisi par le client dans un endroit sensible, passe par escape.

#textarea — une chaîne multiligne

Chapeaux, adresses postales, listes courtes. Cent occurrences dans les quatre thèmes.

Déclarationjson
{
  "type": "textarea",
  "id": "compris",
  "label": "Ce qui est compris",
  "info": "Une ligne par élément.",
  "default": "Déplacement\nDiagnostic\nGarantie 2 ans"
}

Les sauts de ligne sont conservés dans la valeur, mais le HTML les ignore. Deux façons de les rendre visibles :

Avec le filtre lignesliquid
<p>{{ section.settings.adresse | lignes }}</p>
Avec split, pour une vraie listeliquid
{%- assign lignes = bloc.settings.compris | split: '
' -%}
<ul class="liste-coches">
  {%- for ligne in lignes -%}<li>{{ ligne }}</li>{%- endfor -%}
</ul>

Le second est tiré de themes/origo/sections/tarifs.liquid. Le saut de ligne littéral dans le split: est volontaire — Liquid n’interprète pas \n dans une chaîne.

Astuce

lignes échappe le HTML avant de convertir les sauts de ligne en br. C’est le seul filtre maison qui échappe : il est fait pour du texte saisi par le client.

#richtext — du HTML mis en forme

Pour un paragraphe avec du gras, de l’italique et des liens. La valeur est une chaîne de HTML, insérée telle quelle.

Déclarationjson
{
  "type": "richtext",
  "id": "presentation",
  "label": "Présentation",
  "default": "<p>Notre atelier travaille le bois depuis <strong>1998</strong>.</p>"
}
Lectureliquid
<div class="prose">{{ section.settings.presentation }}</div>
Danger

Aucun des quatre thèmes d’origine n’utilise richtext, et rien n’assainit ce HTML. La valeur est écrite dans la page telle quelle, balise script comprise. C’est sans conséquence tant que le thème et ses valeurs viennent du propriétaire du site — il ne peut s’attaquer qu’à lui-même — mais c’est à savoir avant de l’exposer. Voir Le bac à sable.

#number — un nombre libre

Un entier ou un décimal sans borne. À réserver aux cas où une borne n’aurait pas de sens ; sinon, range est plus sûr.

Déclarationjson
{
  "type": "number",
  "id": "annee_creation",
  "label": "Année de création",
  "default": 1998
}
Lectureliquid
<p>{{ 'now' | date: '%Y' | minus: section.settings.annee_creation }} ans d'expérience</p>

Aucun des quatre thèmes ne l’utilise : ils préfèrent tous range, qui rend une valeur absurde impossible à saisir.

#range — un nombre borné

Le type des largeurs, des arrondis, des échelles, du nombre d’articles à afficher. Seize occurrences dans les quatre thèmes.

themes/origo/config/settings_schema.jsonjson
{
  "type": "range",
  "id": "densite",
  "label": "Espace entre les sections",
  "info": "Plus haut, le site respire ; plus bas, il tient sur moins d'écrans.",
  "min": 60,
  "max": 160,
  "step": 10,
  "unit": "%",
  "default": 100
}
minnombre

Borne basse.

maxnombre

Borne haute.

stepnombre

Le pas. 10 ici : on ne peut choisir que 60, 70, 80…

unitchaîne

L’unité affichée à côté du curseur — %, px. Elle ne fait pas partie de la valeur : le réglage vaut 100, pas "100%".

Lecture — l’unité s’écrit dans le CSSliquid
:root {
  --largeur: {{ settings.largeur }}px;
  --densite: {{ settings.densite }};
}

Un range sert aussi à borner une boucle :

liquid
{%- for article in articles limit: section.settings.nombre -%}

#checkbox — un booléen

Afficher ou masquer. Huit occurrences dans les quatre thèmes.

Déclarationjson
{
  "type": "checkbox",
  "id": "mentions",
  "label": "Afficher les mentions légales",
  "default": true
}
Lectureliquid
{%- if section.settings.mentions -%}
  <a href="/legal/mentions-legales">Mentions légales</a>
  <a href="/legal/confidentialite">Confidentialité</a>
{%- endif -%}
Attention

Pas de comparaison à true : {% if section.settings.mentions %} suffit. Et surtout, pas de comparaison à la chaîne "true" — la valeur JSON est un booléen, false == "false" est faux en Liquid, et la condition serait toujours vraie.

#select — une valeur parmi une liste

Le troisième type le plus utilisé : quarante-sept occurrences. Fond de section, nombre de colonnes, hauteur d’un bandeau, forme des boutons.

themes/origo/sections/prestations.liquidjson
{
  "type": "select",
  "id": "colonnes",
  "label": "Colonnes",
  "options": [
    { "value": "2", "label": "Deux" },
    { "value": "3", "label": "Trois" },
    { "value": "4", "label": "Quatre" }
  ],
  "default": "3"
}

Chaque option porte une value — ce que Liquid lira — et un label — ce qu’un humain lit. Les value sont des chaînes, même quand elles ressemblent à des nombres.

Lecture — la valeur devient une classeliquid
<div class="grille grille-{{ section.settings.colonnes | default: '3' }}">

C’est le motif des quatre thèmes : le select ne pilote pas une condition, il compose un nom de classe, et la feuille de style fait le reste. Un select à quatre valeurs vaut alors quatre règles CSS, pas quatre {% if %}.

Quand une condition est inévitable :

liquid
--bouton-rayon: {% if settings.boutons == 'droit' %}4px{% else %}999px{% endif %};
Astuce

Le | default: '3' protège du cas où la valeur n’a jamais été enregistrée et où le schéma n’a pas pu être lu. Sans lui, la classe serait grille- et la grille s’effondrerait sur une colonne.

#radio — une valeur parmi une liste, toutes visibles

Même contenu qu’un select, autre présentation : les options sont affichées côte à côte au lieu d’être repliées dans une liste. À préférer à deux ou trois options courtes.

Déclarationjson
{
  "type": "radio",
  "id": "position",
  "label": "Position du texte",
  "options": [
    { "value": "gauche", "label": "À gauche" },
    { "value": "centre", "label": "Au centre" }
  ],
  "default": "gauche"
}

La lecture est identique à celle d’un select. Aucun des quatre thèmes ne l’utilise : ils déclarent tout en select, y compris les choix à deux options.

#color — une couleur

Quinze occurrences, toutes dans les settings_schema.json : les couleurs sont des réglages globaux, jamais des réglages de section. C’est ce qui permet de changer l’accent d’un site d’un seul geste.

themes/origo/config/settings_schema.jsonjson
{
  "type": "color",
  "id": "accent",
  "label": "Accent",
  "info": "Les boutons, les liens, les chiffres mis en avant.",
  "default": "#4364df"
}
Lecture — dans la coquille, en variables CSSliquid
:root {
  --accent: {{ settings.accent }};
  --accent-sombre: {{ settings.accent | teinte: -18 }};
  --accent-clair: {{ settings.accent | teinte: 88 }};
}
Attention

Le filtre teinte n’accepte que la forme hexadécimale à six chiffres, avec ou sans #. rgb(…), oklch(…) ou un nom de couleur sont rendus tels quels, sans transformation ni erreur. Écris tes default en #rrggbb.

teinte: -18 assombrit de 18 %, teinte: 88 éclaircit de 88 %. Sans lui, chaque nuance devrait être un réglage de plus — et un panneau de vingt sélecteurs de couleur ne se remplit jamais.

#image — une image

La valeur est l'adresse d’une image de la bibliothèque du site, pas un fichier du thème. Six occurrences dans forge, vela et piazza.

themes/piazza/sections/bandeau.liquidjson
{ "type": "image", "id": "image", "label": "Photographie de fond" }
Lecture — toujours sous conditionliquid
{%- if section.settings.image != blank -%}
  <img src="{{ section.settings.image }}" alt="" loading="lazy">
{%- endif -%}

Ou en image de fond, comme le bandeau d’origo :

liquid
<section class="hero"
  {%- if section.settings.image != blank %} style="background-image:url({{ section.settings.image }})"{% endif -%}>
Attention

Le nom Webcosa est image, et les quatre thèmes livrés s’y tiennent.

Ils ne s’y sont pas toujours tenus : origo déclarait quinze de ses réglages d’image en image_picker, forge et vela un chacun — le nom Shopify, qui ne fait pas partie des treize types admis. Ces dix-sept déclarations rendaient correctement, puisqu’un type inconnu est ignoré et que la lecture ne dépend pas du type ; elles étaient simplement invisibles pour tout outil qui lit les schémas, à commencer par le panneau de réglages. Elles ont été renommées.

Les dimensions ne sont pas connues du thème : l’image vient de la bibliothèque du client. Le ratio se pose donc en CSS, jamais en attributs width/height — c’est ce que fait snippets/image.liquid d’origo.

#url — une adresse

Un lien interne (/contact), une ancre (#prestations) ou une adresse externe. Huit occurrences, dans forge et vela.

themes/forge/sections/bandeau.liquidjson
[
  { "type": "text", "id": "cta_label", "label": "Bouton principal", "default": "Demander un devis" },
  { "type": "url", "id": "cta_href", "label": "Lien", "default": "/contact" },
  { "type": "text", "id": "cta2_label", "label": "Bouton secondaire", "default": "Voir les réalisations" },
  { "type": "url", "id": "cta2_href", "label": "Lien", "default": "#realisations" }
]
Lectureliquid
{%- render 'bouton', label: section.settings.cta_label, href: section.settings.cta_href -%}

Rien ne valide la forme de l’adresse : c’est une chaîne comme une autre. origo déclare d’ailleurs les siennes en text, ce qui rend exactement la même chose. url dit l’intention, et c’est déjà utile à la relecture.

#header — un intertitre dans le panneau

Ne porte aucune valeur. Il coupe une longue liste de réglages en sections lisibles.

themes/forge/sections/bandeau.liquidjson
[
  { "type": "textarea", "id": "texte", "label": "Sous-titre" },
  { "type": "image", "id": "image", "label": "Image de fond" },
  { "type": "header", "id": "h_boutons", "label": "Boutons" },
  { "type": "text", "id": "cta_label", "label": "Bouton principal" },
  { "type": "url", "id": "cta_href", "label": "Lien" }
]

Rien à lire en Liquid : {{ section.settings.h_boutons }} rend du vide. L’id n’est pas requis — les trois thèmes qui l’utilisent en mettent un par habitude, ce qui ne coûte rien et évite deux entrées strictement identiques.

#paragraph — une note dans le panneau

Ne porte pas de valeur non plus. Sert à expliquer un parti pris à celui qui remplit les réglages. Son texte est dans content, et non dans label — c’est la convention Shopify, et c’est le seul type qui l’emploie.

themes/vela/sections/temoignage.liquidjson
{
  "type": "paragraph",
  "content": "Un seul témoignage, en grand. Trois avis alignés se lisent comme un argumentaire ; un seul se lit comme une phrase."
}

C’est le bon endroit pour justifier une contrainte : pourquoi la section n’accepte qu’un seul bloc, pourquoi le texte doit rester court, ce que le réglage d’à côté va casser si on le pousse.


#Un type inconnu est ignoré, pas rejeté

Le format n’échoue jamais sur un type qu’il ne connaît pas. Un thème écrit pour une version plus récente de Webcosa — ou importé depuis Shopify, avec ses image_picker, font_picker, product_list — continue de rendre sa page.

Le raisonnement est le même que pour les sections en échec : refuser tout un thème pour un réglage inconnu casserait un site en ligne pour un détail d’éditeur. Le réglage est simplement sans effet.

Note

Conséquence pratique : une faute de frappe dans un type est totalement muette au rendu. "type": "chekbox" se comporte exactement comme "checkbox" : le default s’applique, la valeur écrite dans le template remonte, la page rend juste. Le chemin de rendu ne lit que id et default — le type n’y est consulté nulle part.

Rien ne signalera donc l’erreur : ni le rendu, ni l’installation, ni le CLI. Ce qui cassera, c’est le panneau de réglages le jour où il existera, et tout outil qui lit les schémas. Le seul repère est la relecture du schéma.

#Où les valeurs sont écrites

Dans templates/<gabarit>.json, sous l’instance de la section.

json
{
  "sections": {
    "nos-services": {
      "type": "prestations",
      "settings": { "titre": "Nos services", "colonnes": "2" }
    }
  },
  "order": ["nos-services"]
}

Toute clé de current qui n’est pas sections devient un réglage global. Voir Réglages globaux.

#Pages voisines