Liste d’attente

Documentation · Premium

Thèmes en code

Donne à ton site exactement l’allure que tu veux : templates Liquid et feuilles de style, sans JavaScript, avec des réglages et des sections que tu retrouves dans l’éditeur visuel de Stellr.

Principe

Un thème en code décide du rendu de ton site : la mise en page, le HTML de chaque section, les feuilles de style. Le contenu (textes, images, ordre des sections) reste celui que tu édites dans « Mon site » : changer de thème ne fait rien perdre, et l’IA continue de remplir le site.

Un thème s’écrit en Liquid (le langage de templates de Shopify) et en CSS. Il n’a jamais de JavaScript : les quelques interactions utiles (copier l’adresse, onglets) sont fournies par Stellr. Le HTML produit passe par une liste blanche, et la page est servie sous une politique de sécurité stricte : un thème ne peut ni exécuter de script, ni charger quoi que ce soit hors de Stellr.

  • Réservé aux serveurs Premium.
  • Le thème est rendu côté serveur à chaque visite (avec un cache), puis mis en cache par le CDN.
  • Si le thème a une erreur, le site s’affiche avec le rendu Stellr : un thème cassé ne met jamais ton site hors ligne.
  • Tout s’enregistre en brouillon ; le bouton « Publier » met le site et le thème en ligne ensemble.

Fichiers d’un thème

FichierRôle
layout/theme.liquidObligatoire. L’enveloppe de toutes les pages (menu, pied de page) ; doit afficher {{ content_for_layout }}.
templates/index.liquidObligatoire. L’accueil : il parcourt les sections du site.
templates/boutique.liquidLa boutique (/boutique). Facultatif : sans ce template, la page garde le rendu complet de Stellr (menu et pied de page compris), aux couleurs de « Style ».
templates/voter.liquidLa page de vote (/voter), même règle.
templates/produit, compte, merciNoms réservés aux pages à venir : la page d’achat, le compte du joueur et le remerciement gardent le rendu Stellr.
sections/<nom>.liquidLe rendu d’un type de section (sections/hero.liquid pour la bannière), ou une section propre au thème.
snippets/<nom>.liquidDes fragments réutilisables, insérés avec {% render %}.
assets/<nom>.cssLes feuilles de style, chargées sur toutes les pages, dans l’ordre alphabétique.
config/settings_schema.jsonLes réglages du thème, affichés dans « Mon site → Style ».

Noms en lettres minuscules, chiffres et tirets. Au plus 100 fichiers, 256 Ko par fichier et 2 Mo au total.

Liquid en bref

{{ … }} affiche une valeur ; {% … %} exécute une balise (condition, boucle…). Les valeurs affichées sont échappées automatiquement : un texte saisi dans l’éditeur ne peut jamais injecter de HTML.

{% if server.online %}
  <p class="en-ligne">{{ server.players_label }}</p>
{% else %}
  <p>{{ server.status_label }}</p>
{% endif %}

{% for item in section.items %}
  <h3>{{ item.title | upcase }}</h3>
{% endfor %}

Balises disponibles : if, unless, case, for, break, continue, cycle, tablerow, assign, capture, increment, decrement, comment, raw, render, include, liquid, echo (avec elsif, else et when), plus schema pour les sections du thème. Les filtres standard de Liquid sont disponibles (upcase, date, default, size, split, slice…), ainsi que ceux de Stellr ci-dessous. Un filtre inconnu est une erreur.

Filtre de StellrRôle
iconIcône vectorielle de Stellr : {{ 'sword' | icon: 24 | raw }}
rawSortie sans échappement (HTML voulu, toujours filtré par la liste blanche)

Icônes disponibles pour icon : sword, shield, star, users, trophy, gem, map, bolt, heart, pickaxe, coin, crown, flame, leaf, rocket, castle, chat, copy, check, play, cart, vote, plus.

Un thème ne lit que ses propres fichiers : pas de disque, pas de réseau, pas d’autre serveur. Un rendu trop long (boucles imbriquées) ou trop lourd est arrêté.

Layout et pages

Le layout entoure chaque page. Il reprend généralement les classes de Stellr (stellr.root_class, stellr.root_style) pour garder les couleurs et les polices choisies dans « Style ».

layout/theme.liquid
<div class="{{ stellr.root_class }}" style="{{ stellr.root_style }}">
  <header class="sb-nav">
    <a href="{{ pages.home }}">{{ site.name }}</a>
    {%- if site.shop %}<a href="{{ pages.shop }}">Boutique</a>{% endif -%}
  </header>
  <main>{{ content_for_layout }}</main>
</div>

L’accueil parcourt les sections dans l’ordre choisi dans « Mon site ». Chaque section indique le fichier qui la rend (section.template) :

templates/index.liquid
{% for section in sections %}
  {% render section.template, section: section %}
{% endfor %}

Donne à chaque section l’identifiant de son bloc (id="{{ section.id }}") : les liens d’ancre marchent, et un clic sur la section dans l’aperçu de l’éditeur l’ouvre directement.

Un texte affiché tel quel dans son propre élément (<h2>{{ section.title }}</h2>) se modifie directement dans l’aperçu de l’éditeur. Transformé par un filtre (upcase, truncate) ou mêlé à d’autres éléments, il reste modifiable dans le formulaire.

Boutique : templates/boutique.liquid parcourt shop.sections (catégories non vides, puis les produits sans catégorie), chacune en grille ou en grades comparés (layout : grid ou tiers). Chaque produit a son prix (amount_label, period_label), ses avantages et sa page d’achat (buy_url) ; le paiement reste géré par Stellr. Quand la boutique n’est pas encore ouverte aux achats (shop.available faux), affiche le produit sans lien d’achat. page.cancelled signale le retour d’un paiement annulé.

templates/boutique.liquid
<h1>Boutique</h1>
{% for category in shop.sections %}
  <h2>{{ category.name }}</h2>
  {% for product in category.products %}
    <h3>{{ product.name }}</h3>
    <p>{{ product.amount_label }} {{ product.period_label }}</p>
    {% if shop.available %}<a href="{{ product.buy_url }}">Acheter</a>{% endif %}
  {% endfor %}
{% endfor %}

Votes : templates/voter.liquid affiche les sites de vote (votes.sites) et le classement du mois demandé (votes.ranking, 50 premiers sur cette page), avec les liens vers les mois voisins (previous_url, next_url, nil aux bornes). Les liens de vote peuvent s’ouvrir dans un nouvel onglet (target="_blank").

Le thème de départ contient les deux pages, au même rendu que Stellr : pars de lui pour les adapter.

Données disponibles

Toutes les pages reçoivent les mêmes données, en lecture seule. Aucune donnée personnelle de joueur n’y figure : les pages sont mises en cache pour tous les visiteurs.

  • site Le site du serveur
    • site.name Nom du serveur
    • site.title Titre de la page (référencement)
    • site.description Description (référencement)
    • site.url Adresse du site
    • site.shop Boutique ouverte (vrai ou faux)
    • site.votes Sites de vote déclarés (vrai ou faux)
    • site.logo Logo, ou nil
      • site.logo.url Adresse de l’image (médiathèque)
      • site.logo.width Largeur en pixels
      • site.logo.height Hauteur en pixels
  • server Le serveur de jeu, en direct
    • server.known Statut connu (plugin ou ping relié)
    • server.online En ligne (vrai ou faux)
    • server.players Joueurs en ligne, ou nil
    • server.max_players Places, ou nil
    • server.status_label « En ligne », « Hors ligne » ou « Statut indisponible »
    • server.players_label « 42 joueurs en ligne », ou nil
  • stellr Rendu Stellr, pour réutiliser sa feuille de style
    • stellr.root_class Classes de la racine du site (sb-site…)
    • stellr.root_style Variables CSS des couleurs et des polices, pour style=""
    • stellr.style Style choisi dans « Apparence » (buttons, nav, dividers, texture, headings)
    • stellr.colors Couleurs choisies dans « Apparence » (background, surface, primary, accent…)
  • settings Réglages du thème (config/settings_schema.json)
  • page Page rendue
    • page.handle index, boutique ou voter
    • page.cancelled boutique : retour d’un paiement annulé (aucun montant débité)
  • pages Adresses des pages de Stellr
    • pages.home Accueil
    • pages.shop Boutique
    • pages.vote Voter
    • pages.account Mon compte
  • sectionsliste Blocs du document, dans l’ordre
  • shop Boutique, sur toutes les pages
    • shop.available Boutique ouverte aux achats
    • shop.url Adresse de la boutique
    • shop.productsliste Produits visibles
      • shop.products[].id Identifiant du produit
      • shop.products[].category_id Catégorie, ou nil
      • shop.products[].name Nom
      • shop.products[].description Description
      • shop.products[].tagline Accroche courte
      • shop.products[].featured Mis en avant
      • shop.products[].badge Pastille (« Populaire »…), ou nil
      • shop.products[].perksliste Avantages
        • shop.products[].perks[].text Avantage
        • shop.products[].perks[].tag NEW, IMPROVED ou nil
      • shop.products[].includes_id Produit inclus (grade inférieur), ou nil
      • shop.products[].includes_name Nom du produit inclus, ou nil : « Tous les avantages de … »
      • shop.products[].image_url Image, ou nil
      • shop.products[].price_cents Prix en centimes
      • shop.products[].price_label Prix affiché : « 4,99 € / mois »
      • shop.products[].amount_label Montant seul : « 4,99 € »
      • shop.products[].period_label Période d’un abonnement : « / mois », ou nil
      • shop.products[].billing_interval Abonnement : WEEK, MONTH, QUARTER, YEAR, ou nil (achat unique)
      • shop.products[].buy_url Page d’achat du produit
    • shop.categoriesliste Catégories, avec leurs produits
      • shop.categories[].id Identifiant
      • shop.categories[].name Nom
      • shop.categories[].description Description
      • shop.categories[].layout grid ou tiers
      • shop.categories[].productsliste Produits de la catégorie
        • shop.categories[].products[].id Identifiant du produit
        • shop.categories[].products[].category_id Catégorie, ou nil
        • shop.categories[].products[].name Nom
        • shop.categories[].products[].description Description
        • shop.categories[].products[].tagline Accroche courte
        • shop.categories[].products[].featured Mis en avant
        • shop.categories[].products[].badge Pastille (« Populaire »…), ou nil
        • shop.categories[].products[].perksliste Avantages
          • shop.categories[].products[].perks[].text Avantage
          • shop.categories[].products[].perks[].tag NEW, IMPROVED ou nil
        • shop.categories[].products[].includes_id Produit inclus (grade inférieur), ou nil
        • shop.categories[].products[].includes_name Nom du produit inclus, ou nil : « Tous les avantages de … »
        • shop.categories[].products[].image_url Image, ou nil
        • shop.categories[].products[].price_cents Prix en centimes
        • shop.categories[].products[].price_label Prix affiché : « 4,99 € / mois »
        • shop.categories[].products[].amount_label Montant seul : « 4,99 € »
        • shop.categories[].products[].period_label Période d’un abonnement : « / mois », ou nil
        • shop.categories[].products[].billing_interval Abonnement : WEEK, MONTH, QUARTER, YEAR, ou nil (achat unique)
        • shop.categories[].products[].buy_url Page d’achat du produit
    • shop.sectionsliste Sections de la page boutique : catégories non vides, puis les produits sans catégorie
      • shop.sections[].id Identifiant (autres : produits sans catégorie)
      • shop.sections[].name Titre : nom de la catégorie, « Autres produits » ou « Boutique »
      • shop.sections[].description Description
      • shop.sections[].layout grid ou tiers (grades comparés côte à côte)
      • shop.sections[].productsliste Produits de la section
        • shop.sections[].products[].id Identifiant du produit
        • shop.sections[].products[].category_id Catégorie, ou nil
        • shop.sections[].products[].name Nom
        • shop.sections[].products[].description Description
        • shop.sections[].products[].tagline Accroche courte
        • shop.sections[].products[].featured Mis en avant
        • shop.sections[].products[].badge Pastille (« Populaire »…), ou nil
        • shop.sections[].products[].perksliste Avantages
          • shop.sections[].products[].perks[].text Avantage
          • shop.sections[].products[].perks[].tag NEW, IMPROVED ou nil
        • shop.sections[].products[].includes_id Produit inclus (grade inférieur), ou nil
        • shop.sections[].products[].includes_name Nom du produit inclus, ou nil : « Tous les avantages de … »
        • shop.sections[].products[].image_url Image, ou nil
        • shop.sections[].products[].price_cents Prix en centimes
        • shop.sections[].products[].price_label Prix affiché : « 4,99 € / mois »
        • shop.sections[].products[].amount_label Montant seul : « 4,99 € »
        • shop.sections[].products[].period_label Période d’un abonnement : « / mois », ou nil
        • shop.sections[].products[].billing_interval Abonnement : WEEK, MONTH, QUARTER, YEAR, ou nil (achat unique)
        • shop.sections[].products[].buy_url Page d’achat du produit
        • shop.sections[].products[].tier Grades comparés : palier « 01 », « 02 »…, sinon nil
  • votes Votes, sur toutes les pages
    • votes.url Page de vote
    • votes.sitesliste Sites de vote
      • votes.sites[].name Nom du site
      • votes.sites[].url Lien pour voter
    • votes.ranking Classement du mois (10 premiers, 50 sur la page voter), ou nil
      • votes.ranking.month Mois (AAAA-MM)
      • votes.ranking.month_label « octobre 2026 »
      • votes.ranking.total_votes Votes du mois
      • votes.ranking.is_current Mois en cours (le classement repart à zéro chaque mois)
      • votes.ranking.previous_url voter : mois précédent, ou nil (premier mois avec des votes)
      • votes.ranking.next_url voter : mois suivant, ou nil (mois en cours)
      • votes.ranking.entriesliste Joueurs
        • votes.ranking.entries[].rank Rang
        • votes.ranking.entries[].player Pseudo
        • votes.ranking.entries[].votes Votes
  • section Section rendue (dans sections/*.liquid)
    • section.id Identifiant du bloc, à mettre en id de la section (ancre)
    • section.type Type du bloc : hero, features, status, cta, discord, join, faq, stats, ou theme (section du thème)
    • section.section theme : nom du fichier de la section (sections/<nom>.liquid)
    • section.settings theme : réglages de la section, déclarés par son {% schema %}
    • section.template Fichier de la section : {% render section.template, section: section %}
    • section.tone Fond de la section : base ou alt
    • section.divider Séparateur avant la section, ou nil
      • section.divider.style wave, pixel ou slant
      • section.divider.to Fond de destination
    • section.layout Mise en page choisie (selon le type)
    • section.eyebrow Surtitre
    • section.title Titre
    • section.subtitle Sous-titre
    • section.text Texte (cta, discord)
    • section.highlight hero : passage du titre mis en couleur
    • section.title_before hero : titre avant le passage en couleur
    • section.title_highlight hero : passage en couleur, ou nil
    • section.title_after hero : titre après le passage en couleur
    • section.serverAddress hero, join : adresse du serveur
    • section.address_in_actions hero : afficher l’adresse avec les boutons
    • section.cta hero : bouton principal, ou nil
      • section.cta.label Texte du bouton
      • section.cta.href Adresse du lien
    • section.secondaryCta hero : bouton secondaire, ou nil
      • section.secondaryCta.label Texte du bouton
      • section.secondaryCta.href Adresse du lien
    • section.button cta : bouton
      • section.button.label Texte du bouton
      • section.button.href Adresse du lien
    • section.showOnline hero, stats : afficher les joueurs en ligne
    • section.showLogo hero : afficher le logo en grand
    • section.showPlayerCount status : afficher le nombre de joueurs
    • section.background hero : stars, gradient ou plain
    • section.background_class hero : image, plain, stars ou gradient
    • section.background_image hero : image de fond, ou nil
      • section.background_image.url Adresse de l’image (médiathèque)
      • section.background_image.width Largeur en pixels
      • section.background_image.height Hauteur en pixels
    • section.illustration hero : illustration à côté du texte, ou nil
      • section.illustration.url Adresse de l’image (médiathèque)
      • section.illustration.width Largeur en pixels
      • section.illustration.height Hauteur en pixels
    • section.inviteUrl discord : lien d’invitation
    • section.serverName join : nom du serveur dans Minecraft
    • section.version join : version de Minecraft
    • section.itemsliste features : cartes ; faq : questions ; stats : chiffres
      • section.items[].icon features : nom d’icône, pour le filtre icon
      • section.items[].title features : titre
      • section.items[].text features : texte
      • section.items[].image features : image, ou nil
        • section.items[].image.url Adresse de l’image (médiathèque)
        • section.items[].image.width Largeur en pixels
        • section.items[].image.height Hauteur en pixels
      • section.items[].number features : numéro sur deux chiffres (01, 02…)
      • section.items[].question faq : question
      • section.items[].answer faq : réponse
      • section.items[].value stats : chiffre
      • section.items[].label stats : libellé
    • section.platformsliste join : plateformes (Java, Bedrock, consoles)
      • section.platforms[].id java, bedrock ou consoles
      • section.platforms[].label Nom de la plateforme
      • section.platforms[].detail Appareils concernés
      • section.platforms[].address Adresse à saisir
      • section.platforms[].port Port, ou nil
      • section.platforms[].steps Étapes pour rejoindre (textes)
  • content_for_layout Contenu de la page (dans layout/theme.liquid)

Réglages du thème

config/settings_schema.json décrit les réglages que le propriétaire voit dans « Mon site → Style ». Leurs valeurs sont dans settings : {{ settings.accent }}, ou dans le CSS.

config/settings_schema.json
[
  {
    "name": "Couleurs",
    "settings": [
      { "type": "color", "id": "accent", "label": "Couleur d'accent", "default": "#ff8a3d" },
      { "type": "checkbox", "id": "ombres", "label": "Ombres sous les titres", "default": false },
      { "type": "range", "id": "espacement", "label": "Espace entre les sections", "min": 32, "max": 160, "unit": "px", "default": 88 },
      { "type": "select", "id": "menu", "label": "Menu", "options": [{ "value": "haut", "label": "En haut" }, { "value": "cote", "label": "Sur le côté" }], "default": "haut" },
      { "type": "image", "id": "fond", "label": "Image de fond" }
    ]
  }
]
TypeValeurPrécisions
texttexte500 caractères au plus
textareatexte2000 caractères au plus
color#rrggbbsélecteur de couleur
checkboxvrai ou faux
selectune des optionsoptions obligatoire : { "value", "label" }
rangenombremin et max obligatoires, step et unit facultatifs
imageimage de la médiathèquedans le thème : url, width, height, ou nil

Chaque réglage a un id (lettres minuscules, chiffres et _), un label, et peut avoir un default et une aide info.

Sections propres au thème

Un fichier de sections/ qui déclare un bloc {% schema %} devient une section que le propriétaire peut ajouter, ordonner et régler dans « Mon site → Sections », comme celles de Stellr. Ses valeurs sont dans section.settings.

sections/compte-a-rebours.liquid
{% schema %}
{
  "name": "Compte à rebours",
  "settings": [
    { "type": "text", "id": "titre", "label": "Titre", "default": "Nouvelle saison" },
    { "type": "text", "id": "date", "label": "Date (AAAA-MM-JJ)" },
    { "type": "checkbox", "id": "en_ligne", "label": "Seulement quand le serveur est en ligne" }
  ]
}
{% endschema %}
{%- unless section.settings.en_ligne and server.online != true -%}
<section class="sb-block sb-tone--{{ section.tone }}" id="{{ section.id }}">
  <div class="sb-container">
    <h2>{{ section.settings.titre }}</h2>
    <p>Le {{ section.settings.date | date: "%d/%m/%Y" }}</p>
  </div>
</section>
{%- endunless -%}
  • Le schéma prend les mêmes types de réglages que settings_schema.json, avec un name obligatoire.
  • Le premier {% schema %} du fichier est lu, même dans un commentaire : n’écris pas cette balise dans un commentaire.
  • Si tu renommes ou supprimes le fichier, la section n’est plus affichée (le reste du site l’est) et l’éditeur le signale.

Interactions fournies par Stellr

Sans JavaScript dans le thème, deux interactions sont activées par des attributs :

Copier l’adresse du serveur
<button type="button" data-stellr-copy="{{ section.serverAddress }}">
  <code>{{ section.serverAddress }}</code>
  <span data-stellr-copy-label>Copier</span>
</button>
Onglets
<div data-stellr-tabs>
  <button type="button" role="tab" data-stellr-tab="java" aria-selected="true">Java</button>
  <button type="button" role="tab" data-stellr-tab="bedrock" aria-selected="false">Bedrock</button>
  <div data-stellr-panel="java">…</div>
  <div data-stellr-panel="bedrock" hidden>…</div>
</div>

Les onglets se changent au clic et au clavier (flèches, Début, Fin). Sans script, le premier panneau reste affiché.

Feuilles de style

Les fichiers assets/*.css sont chargés après la feuille de style de Stellr (classes sb-*) : il suffit de surcharger ce qui change. Ils passent aussi par Liquid, pour utiliser les réglages :

assets/theme.css
.sb-site .sb-block { padding-block: {{ settings.espacement }}px; }
{% if settings.ombres %}
.sb-site h1, .sb-site h2 { text-shadow: 0 4px 0 rgb(0 0 0 / 35%); }
{% endif %}
  • Pour écrire {{ ou {% dans le CSS, entoure-les de {% raw %}…{% endraw %}.
  • Les feuilles ne peuvent rien charger hors de Stellr : polices Google Fonts et images de la médiathèque seulement.
  • Les couleurs et polices choisies dans « Style » sont des variables CSS sur la racine (stellr.root_style).
  • Garde stellr.root_class sur la racine du layout : les pages que Stellr affiche lui-même (boutique, compte, vote) en ont besoin. Mais la feuille de base contient .sb-site section { max-width: 1100px; margin: 0 auto; padding: 64px 24px; } : toute balise section de ton thème est bridée à 1 100 px et centrée, fond compris. Annule cette règle pour tes sections, par exemple .sb-site section.ma-section { max-width: none; margin: 0; padding: 0; }, pour avoir des bandes pleine largeur.
  • Navigation flottante (position: sticky ou fixed par-dessus la page) : elle ne doit pas réserver de bande au-dessus de la première section, sinon le fond de la page apparaît derrière elle. Fais remonter la première section sous la navigation, avec la même précision que la règle ci-dessus : .sb-site section.mon-hero { margin-top: -72px; padding-top: 150px; } (hauteur de la navigation, puis assez d’espace pour dégager le contenu).

Ce que la liste blanche garde

Le HTML produit est filtré : ce qui n’est pas dans la liste est retiré, sans erreur. Jamais de script, iframe, object, embed, form (pour l’instant), link, meta, ni d’attribut d’événement (onclick…).

Balises gardées : a, abbr, article, aside, b, blockquote, br, button, caption, cite, code, dd, del, details, div, dl, dt, em, figcaption, figure, footer, h1, h2, h3, h4, h5, h6, header, hr, i, img, ins, kbd, li, main, mark, nav, ol, p, picture, pre, q, s, section, small, span, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time, tr, u, ul, svg, path, g, circle, ellipse, rect, line, polyline, polygon.

BaliseAttributs gardés
toutesclass, id, role, title, hidden, style, lang, dir, tabindex, aria-*, data-*
ahref, target, rel
imgsrc, alt, width, height, loading, decoding
buttontype, disabled
detailsopen
tdcolspan, rowspan
thcolspan, rowspan, scope
timedatetime
olstart, reversed
svgviewbox, viewBox, width, height, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin, d, cx, cy, r, rx, ry, x, y, x1, y1, x2, y2, points, transform, opacity, focusable, xmlns
  • Liens : http, https, mailto ou relatifs. Un lien target="_blank" reçoit rel="noopener noreferrer" ; seuls nofollow, ugc et sponsored sont gardés du rel du thème.
  • Images : de la médiathèque du serveur, des produits de la boutique, ou relatives ; les autres perdent leur adresse.
  • Icônes SVG : seulement des formes simples (pas de use, image ni foreignObject).