magentix

Développeur Magento indépendant depuis 2009

Billets : Le générateur de site statique StaPy


Le générateur de site statique StaPy

Par Matthieu le 15/11/2021

Il y a quelques mois j'ai entrepris de re-développer le site Magentix. Celui-ci utilisait un traditionnel PHP / MySQL. Mais au vue de la simplicité du site, le statique était beaucoup plus adapté.


StaPy est le générateur de site statique que j'utilise depuis plusieurs mois. Le développement a été motivé par la refonte de Magentix. Le site est devenu un micro-blog, sans interaction (pas de formulaire, pas de commentaire). Un SSG (Static Site Generator) est parfaitement adapté.

Il existe des centaines de générateurs de site statique. Je voulais quelque chose de très simple. StaPy est un mini SSG qui s'enrichit au fur et à mesure des releases. J'aimais aussi l'idée de concevoir l'outil avec lequel j'allais travailler.

À l'heure où j'écris ce billet la version 1.7.0 vient juste de paraître. Je pense le SSG assez mature pour en parler plus largement et exposer ici les choix de conception.

Python

Il y a un énorme avantage à Python : il est disponible partout et lorsque ce n'est pas le cas il est très facile de l'installer.

Sous Windows par exemple, il peut s'installer directement depuis le Microsoft Store. Le SSG devient sur ce système un simple executable capable de lancer un serveur et de générer le site sans passer par la ligne de commande.

Python sur le Microsoft Store

Sous unix il y a de fortes chances que Python soit déjà disponible sur le système car préinstallé.

Portabilité

StaPy présente un seul script et aucune dépendance. Dans l'esprit de simplicité, je me suis imposé d'utiliser ce que permet nativement Python, sans paquet supplémentaire.

Il suffit de partager le script et les sources du site pour que n'importe quel système disposant de Python puisse générer un site, sans disposer d'une connexion Internet. Même sur Android via Termux.

Portabilité de Stapy

Compatibilité

StaPy fonctionne à partir de la version 3.4 de Python, dont la date de release est le 16 mars 2014. Il restera compatible pour cette version le plus longtemps possible. Je m'efforce de plus en plus d'intégrer la notion d'obsolescence logicielle dans mes conceptions, facilitée ici par un programme local sans dépendance dont le seul objectif est d'assembler un site.

JSON

Le format JSON pour stocker les données est très adapté. Une solution efficace pour assurer l'interopérabilité entre les systèmes. Je peux imaginer générer les JSON de différentes manières, par exemple les récupérer depuis l'API d'une solution comme graphCMS (SAAS) ou Strapi (FOSS), et les copier sans effort. Ou tout simplement les écrire à la main.

Dans StaPy le nom du fichier correspond au chemin de l'URL, et les données qu'il contient alimentent la page (metas, titre, date, chemins des blocs et page de contenu, etc...)

/                 : index.html.json
/hello.html       : hello.html.json
/hello/world.html : hello/world.html.json
/hello/world/     : hello/world/index.html.json
{
    "template": "template/default.html",
    "content":  "page/blog/post.html",

    "meta_title":       "Welcome to this new post!",
    "meta_description": "Check out a great post.",
    "title":            "This is a new post!",
    "intro":            "This post is great.",
    "author":           "Matthieu",
    "date":             "01/01/2021",

    "tags": ["post", "sitemap"]
}

La seule clé obligatoire est template, le reste est totalement libre.

Le format JSON permet aussi de ne pas dépendre d'un paquet supplémentaire. Cela aurait été le cas avec du YAML ou du TOML. Je le trouve également plus lisible que le XML.

Multi environnement

Certaines données de la page comme le domaine ou les scripts analytics sont propres à l'environnement : production, développement, recette...

Il est possible de définir des variables spécifiques pour un environnement, et de générer plusieurs versions du site.

Environnements Stapy

Temps réel

La page statique est générée pour tous les environnements à chaque requête de type GET (ressources incluses). Lorsqu'une page est ajoutée ou modifiée et que je visualise le rendu dans un navigateur, la version statique est mise à jour, il n'est pas nécessaire de re-générer tout le site.

Génération des pages en temps réel

Modularité

Une fois le serveur lancé, d'autres scripts indépendants peuvent interagir avec l'API HTTP, par exemple pour générer un sitemap ou un flux RSS.

Serveur Stapy

Un script (en n'importe quel language) peut ainsi récupérer la liste de toutes les pages au format JSON (GET), générer un fichier rss.xml puis le copier sur l'environnement souhaité (POST).

Templating

Le moteur de template est simplifié à l'extrême. Pas de condition, pas de boucle. Il effectue uniquement du remplacement.

{{ name }} <-- Variable -->
{% content %} <-- Template simple (bloc) -->
{% link + hello.html %} <-- Template avec données d'une page spécifique -->
{% post ~ tags:post %} <-- Template avec boucle sur une liste de pages -->

L'affichage d'un bloc ou d'une variable est conditionné par les données de la page ou de l'environnement. Il est donc possible de se passer de l'instruction if :

{
    "analytics": "",
    "analytics.prod": "template/bloc/analytics.html"
}
{% analytics %}

Le bloc analytics est ici affiché uniquement sur l'environnement prod.

Contenus

Markdown est très pratique, je me suis longuement intérrogé sur son implémentation. Il est un véritable atout pour la portabilité, l'interopérabilité et la pérennité des contenus.

Mais il m'oblige à dépendre d'une librairie externe, et j'aime la liberté qu'offre le HTML dans la rédaction des articles. Il m'arrive souvent d'ajouter un attribut class ou id sur un élément pour un rendu spécifique.

L'idée serait pour ce point de laisser la liberté d'implémenter Markdown sous forme de plugin externe sur le moteur de template. À l'étude.

Légèreté

Le script pèse environ 16ko pour 450 lignes. Le challenge est d'implémenter tout ce que je souhaite le plus efficacement possible (sans dépendance).

StaPy peut être forké, modifié et partagé très facilement.

Roadmap


Une question ? Contactez-moi sur Twitter