De Jekyll à Hugo
- 7 minutes de lecture
Dans l’univers des générateurs de sites statiques, la bataille fait rage entre plusieurs frameworks depuis quelques années. Vous avez peut-être entendu parler de Jekyll, Next.js, Gastby ou Hugo ? Je ne cite que les plus sollicités par la communauté sur GitHub, mais il en existe des centaines.
Pourquoi cet engouement ? Cet article n’en parlera pas.
Pour de louables raisons, je m’étais engagé l’année dernière à auto-héberger mon nouvel espace d’expression personnel. J’y ai découvert avec intérêt et amusement de nombreuses technologies que j’ai pliées, réinstallées, transformées pour les adapter à mon besoin. Sans trop rentrer dans les détails, j’ai fini par avoir :
- un serveur VPS chez OVH pour un coût de 3,99€ par mois
- une routine mensuelle de renouvellement de certificat avec certbot
- une instance Theia dans un conteneur Docker
- une image Jekyll 4.1.0 que j’invoquais dans Docker
- deux dépôts GitHub privés pour les articles (posts) et les brouillons (drafts)
- le thème Poole, léger et modulable… que j’ai modulé
Alors que la question de conserver ou non le serveur VPS se pose pour la nouvelle année qui démarre bientôt (il devient agé, limité, pour ne pas dire sénil), j’ai remis récemment en cause mon attachement pour le framework Jekyll, si élégant à l’époque.
Le machin repose sur des dépendances Ruby. Aussi nombreuses (ou presque) qu’un
nouveau projet en Node.js. J’ai mangé du Gemfile
par le passé, aussi je n’ai eu
aucune réelle difficulté à installer les quelques modules nécessaires à la
concrétisation de mon projet. En voici le contenu :
source "https://rubygems.org"
gem "jekyll", "~> 4.1.0"
gem "classifier-reborn"
# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-paginate-v2"
gem 'jekyll-target-blank', "~> 2.0"
gem 'jekyll-time-to-read'
end
Et c’est tout.
Je n’avais besoin que de la pagination et de l’estimation du temps de lecture par article. Mine de rien, ça me semblait un peu grossier d’exiger que ces simples modules ne soient pas intégrés nativement. J’ai donc engagé mes recherches et le portage du présent site sur l’une des autres solutions, à savoir Hugo.
Migre moi ça, p’ti con
Et les développeurs de Hugo n’y sont pas allé de main morte pour asseoir leur
logiciel dans ce paysage turbulent : ils intègrent un assistant de migration
spécialement pour un projet Jekyll en récupérant ses fichiers .md
et ses
ressources statiques. En soit, la chose n’est pas complexe et le résultat est
au rendez-vous. Mais…
$ hugo import jekyll blog blog_hugo
Importing...
Congratulations! 128 post(s) imported!
Now, start Hugo by yourself:
$ cd blog_hugo
$ git clone https://github.com/spf13/herring-cove.git themes/herring-cove
$ hugo server --theme=herring-cove
Bien sûr, l’assistant propose un thème pour embellir le projet en lieu et place d’une transposition du language Liquid sur lequel repose les fichiers modèles de Jekyll. C’est plus simple mais… ce n’est pas réellement ce que je souhaitais.
Autant le rendu des articles est impeccable avec ce thème, autant la navigation est assez pauvre à mon goût. Bien évidemment, c’est bien suffisant pour n’importe qui. Mais voilà. Mon thème principal me manquait et malheureusement pour moi, il n’existait pas pour Hugo.
De longues soirées d’hiver
J’aime les choses simples. Et j’aime encore plus les comprendre en profondeur. C’est pour cette raison que je me suis lancé plusieurs heures dans la lecture assidue de la documentation très riche sur gohugo.io. Les concepts sont assez différents et le passage n’a pas été si évident que cela. Je vous propose un florilège des astuces qu’il m’a fallu découvrir pour proposer le portage intégral de mon site.
Les permaliens
Jekyll et Hugo proposent une gestion fine des URL à l’aide du paramètre
permalinks
pour reconstruire l’adresse d’une page ou d’un article et favoriser
son référencement. Cependant, leur paramètrage par défaut diffère et il est
nécessaire de retrouver le comportement de l’un avec l’autre.
permalinks:
posts: /:year/:month/:day/:slug
Pour ma part, j’ai privilégié le dérivé :slug
pour être en mesure de surcharger
la dernière portion de l’URL dans les rares cas où le titre était malformé entre
Jekyll et Hugo. Par exemple pour mon article « Tour d’horizon de PgBouncer »
où l’apostrophe n’était pas remplacée par le tiret et où je ne voulais pas
perdre le référencement, j’ai pu contourner le problème avec l’ajout d’une simple
ligne en en-tête du fichier Markdown.
---
title: "Tour d'horizon de PgBouncer"
slug: tour-d-horizon-de-pgbouncer
---
Il m’a également fallu découvrir un paramètre particulier pour ne pas prendre en compte les accents présents dans les titres lors de la génération du slug.
removePathAccents: true
Syndication automatique du contenu
Pour le coup, j’ai bénéficié d’une simplification dans mon projet grâce au support
natif et avancé des flux RSS. Alors qu’avec Jekyll, je devais maintenir mes
fichiers feed.xml
et atom.xml
à la racine du projet, j’ai découvert avec Hugo
la notion de taxonomie qui permet la classification des articles. La
taxonomie regroupe autant les sections, les catégories et les tags, et je trouve
ça astucieux.
Imaginons une arborescence très simple avec une page et un article :
content/
├── pages
│ └── a-propos.md
└── posts
└── 2020-11-18-quelques-outils-meconnus.md
Sans configuration supplémentaire, Hugo générera le contenu statique pour chacun
des éléments du projet, en consultant notamment les en-têtes pour extraire les
informations categories
et tags
des articles.
La magie opère avec un ensemble de fichiers index.xml
regroupant les éléments
d’une même taxonomie.
public/
├── 2020
│ └── 11
│ └── 18
│ └── quelques-outils-meconnus
│ └── index.html
├── categories
│ ├── index.html
│ ├── index.xml
│ └── postgresql
│ ├── index.html
│ └── index.xml
├── index.html
├── index.xml
├── pages
│ ├── a-propos
│ │ └── index.html
│ ├── index.html
│ └── index.xml
└── tags
└── administration
├── index.html
└── index.xml
La colorisation syntaxique
À ce sujet, j’ai eu une petite surprise avec les balises HTML jusqu’à ce que je me penche sur la documentation. En effet, par défaut, Hugo transforme un bloc de code Markdown en série de balises stylisées.
<div class="highlight">
<pre style="color:#f8f8f2;background-color:#272822;
-moz-tab-size:4;-o-tab-size:4;tab-size:4">
<code class="language-sql" data-lang="sql">
<span style="color:#66d9ef">CREATE</span>
<span style="color:#66d9ef">TABLE</span> people (
id BIGINT
<span style="color:#66d9ef">GENERATED</span>
ALWAYS <span style="color:#66d9ef">AS</span>
<span style="color:#66d9ef">IDENTITY</span>,
details jsonb,
<span style="color:#66d9ef">PRIMARY</span>
<span style="color:#66d9ef">KEY</span> (id)
);
</code>
</pre>
</div>
Puisque mon thème original proposait une feuille de style au format SASS spécfiquement pour la colorisation syntaxique, j’ai tenté d’activer l’un des paramètres de Hugo pour utiliser les classes de style plutôt que le comportement ci-dessus.
pygmentsUseClasses: true
Le résultat était inespéré avec les classes reconnus par mes règles CSS.
<div class="highlight">
<pre class="chroma">
<code class="language-sql" data-lang="sql">
<span class="k">CREATE</span>
<span class="k">TABLE</span> <span class="n">people</span>
<span class="p">(</span>
<span class="n">id</span> <span class="nb">BIGINT</span>
<span class="k">GENERATED</span>
<span class="n">ALWAYS</span> <span class="k">AS</span>
<span class="k">IDENTITY</span><span class="p">,</span>
<span class="n">details</span> <span class="n">jsonb</span>
<span class="p">,</span>
<span class="k">PRIMARY</span> <span class="k">KEY</span>
<span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">);</span>
</code>
</pre>
</div>
Les balises HTML dans le Markdown
Mes fichiers Markdown contenaient des balises HTML pour quelques effets visuels,
à savoir des encarts d’avertissement <div>
, du surlignage <u>
et de très
(trop) nombreux exposants <sup>
pour mes sources d’articles. Pour cet aspect,
Hugo est plus restrictif que Jekyll et ignore tout bonnement les balises dans le
rendu de ses pages.
<!-- raw HTML omitted -->
Pour le coup, je n’ai pas cherché s’il existait un paramètre de configuration qui me permettrait de lever la restriction. Ma solution de contournement fut d’utiliser les composants shortcodes pour mes quelques exceptions et la documentation était bien suffisante pour y parvenir sereinement.
Par exemple pour mes encarts, j’ai gagné en facilité de rédaction avec la méthode
markdownify
fourni par le système de rendu, et je n’écris plus que du Markdown
dans mes fichiers !
<!-- layout/shortcodes/message.html -->
<div class="message">{{ .Inner | markdownify }}</div>
<!-- content/posts/exemple.md -->
{\{< message >}\}
Exemple de rendu avec un lien de [documentation][17].
{\{< /message >}\}
Ne pas s’attarder sur les \
qui ne servent qu’à échapper les accolades.
En bref
Au-delà des quelques paramètrages ou réécriture Markdown qui m’ont fait perdre du temps, Hugo présente bien plus de fonctionnalités natives que ne le fait Jekyll. Je dresse une liste non exhausitive des apports qui m’ont convaincu à passer le cap.
- Pagination simple et intégrée
- Temps estimé de lecture avec la variable
.ReadingTime
- Génération des pages nettement plus rapide
- Portabilité du logiciel avec zéro dépendance système
Pour conclure, je me suis résolu à héberger le projet et le rendu des pages sur GitHub, en suivant les instructions détaillées. La bascule du nom de domaine a ainsi été opérée ce midi et je n’ai plus à me préoccuper de mon ancienne instance VPS ni du certificat à renouveller auprès de Let’s Encrypt.