#Liquid
Un thème Webcosa est écrit en Liquid, le langage de gabarit de Shopify. Cette section dit exactement ce que le moteur expose : quels objets un thème peut lire, quels filtres il peut appliquer, quels tags il peut écrire — et ce qui n’existe pas, pour que personne ne le cherche.
#Le moteur, en une phrase
Webcosa exécute LiquidJS, la même grammaire portée en JavaScript. Écrire notre propre interpréteur aurait coûté des semaines pour obtenir moins sûr et moins complet ; reprendre celui de Shopify n’était pas possible, il est en Ruby. LiquidJS suit la spécification de près, et la quasi-totalité de ce qu’on trouve dans un tutoriel Liquid fonctionne ici tel quel.
La conséquence pratique est agréable : la coloration syntaxique de ton éditeur,
les extensions Liquid, dix ans de réponses sur les forums — tout marche. La
conséquence désagréable est qu’un exemple trouvé en ligne parlera de product
et de cart, qui n’existent pas ici. Les quatre pages ci-dessous existent pour
que tu saches, sans essayer, ce qui répondra.
#Une surface fermée, et c’est un contrat
La liste des objets exposés est courte, et elle l’est exprès. Chaque nom
qu’on y ajoute est un nom qu’on ne peut plus renommer : le jour où un client a
un thème qui écrit {{ site.nom }}, site.nom doit continuer d’exister sous ce
nom, avec ce sens, aussi longtemps que ce thème est publié. Un objet exposé par
confort aujourd’hui est une dette pour toujours.
C’est pourquoi la règle est l’inverse de l’intuition : on n’expose rien tant qu’un thème réel n’en a pas besoin. Ajouter un objet est facile et se fait sans rien casser ; en retirer un casse tous les sites qui s’en servaient.
Le fichier qui fait foi est src/lib/liquid/contexte.ts. Il porte lui-même
cette phrase en tête : « Cette liste est un CONTRAT ». Si un objet n’y est pas,
il n’existe pas — quoi qu’en dise un exemple Shopify.
#Ce que rend une expression inconnue
Le moteur tourne avec strictVariables et strictFilters désactivés. Une
variable qui n’existe pas rend une chaîne vide ; un filtre qui n’existe pas
laisse la valeur intacte et passe son chemin. Rien n’échoue, rien ne s’affiche.
{{ produit.titre }} → (rien)
{{ site.non }} → (rien)
{{ 'Bonjour' | traduire }} → BonjourC’est le bon comportement en production — une faute de frappe dans un coin de pied de page ne doit pas éteindre la page entière — et c’est un piège pendant l’écriture. Quand un réglage « ne marche pas », la première hypothèse à tester est toujours la faute de frappe, pas le bug du moteur.
#Un exemple complet, tiré d’un thème réel
Voici la coquille du thème Origo, telle qu’elle est livrée. Elle tient en
quarante lignes et utilise déjà la moitié de ce que la référence décrit :
page, site, settings, les filtres asset_url, stylesheet_tag et
teinte, le tag section, et la variable content_for_layout.
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>{{ page.titre }} — {{ site.nom }}</title>
{{ 'theme.css' | asset_url | stylesheet_tag }}
<style>
:root {
--encre: {{ settings.encre }};
--accent: {{ settings.accent }};
--accent-sombre: {{ settings.accent | teinte: -18 }};
--accent-clair: {{ settings.accent | teinte: 88 }};
--bouton-rayon: {% if settings.boutons == 'droit' %}4px{% else %}999px{% endif %};
}
</style>
</head>
<body>
{% section 'annonce' %}
{% section 'entete' %}
<main id="contenu">{{ content_for_layout }}</main>
{% section 'pied' %}
</body>
</html>Deux choses méritent d’être remarquées tout de suite, parce qu’elles reviennent partout dans les quatre thèmes livrés.
Les réglages deviennent des variables CSS, ici et nulle part ailleurs. Aucune
section ne connaît une couleur : elles héritent toutes de :root. C’est ce qui
permet de retoucher tout un site depuis l’éditeur sans rouvrir une seule section.
teinte fabrique les nuances. Sans lui, --accent-clair et
--accent-sombre seraient deux réglages de plus dans le panneau. Vingt
sélecteurs de couleur, personne ne les remplit.
#Où le code s’exécute, et dans quelles bornes
Un thème s’exécute sur notre serveur, celui qui rend aussi les sites de tous les autres clients. Le moteur est donc borné : trois secondes par rendu, une limite de mémoire, six niveaux d’imbrication de sections, aucun accès au disque. Ces bornes ne se voient pas tant qu’on écrit un thème normal, et elles se voient brutalement dès qu’une boucle s’emballe.
Elles sont détaillées, chiffres à l’appui, dans le bac à sable. Une chose vaut d’être sue dès maintenant : une section qui échoue ne fait pas tomber la page, elle est remplacée par un commentaire HTML. Si un bloc a disparu du rendu sans explication, le code source de la page contient la raison.
<!-- section prestations : Le rendu du thème a pris trop de temps. -->
<!-- section absente : bandeau-promo -->
