#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
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
| Type | Valeur attendue | Porte une valeur |
|---|---|---|
text | chaîne courte | oui |
textarea | chaîne multiligne | oui |
richtext | chaîne de HTML | oui |
number | nombre libre | oui |
range | nombre borné | oui |
checkbox | booléen | oui |
select | une valeur d’une liste | oui |
radio | une valeur d’une liste | oui |
color | couleur hexadécimale | oui |
image | adresse d’image | oui |
url | adresse | oui |
header | — | non |
paragraph | — | non |
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înerequisL’un des treize ci-dessus. Un type inconnu est ignoré, jamais rejeté.
idchaînerequisLe 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îneLe nom lisible du réglage.
defaultLa valeur de départ. C’est la seule clé que le rendu lit vraiment, avec
id.
infochaîneUne 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îneLe 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.
{
"type": "text",
"id": "cta_label",
"label": "Bouton",
"default": "Nous contacter"
}{%- 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.
{
"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 :
<p>{{ section.settings.adresse | lignes }}</p>{%- 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.
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.
{
"type": "richtext",
"id": "presentation",
"label": "Présentation",
"default": "<p>Notre atelier travaille le bois depuis <strong>1998</strong>.</p>"
}<div class="prose">{{ section.settings.presentation }}</div>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.
{
"type": "number",
"id": "annee_creation",
"label": "Année de création",
"default": 1998
}<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.
{
"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
}minnombreBorne basse.
maxnombreBorne haute.
stepnombreLe pas. 10 ici : on ne peut choisir que 60, 70, 80…
unitchaîneL’unité affichée à côté du curseur — %, px. Elle ne fait pas partie de
la valeur : le réglage vaut 100, pas "100%".
:root {
--largeur: {{ settings.largeur }}px;
--densite: {{ settings.densite }};
}Un range sert aussi à borner une boucle :
{%- for article in articles limit: section.settings.nombre -%}#checkbox — un booléen
Afficher ou masquer. Huit occurrences dans les quatre thèmes.
{
"type": "checkbox",
"id": "mentions",
"label": "Afficher les mentions légales",
"default": true
}{%- if section.settings.mentions -%}
<a href="/legal/mentions-legales">Mentions légales</a>
<a href="/legal/confidentialite">Confidentialité</a>
{%- endif -%}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.
{
"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.
<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 :
--bouton-rayon: {% if settings.boutons == 'droit' %}4px{% else %}999px{% endif %};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.
{
"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.
{
"type": "color",
"id": "accent",
"label": "Accent",
"info": "Les boutons, les liens, les chiffres mis en avant.",
"default": "#4364df"
}:root {
--accent: {{ settings.accent }};
--accent-sombre: {{ settings.accent | teinte: -18 }};
--accent-clair: {{ settings.accent | teinte: 88 }};
}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.
{ "type": "image", "id": "image", "label": "Photographie de fond" }{%- if section.settings.image != blank -%}
<img src="{{ section.settings.image }}" alt="" loading="lazy">
{%- endif -%}Ou en image de fond, comme le bandeau d’origo :
<section class="hero"
{%- if section.settings.image != blank %} style="background-image:url({{ section.settings.image }})"{% endif -%}>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.
[
{ "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" }
]{%- 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.
[
{ "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.
{
"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.
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.
{
"sections": {
"nos-services": {
"type": "prestations",
"settings": { "titre": "Nos services", "colonnes": "2" }
}
},
"order": ["nos-services"]
}Dans config/settings_data.json, sous current.sections.<nom>.settings.
{
"current": {
"sections": {
"entete": { "settings": { "cta_label": "Nous contacter", "cta_href": "/contact" } }
}
}
}Dans config/settings_data.json, directement sous current.
{
"current": {
"accent": "#4364df",
"largeur": 1160
}
}Toute clé de current qui n’est pas sections devient un réglage global. Voir
Réglages globaux.

