Créer un site web statique en 2024 ?
Les intelligences artificielles génératives nous forcent à réfléchir. Face au déferlement des contenus semi-débiles, il est temps de se poser les bonnes questions. Ou va le web ? Dans le mur. Voici quelques briques techniques pour ne pas devenir fou.
Make the web great again
Comme premier billet technique de ce blog, il nous a paru naturel de décrire la conception du blog lui-même. Histoire de changer un peu de la science des données, notre sujet de prédilection.
Ce qui suit sera probablement erroné
Le blog va évoluer au cours du temps : il serait étonnant d'avoir anticipé toutes les fonctionnalités utiles du premier coup. Ce qui est décrit ici ne correspondra donc probablement pas à la version actuelle du blog que tu lis actuellement en 2067. Et si vous le lisez en 2024, vous constaterez que la peinture n'est pas vraiment fraiche, alors vous ferez gaffe à vous mettrez vos doigts et vous n'hésiterez pas à nous remonter les incohérences et inévitables bugs du machin.
Sobriété
L'objectif est de disposer d'un site sur lequel publier exclusivement du texte accompagné parfois de quelques images. Par conséquent, rien d'interactif. Pas de commentaires. Pas de vidéo non plus. Encore moins de plugin vers un agent conversationnel tout claqué comme chatGPT. Bref, nous souhaitons construire un site avec une présentation minimaliste qui ne divertisse pas le lecteur du fond - en espérant qu'il y en ait, quand même, du fond. Un site statique, donc. C'est-à-dire un site dont le contenu ne varie pas en fonction du lecteur.
Nous nous sommes inspiré de ce magnifique site.
Un produit bien de chez nous
Il existe de nombreux générateurs de sites statiques en 2024 : Astro, Jekyll, Hugo. Mais bon, installer 600 Mo de dépendances obscures pour une tâche (a priori) aussi simple, ça freine. Sachant qu'on va probablement tomber sur des problèmes de versions. Jongler avec les versions de Python nous suffit amplement.
De plus, se farcir les documentations, passer des heures sur Stack Overflow ou lire le code source pour trouver la bonne configuration qui marche, ca n'est pas super enthousiasmant. En général, d'ailleurs, on n'en retire rien d'intelligent ; trop de spécifique, rien d'utile. Ça tombe en marche, mais pourquoi ? D'autant plus que les technologies web ont cette fâcheuse tendance à être obsolètes dès qu'on regarde 5 minutes ailleurs.
Nous avons ainsi développé notre solution maison. Comme Ploum, par exemple. Bien sûr, on suspecte un syndrome NIH. Et on guette les inconnues inconnues tapies dans l'ombre prêtes à nous mordre au visage. D'un autre côté, si on ne peut plus écrire simplement une page HTML en 2024, alors le web a fortement régressé.
Python
Un générateur de site statique n'est pas juste une simple page HTML. C'est un compilateur vers du HTML, entre autres. Autrement dit, un programme qui prend du texte (dans un certain langage) en entrée et le transforme en HTML que le navigateur pourra alors afficher. Si tout se passe bien.
Pour écrire ce programme, nous avons choisi Python, langage vulgaire qui fait tout, mais mal. On sacrifie ainsi l'élégance à l'efficacité. Car le but c'est d'avoir un site, pas de définir une architecture web idéale à base de d'effets algébriques. Si nous avions le temps, nous l'aurions écrit en Haskell ou en Brainf*ck.
Le gestionnaire d'environnement virtuel pipenv rapplique aussitôt et pyenv le rejoindra si les versions locales de Python ne correspondent pas.
Markdown
Une fonctionnalité souhaitée est la possibilité d'écrire le texte en Markdown, format très pratique et moins velu que le LaTeX, puis de le convertir automatiquement en HTML. Là encore, c'est de la compilation. Cette fonctionnalité est raisonnable et proposée par de nombreux générateurs disponibles.
Ce serait bête d'écrire le compilateur Markdow vers HTML nous-mêmes : l'honnête paquet Python markdown fait ça très bien pour nous. De plus, ce paquet gère des extensions au cas où le Markdown natif ne suffise plus.
I speak Wall Street English
Autant que possible, chaque page sera traduite dans la langue des perfides. Nous avons une vie en dehors de l'informatique, et les progrès de la traduction automatique ont été fabuleux ces dernières années ; nous utilisons donc sans aucune vergogne les outils comme Deepl ou l'autre chat. Puisque le site est statique, cela implique de doubler tous les billets en Markdown et toutes les pages HTML. Pour les pages générales (comme l'index) et les différents composants (comme la barre de navigation), nous avons utilisé un dictionnaire de traduction pour chaque langue. Il y a encore une version par langue pour les pages générales, mais le but est de passer à une seule.
Jinja
Une page web est typiquement constitué d'un en-tête, d'un pied de page, d'un menu de navigation et d'autres éléments que l'on retrouve inchangés à chaque page. Pour éviter de recopier à la main tous ces éléments (sans se tromper), on utilise le moteur de gabarit Jinja, plutôt répandu. De plus, on fourre les gabarits avec plein de variables, par exemple pour obtenir la traduction des mots dans la langue affichée.
Là encore, c'est de la compilation : une surcouche d'HTML qui sera dépouillée.
Jolie soupe
Les projets informatiques sont toujours plus complexes que prévus. On ne peut pas y échapper, c'est terrible.
Dans notre cas, nous voulions insérer des liens vers la traduction d'un billet juste après son titre et avant son contenu. Problème : le titre du billet est écrit dans le même fichier Markdown que son contenu et tout est traduit d'un coup en HTML. Or, les liens sont engendrés par le générateur du blog : ils arrivent après. Notamment parce que le générateur vérifie si une traduction du billet existe.
Il a donc fallu modifier le code HTML engendré par la traduction du Markdown en retirant le titre pour le déplacer à un autre endroit de la page finale. Avec le paquet Python BeautifulSoup, conçu pour travailler le HTML au corps.
CSS
Nous voulons éviter autant que possible le JavaScript, mais pas le CSS, quand même, nous ne sommes pas des barbares et nous avons pitié de nos lecteurs éventuels.
Le CSS est une bête sauvage, un accumulateur de dette technique. Il a même été pensé comme ça, c'est dans son nom : une cascade de dépendances.
Le compilateur Sass, à défaut de le domestiquer, le tempère légèrement. Là aussi, par souci de légèreté, nous évitons (pour l'instant ?) les cadriciels comme Tailwind CSS.
Typographie
La typographie est un sujet important et souvent délaissé. Nous avons suivi les recommandations de Matthew Butterick, et, reconnaissons-le mollement, nous avons honteusement copié le style de son blog. Les polices utilisées sont IBM Plex, Charter et Terminal Grotesque.
Structure
Pour que chacun puisse retrouver ses petits, notamment en séparant chaque langage (le Python d'un côté, le Markdown de l'autre, les gabarits Jinja ailleurs, le CSS autre part, etc.), il faut disposer d'une structure de répertoires pertinente qui reflète le fonctionnement du générateur. On peut écrire du code propre au sein d'une structure infâme. Cela revient à lire un livre bien écrit mais dont les pages sont dans le désordre.
Le projet étant en cours, les fonctionnalités et, par conséquent, la
structure va évoluer. Toutefois, certains répertoires s'imposent à
force d'expérience, par exemple bin
contenant des scripts utiles ou
asset
avec les données statiques.
GitLab
Pour éviter de se transmettre le code par mail ou pigeons voyageurs, nous avons déposé le code sur GitLab. Là. Libre à vous de reprendre le code et d'en faire ce que vous voudrez.