Aller au contenu

#La coquille

layout/theme.liquid est le HTML qui entoure toutes les pages du site : le doctype, la balise head, l’en-tête, le pied, et le trou dans lequel le contenu de la page vient tomber. C’est le seul fichier de layout/ que le moteur connaisse, et l’un des trois sans lesquels un thème ne rend rien.

Cette page le dissèque à partir de themes/origo/layout/theme.liquid, qui tient en quarante-quatre lignes et fait tout ce qu’une coquille doit faire.

#Le fichier entier

themes/origo/layout/theme.liquidliquid
<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ page.titre }} — {{ site.nom }}</title>
    {{ 'theme.css' | asset_url | stylesheet_tag }}

    <style>
      :root {
        --encre: {{ settings.encre }};
        --papier: {{ settings.papier }};
        --accent: {{ settings.accent }};
        --accent-sombre: {{ settings.accent | teinte: -18 }};
        --accent-clair: {{ settings.accent | teinte: 88 }};
        --largeur: {{ settings.largeur }}px;
        --arrondi: {{ settings.arrondi }}px;
        --bouton-rayon: {% if settings.boutons == 'droit' %}4px{% else %}999px{% endif %};
      }
    </style>
  </head>
  <body>
    <a class="saut" href="#contenu">Aller au contenu</a>

    {% section 'annonce' %}
    {% section 'entete' %}

    <main id="contenu">{{ content_for_layout }}</main>

    {% section 'pied' %}
  </body>
</html>
Note

L’original porte en plus un {%- comment -%} qui explique le bloc de variables CSS, et trois réglages de typographie. Ils sont retirés ici pour la lisibilité, pas parce qu’ils poseraient problème.

#{{ content_for_layout }} — le seul point obligatoire

Le moteur rend d’abord toutes les sections du template, concatène leur HTML, puis rend la coquille avec cette chaîne dans content_for_layout. C’est la mécanique de Shopify, et elle a l’avantage de laisser la coquille décider où le contenu tombe et ce qui l’entoure.

Une coquille sans {{ content_for_layout }} rend une page sans contenu. Sans erreur, sans avertissement : l’en-tête et le pied s’affichent, le milieu est vide. Si une page paraît « ne rien afficher », c’est la première ligne à chercher.

Attention

content_for_header n’existe pas dans Webcosa. Chez Shopify, il injecte les balises de la plateforme dans le head. Ici il n’y a rien à injecter, et la variable n’est pas définie : elle rendra une chaîne vide, silencieusement, puisque le moteur tourne avec strictVariables désactivé. Ne le copie pas depuis un thème Shopify en croyant qu’il fait quelque chose.

#Le head

#Le titre

liquid
<title>{{ page.titre }} — {{ site.nom }}</title>

page.titre est le titre de la page courante, site.nom celui de l’entreprise. Les quatre thèmes d’origine utilisent exactement cette forme. Voir Objets.

#La feuille de style

liquid
{{ 'theme.css' | asset_url | stylesheet_tag }}

Deux filtres à la suite. asset_url transforme un nom de fichier en adresse servie, stylesheet_tag l’enveloppe dans une balise link. Le résultat, pour un thème d’identifiant abc… :

HTML renduhtml
<link rel="stylesheet" href="/theme-assets/abc123.../theme.css">
Danger

asset_url prend le nom seul, jamais le chemin. L’adresse produite est /theme-assets/<id-du-thème>/<nom> — un seul segment de nom — et c’est la route qui remet le préfixe assets/ pour interroger la base.

Écrire {{ 'assets/theme.css' | asset_url }} fabrique une adresse à deux segments qui ne correspond à aucune route. La feuille de style répond 404, et la page rend quand même : du HTML nu, mais du HTML. Un site sans CSS ressemble à un thème mal écrit, pas à une adresse fausse — c’est pour ça que le défaut a tenu longtemps, sur tous les sites à la fois.

Voir Assets pour le détail de la route et de son cache, et Filtres pour les autres filtres maison.

#Les réglages posés en variables CSS

C’est la technique des quatre thèmes, et elle mérite d’être copiée : les réglages globaux deviennent des variables CSS sur :root, ici et nulle part ailleurs.

liquid
<style>
  :root {
    --encre: {{ settings.encre }};
    --accent: {{ settings.accent }};
    --accent-sombre: {{ settings.accent | teinte: -18 }};
    --largeur: {{ settings.largeur }}px;
  }
</style>

Aucune section n’a alors besoin de connaître une couleur : elles héritent toutes de :root, et la feuille de style dans assets/ reste un fichier CSS ordinaire, sans une ligne de Liquid.

Le filtre teinte évite de multiplier les réglages : teinte: -18 assombrit de 18 %, teinte: 88 éclaircit de 88 %. Sans lui, chaque nuance d’une couleur réglable devrait être un réglage de plus, et un panneau de vingt sélecteurs de couleur ne se remplit jamais.

Astuce

Les unités s’écrivent hors de l’expression : {{ settings.largeur }}px et non {{ settings.largeur | append: 'px' }}. Le réglage reste un nombre, donc comparable et utilisable dans un {% if %}, et le CSS reste lisible.

Une condition Liquid peut aussi produire directement une valeur CSS :

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

C’est ce que fait origo pour la forme des boutons, la police des titres et la casse des surtitres. Un select dans le schéma, une variable CSS dans la coquille, et toute la feuille de style suit.

#Le body

#Le lien d’évitement

liquid
<a class="saut" href="#contenu">Aller au contenu</a>

Premier élément focalisable de la page, visuellement masqué jusqu’à ce qu’il reçoive le focus. Les quatre thèmes le posent, et l’ancre #contenu correspond au <main id="contenu"> plus bas. Ce n’est pas une exigence du format, c’est une exigence d’accessibilité — et il coûte une ligne.

#{% section %} — l’en-tête et le pied

liquid
{% section 'annonce' %}
{% section 'entete' %}

<main id="contenu">{{ content_for_layout }}</main>

{% section 'pied' %}

Le tag {% section 'nom' %} rend sections/nom.liquid depuis la coquille, c’est-à-dire hors de tout template. Sans lui, il faudrait écrire l’en-tête et le pied en dur ici, donc les sortir de l’éditeur et du schéma : le client ne pourrait plus changer son numéro de téléphone sans toucher au code.

Ce que la section reçoit :

section.idchaîne

Le nom passé au tag. {% section 'entete' %} donne entete.

section.typechaîne

Le même nom. Pour une section de coquille, id et type sont identiques — il n’y a qu’une instance par nom.

section.settingsobjet

Les valeurs lues dans config/settings_data.json, sous current.sections.<nom>.settings, par-dessus les default du schéma de la section.

section.blockstableau

Les blocs lus sous current.sections.<nom>.blocks, ou un tableau vide.

Attention

Pour une section de coquille, blocks est passé tel quel : ce doit donc être un tableau d’objets { "type": …, "settings": … } dans settings_data.json, et non l’objet indexé par identifiant qu’utilisent les templates. C’est la seule asymétrie du format, et elle n’est écrite nulle part ailleurs. Voir Les blocs.

Une section absente ne casse rien : le tag rend un commentaire HTML <!-- section absente : nom -->. Une section qui lève une erreur rend <!-- section nom : message -->. Et l’imbrication est bornée à six niveaux, compteur hors de portée du thème — détails dans Le bac à sable.

#Ce que la coquille voit, et ce qu’elle ne voit pas

La coquille est rendue avec le contexte complet : site, page, settings, menu, articles, annee, theme_base, plus content_for_layout.

Elle ne voit pas section — il n’y a pas de section en cours à ce niveau. {{ section.settings.titre }} dans la coquille rend du vide.

Note

Un {% schema %} dans layout/theme.liquid casse la page : schema n’est pas un tag reconnu, et le fichier est rendu tel quel, sans que le bloc ne soit retiré comme il l’est pour les sections. L’erreur remontée est tag "schema" not found. La coquille n’a pas de réglages propres — ceux dont elle a besoin sont les réglages globaux.

#Une coquille minimale qui fonctionne

Pour démarrer, ou pour isoler un problème :

layout/theme.liquidliquid
<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ page.titre }} — {{ site.nom }}</title>
    {{ 'theme.css' | asset_url | stylesheet_tag }}
  </head>
  <body>
    {{ content_for_layout }}
  </body>
</html>

#Les erreurs qui se voient le moins

content_for_layout oublié

La page s’affiche, l’en-tête et le pied aussi, et le contenu n’est nulle part. Aucune erreur.

asset_url avec le chemin complet

Le site rend en HTML nu. La page fonctionne, elle est juste sans style. À vérifier dans l’onglet réseau : un 404 sur /theme-assets/…/assets/theme.css.

Une variable mal orthographiée

{{ settings.acent }} rend une chaîne vide. Le moteur tourne avec strictVariables désactivé, exprès : une faute de frappe dans un coin de pied de page ne doit pas éteindre la page entière. Traître en développement, salutaire en production.

Une section de coquille absente du thème

{% section 'annonce' %} sans sections/annonce.liquid rend un commentaire HTML. Invisible à l’écran, lisible dans le code source de la page.

#Pages voisines