1
0
Fork 0
contenu/blog/2023/09/03/nouveau-site-en-ligne/index.md

13 KiB
Raw Blame History

Me voilà enfin débarrassé de deux outils sur lesquels je (et dautres) râle depuis quelques temps : Hugo, et Tailwind.

Maintenant, on va pouvoir samuser. Maintenant, je vais avoir un blog véritablement à mon image, épuré de technologies qui ne me conviennent pas, auxquelles je nadhère pas, utilisées juste sous prétexte que cest hype. Ce nouveau site, cest 100% Richard Dern (ou presque).

Il va donc falloir vous habituer à ces inclusions darticles dans larticle parce que jen suis assez fan personnellement. Je ne men servirai jamais pour introduire un contenu qui na rien à faire là : ces inclusions seront toujours pertinentes, mais cest là loccasion pour moi den abuser à titre démonstratif. Jai juste à faire :

<x-read-more :urls="/blog/2023/04/18/refonte-du-site/" />@endverbatim

Ou :

<x-read-more :urls="[
    '/liens-interessants/2023/08/11/3ebdad4c8bd168e0d3f29a64341866a3/',
    '/blog/2023/04/06/rant-mon-site-c-est-de-la-merde/',
    '/blog/2022/02/12/rant-hugo-et-tailwind/'
]" />@endverbatim

Comme au début de cet article, pour que mes inclusions se fassent. De façon plus générale, je peux travailler avec Blade dans les articles, et donc en PHP. Évidemment, pour un développeur PHP, cest beaucoup plus agréable…

Jai développé mon propre générateur de site statique. Il nest pas fait pour être redistribué : nespérez pas télécharger les sources et lancer votre propre blog. Déjà parce que les sources de mes propre articles sont incluses1, et puis parce que je lai développé pour répondre à mes besoins et envies spécifiques. Par contre, jencourage la lecture du code : vous y trouverez peut-être une bonne idée ou deux.

Le moteur repose sur Laravel dans sa dernière version. La partie UI/UX, cest moi, vraiment à 100%. Non pas quil y ait de quoi se vanter, je ne cherche pas à faire du beau, je cherche à faire du “moi” : cest pas très beau parce que je nai aucun goût (pas pour rien que je suis développeur back-end), mais je suis content du résultat.

Pas de framework pour le CSS, jai tout fait à la main, et ça correspond enfin à une esthétique de laquelle je me sens proche. Les sources du CSS sont moches et pas franchement optimisées, jai du refactoring à faire, mais cest ce qui arrive quand on ne sait pas trop où lon va. Mais au final, je suis assez satisfait de mes choix esthétiques. Encore une fois, je sais que ça ne plaira pas à tout le monde, mais pour mon blog, cest terminé : je nutiliserai plus rien de prémâché. Je me considère comme un artisan, je fais de lartisanat, et puis zut.

Promis, je ne ferai pas trop dinclusions sauvages dans les futurs articles, mais jaime bien mon nouveau super-pouvoir…

En ce qui concerne les fonctionnalités, on va dire que je considère disposer dun Minimum Viable Product : dans mon cas, cela signifie que je dispose à peu près des mêmes fonctionnalités que celles que jutilisais avec Hugo. En fait, mes sources markdown sont récupérées pratiquement telles quelles, seuls les shortcodes ont été un peu chiants à réécrire parce que cela impliquait changer tous les appels bizarres à @{{< shortcode [...] />}}, là où maintenant jai des balises, beaucoup mieux question interopérabilité.

Puisque jai là un MVP, et quen plus de dégager Hugo et Tailwind je poursuivais dautres objectifs, je vais désormais pouvoir faire des choses vraiment intéressantes que je veux faire depuis longtemps sans savoir comment my prendre avec Hugo.

Jai déjà un système partiellement fonctionnel pour les liens externes et internes mais je veux aller plus loin. À titre informatif, voilà ce que je dois faire sous Hugo :

{{- /*
Putain mais que c'est dégueulasse...
Les séquences d'échappement sont pour éviter les espaces indésirables dans les
liens.
Le but ici est de changer l'aspect des liens s'ils pointent vers une page
externe ou interne, et dans ce dernier cas, en fonction de la section concernée.
*/ -}}{{ $ext := strings.HasPrefix .Destination "http" }}{{- /* Check si l'URL est absolue ou relative
*/ -}}{{ $url := .Destination | safeURL }}{{- /* Hugo déconne plus loin sans ça...
*/ -}}{{ $content := .Text | safeHTML }}{{- /*
*/ -}}{{ if $ext }}{{- /* Lien externe
*/ -}}<a rel="noopener noreferrer" class="link external inline-flex items-center space-x-1"
    title="Lien externe : {{ $url }}" href="{{ $url }}">{{- /*
    */ -}}<span>{{ $content }}</span>{{- /*
    */ -}}<span class="icon-[ri--external-link-line] h-4 w-4 text-slate-400 ml-1"></span>{{- /*
    */ -}}</a>{{- /*
*/ -}}{{ else }}{{- /* Lien interne
🤮 */ -}}{{ with (index (where .Page.Site.AllPages "RelPermalink" .Destination) 0) }}{{- /* Référence à la page liée
🤮 */ -}}{{ $date := .PublishDate | time.Format ":date_long" }}{{- /*
🤮 */ -}}{{ $section := .Parent }}{{- /* .Section ne fonctionne pas...
🤮 */ -}}{{ $title := "" }}{{- /* Le titre du lien est la concaténation de plusieurs éléments ci-dessous...
🤮 */ -}}{{ $parentTitle := delimit (slice "[" .Parent.Title "] ") "" }}{{- /*
🤮 */ -}}{{ if eq .Section "tags" }}{{- /* On ne met pas de date de publication si c'est un lien vers un mot-clé
🤮 */ -}}{{ $title = delimit (slice $parentTitle .Title) "" }}{{- /*
🤮 */ -}}{{ else }}{{- /*
🤮 */ -}}{{ $formatedDate := delimit (slice ", publié le" $date) " " }}{{- /*
🤮 */ -}}{{ $title = delimit (slice $parentTitle .Title $formatedDate) "" }}{{- /*
🤮 */ -}}{{ end }}{{- /*
*/ -}}<a rel="noopener noreferrer" class="link internal inline-flex items-center space-x-1" title="{{ $title }}"
    href="{{ $url }}">{{- /*
    */ -}}{{ if eq .Section "tags" }}{{- /*
    */ -}}<span class="icon-[bi--tags-fill] text-emerald-600 h-4 w-4"></span>{{- /*
    */ -}}{{ else }}{{- /*
    */ -}}<span class="{{ $section.Params.icon }} {{ $section.Params.color }} h-4 w-4"></span>{{- /*
    */ -}}{{ end }}{{- /*
    */ -}}<span>{{ $content }}</span>{{- /*
    */ -}}</a>{{- /*
*/ -}}{{ end }}{{- /*
*/ -}}{{ end }}{{- /*
*/ -}}@endverbatim

Cest juste a-bo-mi-na-ble. À gerber. Avec PHP/Laravel/mon moteur, toute la logique se fait là où elle doit être faite : dans un fichier PHP, et laffichage du résultat se fait là où il doit être fait : dans un fichier HTML. Plus exactement, cest le parseur CommonMark de PHPLeague qui moffre la possibilité de détecter un lien et le modifier pour affichage. Cest propre, lisible, maintenable. On pourra toujours mobjecter que cest parce que je ne maîtrise pas Go.

Non, c'est juste que Go c'est de la merde. En particulier son templating mais je ne vais pas radoter.

En fait, le développement de mon moteur sest fait en plusieurs phases. La première phase, jai tenté de mimer le fonctionnement dHugo. Les performances étaient excellentes, parfois meilleures (alors quHugo se prend pour le plus rapide du monde). Mais très vite je suis arrivé aux mêmes limitations : toute modification dans ce que je veux faire prend des proportions dantesques et rend très vite le code dégueulasse. Si Go, cest de la merde, en fait, ça va un peu plus loin que ça (évidemment).

Je critique donc un paradigme de programmation qui sest très vite répandu (et qui dailleurs, infeste les 3/4 du web), cest le principe du Just-in-Time. En gros, on repousse lexécution dune instruction jusquau tout dernier instant. Au lieu de lancer quelques instructions préliminaires pendant lesquels lutilisateur a limpression que rien ne se passe ou que sa machine rame, toute instruction est divisée en plein de micro-instructions qui ne seront exécutées que lorsque lutilisateur veut que quelque chose se passe.

Cest assez difficile à expliquer concrètement mais ce qui rend Hugo si rapide, cest quil ne génère le rendu dune page que lorsquil na plus le choix. Il diffère le plus possible le plus dinstructions possibles, de sorte à économiser les ressources.

Ma deuxième tentative aurait pu me faire croire que cétait effectivement la meilleure chose à faire. Jai décidé dopter pour une approche qui anticipe beaucoup plus les choses, avec une étape de collecte dinformations, une étape de transformation, et une étape denregistrement, le tout en utilisant massivement toutes sortes de caches, au risque de dupliquer des caches que Laravel aurait déjà fait pour moi “sans que je sois au courant”. Il en a résulté une application vraiment lente (plus de 10 minutes pour une génération du site à froid).

Et puis, je me suis dit que ce nest pas parce que je développe un site statique que mon moteur doit être minimaliste : je veux que mon moteur génère un site statique de la façon la plus personnalisée possible, cest-à-dire qui respecte mes besoins et envies. Jai ainsi abandonné lidée de faire une application sans base de données, et je suis reparti dune feuille blanche pour la dernière fois.

Il faut environ 1m30 à Hugo pour générer à froid (caches vides) lensemble de mon site, dans un container docker avec la surcouche Rosetta dApple. Il ne lui faut ensuite plus que 8 secondes pour “rafraîchir” le site après une petite modification.

Mon générateur est exactement aussi rapide. À la seconde près, en fait.

Mais la vraie force de mon générateur par rapport à Hugo est sa capacité à identifier et maider à corriger les problèmes. Actuellement, il est capable de me dire quels fichiers sources devraient être renommés (par exemple, /test-du-bidule-machin.md vers /test-du-bidule-machin/index.md), quels attributs front matter sont problématiques (inutilisés, obsolètes, mal-formés, orphelins, etc.), lister les liens morts, etc. Et il peut corriger tout seul certains de ces problèmes.

Ce qui traduit un deuxième paradigme moderne sur lequel je peste aussi tout le temps : il faut cacher les problèmes aux utilisateurs. Ils ne doivent pas savoir quil se passe un truc pas normal, on doit poursuivre lexécution coûte que coûte. Du coup, jai des anomalies dans mes articles, et Hugo sen fout, mon site est généré.

Mon moteur va me dire (prochainement) sil existe des mots-clés orphelins, sous-utilisés, ou qui se rapprochent sémantiquement dautres mots-clés pré-existants, voire corriger automatiquement des erreurs de syntaxe à la con (javais un mot-clé appelé “Intelligence Atificielle” : vas demander à Hugo de rajouter le “r” manquant et mettre à jour tout seul les pages qui référencent ce mot-clé erroné).

Autre fonctionnalité quil me tarde de mettre en place : les dossiers. Une façon de regrouper des articles éparpillés dans le temps ou dans les sections du site, dune façon ordonnée, triée et navigable. Je pense évidemment à mon livre Lhumain, cette espèce primitive dont la lecture est actuellement hasardeuse et décousue. Mais ça serait pertinent pour dautres séries darticles, telles que :

Enfin, jaimerais des liens entre taxonomies. Par exemple, pour les films et séries, jai une taxonomie pour les acteurs et une taxonomie pour les personnages fictifs, mais rien pour dire que Bryce Dallas Howard interprète Claire Dearing dans la saga Jurassic World. Je veux, dans un avenir proche, que si vous êtes sur la page consacrée à Bryce Dallas Howard, vous voyez le personnage quelle a interprété et dans quel(s) film(s) et séries. Auparavant, sous Hugo, je navais pas la moindre idée de la faisabilité du truc. Maintenant, jai beaucoup plus de flexibilité à disposition.

Jai évidemment un peu de polissage à faire, et une tonne de choses dans ma TODO pour ce nouveau moteur, mais en létat, jen suis très content. Il y a de la marge pour laméliorer, comme le veut lexpression consacrée, mais je peux déjà en faire plus quaprès deux ans dexpérience avec Hugo.

Maintenant, je me sens un peu plus chez moi.


  1. Ce nest plus le cas depuis le 6 septembre :

    ↩︎