#Les templates
Un template est un fichier JSON de templates/ qui compose une page : quelles
sections, avec quels réglages, dans quel ordre. Il ne contient pas une ligne
de HTML — le balisage est dans les sections, le template ne fait que les
assembler.
C’est la séparation qui permet à un client de réorganiser sa page d’accueil sans ouvrir un fichier Liquid, et à un thème de servir sept gabarits avec les mêmes trente-cinq sections.
#La forme
{
"sections": {
"hero": {
"type": "hero",
"settings": { "titre": "Un travail soigné, tenu dans les délais" },
"blocks": {
"b1": { "type": "argument", "settings": { "texte": "Devis gratuit" } },
"b2": { "type": "argument", "settings": { "texte": "Intervention sous 48 h" } }
},
"block_order": ["b1", "b2"]
},
"prestations": {
"type": "prestations",
"settings": { "colonnes": "3", "fond": "voile" }
}
},
"order": ["hero", "prestations"]
}Deux clés à la racine, et c’est tout.
sectionsobjetrequisLes instances de section, indexées par un identifiant libre. La clé n’est pas le type : c’est ce qui permet de poser deux fois la même section sur une page, avec des réglages différents.
ordertableauL’ordre d’affichage, par identifiant. Facultatif : sans lui, on prend
l’ordre des clés de sections. C’est ce que fait Shopify pour les templates
écrits à la main, et cela évite qu’un template parfaitement valable soit
refusé pour une clé manquante.
#Ce qu’une instance peut porter
typechaînerequisLe nom du fichier de section, sans sections/ ni .liquid. "type": "prestations" fait chercher sections/prestations.liquid.
settingsobjetLes valeurs des réglages, par id. Elles recouvrent les default du schéma
de la section.
blocksobjetLes blocs, indexés par identifiant. Voir Les blocs.
block_ordertableauL’ordre des blocs. Fait foi quand il existe.
disabledbooléendéfaut : falsetrue retire la section du rendu sans la supprimer du fichier. Le contenu est
conservé, la section n’apparaît plus.
Une clé de sections absente d’order n’est pas rendue, et une entrée
d’order qui ne correspond à aucune section est ignorée en silence. Les deux
sont utiles — la première pour mettre une section de côté, la seconde pour
supprimer une section sans nettoyer l’ordre — et les deux font disparaître du
contenu sans un mot. C’est le premier endroit à regarder quand une section
« n’apparaît pas ».
#L’ordre de résolution — trois niveaux
Une page du CMS demande un gabarit. Le moteur cherche, dans cet ordre :
templates/<nom>.json
Le gabarit dédié. Une page « Contact » avec
templates/contact.jsonobtient exactement la composition prévue pour elle.templates/page.json
Le gabarit générique des pages libres. C’est le maillon qui compte, et il est expliqué ci-dessous.
templates/index.json
Le dernier recours. Il est requis dans tout thème, donc ce niveau répond toujours — sauf si son JSON est cassé.
Si aucun des trois ne répond, la page rend une chaîne vide et l’erreur
Aucun template pour « <nom> ».
Ces trois niveaux valent pour les pages du CMS. Le blog a ses deux gabarits à lui, sans repli : voir Le blog.
#Ce que page.json répare
Sans templates/page.json, une page « Tarifs » sans gabarit dédié retombait
sur index.json — c’est-à-dire affichait la page d’accueil entière,
bandeau, prestations et avis compris, sous un autre titre. Chaque page
nouvelle était donc un doublon de l’accueil : ce que Google sanctionne, et ce
qu’aucun client ne comprend.
D’où la forme d’un page.json : une tête neutre et un corps vide, prêts à
recevoir du contenu.
{
"sections": {
"tete": {
"type": "hero-sobre",
"settings": { "surtitre": "", "titre": "", "texte": "" }
},
"corps": {
"type": "texte",
"settings": {},
"blocks": {
"b1": {
"type": "paragraphe",
"settings": {
"texte": "Cette page attend son contenu. Ajoutez-y les sections que vous voulez depuis l'éditeur, ou demandez à Cosa de la rédiger pour vous."
}
}
},
"block_order": ["b1"]
}
},
"order": ["tete", "corps"]
}Les titres sont volontairement vides : la section hero-sobre masque ce
qui est blank, la page affiche donc une tête sobre sans texte parasite, et
non « Un travail soigné, tenu dans les délais » sur la page « Mentions
légales ».
Écris page.json en premier, avant même index.json. C’est lui qui décide de
ce à quoi ressemble une page dont personne ne s’est occupé — et il y en aura
toujours.
#Les gabarits des thèmes d’origine
| Thème | Templates |
|---|---|
aplomb | index, page, contact, a-propos, prestations, tarifs, realisations |
cadence | index, page, contact, a-propos, prestations, tarifs, planning |
epure | index |
forge | index, page, contact, a-propos |
origo | index, page, contact, a-propos, prestations, tarifs, realisations |
piazza | index, page, contact, a-propos |
scene | index, page, contact, a-propos, prestations, tarifs, realisations |
vela | index, page, contact, a-propos |
Aucun ne déclare encore blog ni article : leurs blogs sont rendus par la
plateforme. Voir Le blog.
Sept d’entre eux déclarent au minimum index, page, contact et
a-propos : ce sont les pages qu’un site vitrine a toujours. origo,
aplomb, cadence et scene vont plus loin parce qu’ils visent tous les
métiers ; epure n’a que son index, sur lequel toutes ses pages
retombent — c’est exactement le doublon d’accueil décrit plus haut, une
dette de ce thème et non un modèle à copier.
{
"sections": {
"tete": {
"type": "hero-sobre",
"settings": {
"surtitre": "Écrivez-nous",
"titre": "Nous contacter",
"texte": "On vous répond sous 48 h, toujours par une personne."
}
},
"contact": { "type": "contact", "settings": { "surtitre": "", "titre": "", "texte": "" } },
"acces": {
"type": "acces",
"settings": { "fond": "voile" },
"blocks": {
"b1": { "type": "info", "settings": { "intitule": "Adresse", "detail": "12 rue de l'Exemple\n69000 Lyon" } },
"b2": { "type": "info", "settings": { "intitule": "Téléphone", "detail": "04 00 00 00 00" } }
},
"block_order": ["b1", "b2"]
}
},
"order": ["tete", "contact", "acces"]
}Deux choses à noter. La section contact reçoit des titres vides parce
que la tête les a déjà écrits : deux « Nous contacter » à la suite, c’est ce
qu’on obtient quand on laisse les défauts partout. Et "detail" contient
\n — dans un fichier JSON, l’échappement standard fonctionne ; c’est dans
une chaîne Liquid qu’il ne fonctionnerait pas.
#La même section, deux fois sur une page
C’est tout l’intérêt d’indexer par identifiant plutôt que par type :
{
"sections": {
"services-particuliers": {
"type": "prestations",
"settings": { "titre": "Pour les particuliers", "colonnes": "2" }
},
"services-pros": {
"type": "prestations",
"settings": { "titre": "Pour les professionnels", "colonnes": "3", "fond": "voile" }
}
},
"order": ["services-particuliers", "services-pros"]
}Chaque instance reçoit son propre section.id, ce qui permet à la section de
fabriquer des ancres uniques.
#Le blog : blog.json et article.json
Le blog d’un site — /blog, /blog/<blog>, /blog/<blog>/<article> — n’est
pas une page du CMS : les articles s’écrivent dans le CMS, et c’est la
plateforme qui les sert. Par défaut, elle les sert dans sa propre page :
sobre, aux couleurs du site, mais sans l’en-tête, le menu, le pied ni les
polices de ton thème. Sur un thème fait sur mesure, le blog a alors l’air d’un
autre site, et le visiteur n’a plus de menu pour revenir.
Un thème qui veut habiller son blog déclare l’un des deux gabarits, ou les deux, comme chez Shopify. La page est alors rendue comme toutes les autres : la coquille, ses sections d’en-tête et de pied, puis les sections du gabarit.
templates/article.jsontemplates/blog.jsonLes listes. /blog/<blog> montre les articles d’un blog ; /blog montre
directement les articles quand le site n’a qu’un blog (ou aucun), et le
sommaire des blogs quand il en a plusieurs. Les trois passent par ce
gabarit, avec l’objet blog. Le sommaire se reconnaît à
page.adresse == '/blog' avec blog.blogs.size > 1.
Les deux sont indépendants : un thème qui ne déclare que article.json habille
ses articles, et ses listes restent celles de la plateforme.
Aucun repli. C’est le fichier qui décide, et lui seul : sans
templates/article.json, l’article est rendu par la plateforme — jamais par
page.json ni par index.json, qui ne savent pas afficher un texte
d’article. Un fichier présent mais illisible (JSON cassé, clé sections
absente) a le même effet : la plateforme reprend la main, plutôt que de servir
une page vide comme le ferait une page ordinaire.
{
"sections": {
"article": { "type": "article" },
"suite": { "type": "a-lire-aussi", "settings": { "nombre": 3 } }
},
"order": ["article", "suite"]
}<article class="article">
<a class="retour" href="{{ article.blog.adresse }}">← {{ article.blog.titre }}</a>
<h1>{{ article.titre }}</h1>
{%- if article.date != blank -%}
<time datetime="{{ article.date }}">{{ article.date | date_fr }}</time>
{%- endif -%}
{%- if article.image != blank -%}
<img src="{{ article.image }}" alt="" width="1600" height="900">
{%- endif -%}
<div class="article-corps">{{ article.contenu }}</div>
</article>Le <h1> est à toi : le corps de l’article commence à <h2>. Et
article.contenu est du HTML déjà rendu — pose-le tel quel, sans escape, et
mets-le en forme dans ta feuille de style : la plateforme n’y ajoute aucun
style.
Ce que la plateforme garde, quel que soit le gabarit : la porte d’un site
protégé, la 404 d’un blog ou d’un article inconnu, les brouillons (seuls les
articles publiés sont servis), et les métadonnées — titre, description,
canonique, fil d’Ariane et BlogPosting. Ta coquille n’a pas à les reposer.
Voir La coquille.
#Ce qui n’est pas dans un template
L’en-tête, le pied, la barre d’annonce. Ils apparaissent sur toutes les
pages, donc c’est la coquille qui les pose avec {% section %}, et leurs
valeurs vivent dans config/settings_data.json sous current.sections. Voir
La coquille.
Les réglages globaux. Couleurs, largeur, typographie : ils valent pour le thème entier. Voir Réglages globaux.
#Ce qui se passe quand le JSON est cassé
lireTemplate rend null, et la page rend une chaîne vide avec l’erreur
Aucun template pour « <nom> ». La coquille n’est même pas rendue.
C’est le seul fichier du thème dont une erreur produit une page vide, et
non un simple commentaire HTML. Un .json est vérifié à l’écriture par l’API
— JSON invalide : <message de l'analyseur> — donc l’accident vient rarement
de l’éditeur du CMS. Il vient d’un import, ou d’un fichier écrit hors ligne et
poussé par le CLI.
Un template dont le JSON est valide mais auquel il manque la clé sections
est traité de la même façon : null, page vide. La clé order, elle, est
facultative.
#Le rendu, dans l’ordre
Les instances sont sélectionnées
orderest parcouru, chaque identifiant est cherché danssections. Les absents sont écartés, lesdisabledaussi.Les blocs sont ordonnés
Pour chaque instance,
block_order— ou l’ordre des clés — donne le tableausection.blocks.Les sections sont rendues en parallèle
Chacune avec son propre
section, et le contexte complet du site. Une section ne voit ni les autres, ni ce qu’elles ont produit.Les HTML sont concaténés, puis la coquille est rendue
Les résultats sont joints par un saut de ligne, et cette chaîne devient
content_for_layout.

