Passer aux générateurs de sites statiques

Depuis avoir lu cet article en début d’année dernière, sur l’excellent Smashing Magazine, qui parlait de leur passage à Hugo, je me suis dit que dès que j’en aurai l’occasion, je me pencherai dessus. Et bien voilà, l’occasion est arrivée grâce aux Geeking Days que nous propose Slickteam.

Pourquoi passer à un générateur de sites statiques ?

La plupart des gens vont se diriger vers WordPress (WP) lorsqu’ils veulent mettre en place un site Internet. Il est facile d’accès, paramétrable et au final fait très bien le job. Mais au fil du temps, il s’est considérablement alourdi. Il est vrai que WP, pour les non développeurs est très accueillant avec sa multitude de thèmes, de plugins. On peut donc réaliser un site web rapidement et sans vraiment s’y connaître en développement.

Le problème est que dans certains cas, WP s’avère être un peu comme un bulldozer. En effet, dans le cas de sites vitrines ou de simples blogs, utiliser une base de données pour afficher quelques pages, c’est s’ajouter des contraintes de temps de réponse ou de non réponse de la part du serveur. En plus de cette base de données, il y a la multitude de fichiers utilisés par WP, qui doivent être inclus et compilés, et donc qui augmentent les temps de traitements.

Une autre très grosse problématique de WP sont “les plugins”. Ils peuvent ne pas être optimisés, ce qui aura pour conséquence d’augmenter le temps de réponse du serveur mais alourdira aussi le “poids” de vos pages. De plus, ils peuvent être mal sécurisés et donc corrompre l’intégrité de votre site et de vos données.

Une des autres contraintes, est liée au versionnage du contenu. WP s’est largement amélioré à ce sujet grâce à des plugins comme VersionPress mais lorsque l’on parle de versionnage et de bases de données, c’est toujours un peu la galère.

Toutes ces contraintes nous font nous dire qu’un site statique c’est bien. Le problème c’est qu’il faut être à l’aise avec le HTML/CSS et JS, ce qui peut être surmonté, mais surtout qu’il faut gérer les fichiers à la main un par un pour pouvoir modifier leur contenu, leur mise en forme ainsi que tous les fichiers dont ils dépendent. Et ça, c’est vraiment rédhibitoire.

C’est là qu’interviennent les générateurs de sites statiques. Le principe est que vous ne gérez que le contenu, une fois que vous aurez tout configuré bien entendu, et votre générateur s’occupera de créer tout le reste pour vous. On balance donc le contenu aux différents templates et hop, nos pages sont générées.

Ici, pas besoin de base de données et donc pas d’appels serveur et pas de requêtes. Pas de problème de sécurité avec des injections SQL ou autres. Il n’y a pas de calculs serveur autres que ceux pour le rendu de la page. Il y a donc un gain au niveau des performances mais aussi de la sécurité.

De plus, avec un site statique, nous pouvons imaginer l’héberger chez n’importe quel hébergeur vu qu’il n’y a pas d’autres besoins que HTML/JS/CSS.


La migration du site de Slickteam

Après cette présentation, entrons maintenant dans le vif du sujet avec cette partie plus technique.

Le site actuel de Slickteam est, comme vous l’aurez compris, basé sur WP et dans le cadre des Geeking Days, je me suis pris au jeu de le migrer vers une version statique générée grâce à Hugo. Il existe tout un tas d’autres générateurs mais mon choix s’est arrêté sur celui-ci dans le cadre de cet article car c’était un des plus connus avec Jekyll.

Le but que je me suis fixé a été de le porter en “ISO fonctionnel”. A savoir, même style graphique et même type de contenu. L’objectif principal étant d’appréhender Hugo.

Page d’accueil du site Slickteam

Analyse des types de contenu de slickteam.fr

Le site actuel se compose de deux types de pages. En soit, rien de bien compliqué et sûrement pas de quoi nécessiter un WP complet.

Les deux types sont :

  • La page d’accueil avec ses multiples sections
  • La page présentant les jobs proposés par Slickteam

La page d’accueil étant celle qui va nous faire étudier le plus de principes de Hugo. Nous verrons donc l’utilisation de la configuration, la mise en place des différentes sections, la création de contenu avec leur résumé associé pour en faire une accroche dans des listings.

La page des jobs, elle, permettra de voir le fonctionnement principal des générateurs de sites, à savoir la gestion de contenu.

Pour la suite, nous allons avoir recours à la ligne de commande, alors armez-vous d’un terminal et pour la modification des fichiers, utilisez votre éditeur de texte préféré.

Afin de pouvoir suivre plus facilement, je vous invite à récupérer les sources du projet qui sont à disposition sur le dépôt Github de Slickteam.

Installation

Pour l’installation de Hugo, selon l’OS que vous utilisez, vous pouvez l’installer via le gestionnaire de paquets de celui-ci : Homebrew pour OsX, Snap pour Linux ou Chocolatey pour Windows. Je l’ai installé sous OsX, j’ai donc saisi la commande suivante :

brew install hugo

Nous avons maintenant la commande hugo disponible dans notre terminal.

Création du projet

Pour la création de notre projet, il suffit de saisir la commande suivante :

hugo new site nom-du-site

Vous devriez vous retrouver avec l’arborescence suivante :

archetypes/
config.toml
content/
data/
layouts/
static/
themes/

Maintenant que le projet est créé, nous pouvons lancer le serveur local afin d’aller voir de quoi il en retourne dans notre navigateur.

Lançons donc notre serveur :

hugo server -D

L’option -D(draft) permettant de prendre en compte les contenus en brouillon.

La console est sympa et nous indique de nous rendre à l’adresse http://localhost:1313/. Alors exécutons nous.

Miracle … rien n’apparaît, juste une page blanche. Ceci est dû au fait que Hugo ne crée pas de thème par défaut. Tout est vide et nous devons nous même créer ce dont nous avons besoin.

Donc, à partir de là, soit vous allez télécharger des thèmes, soit comme moi, vous allez en créer un.

Juste une remarque avant de continuer : chaque modification effectuée sur les fichiers du projet entraîne un rechargement automatique du rendu dans le navigateur. Vous quittez votre éditeur de texte pour aller vers votre navigateur et hop, tout est déjà à jour. Plutôt pratique.

Création du thème

Comme je l’ai indiqué, nous allons créer notre propre thème. Pour se faire, il faut saisir la commande suivante :

hugo new theme nom-du-theme

Vous devriez vous retrouver avec un nouveau répertoire nom-du-theme dans le répertoire themes. Vous deviez avoir l’arborescence suivante dans ce répertoire fraîchement créé :

archetypes/
— defaut.md
layouts/
— _default/
—— list.html
—— single.html
— partials/
—— footer.html
—— header.html
— 404.html
— index.html
static/

Le répertoire layouts contiendra tout ce qui est propre à la structure des pages, static, lui, contiendra tout ce qui est propre au JS, CSS ainsi que les images.

Nous pouvons voir que cette arborescence est semblable à celle en dehors du répertoire des thèmes. Ceci est normal, étant donné que Hugo utilise les thèmes pour surcharger les fichiers de base. Si un fichier est présent dans votre thème, il sera utilisé mais si le même existe dans un des répertoires par défaut, celui-ci viendra l’écraser.

Il est donc possible d’utiliser de l’héritage selon les contextes. Ceci n’a pas été le cas lors de mon utilisation mais sachez que cela existe.

Paramétrage du thème

Nous pouvons maintenant jouer avec ce thème pour faire en sorte qu’il ressemble à celui de notre WP.

Base de notre thème

Dans ce qui est généré, il n’y a pas de fichier permettant de déterminer une structure HTML globale de nos fichiers. Nous avons bien le index.html mais il n’est plus utilisé que pour la page d’accueil.

Nous allons donc remédier à ce problème en créant un fichier baseof. Ces types de fichiers permettent de créer un gabarit de page selon les différents contextes que propose Hugo.

Je vais donc en créer un basique, qui sera composé des déclarations du <head> et du <body> de toutes nos pages. Afin qu’il soit le plus global possible, je le place dans layouts/_default/. Il sera ainsi chargé par défaut.

Ce type de fichier est bien pratique pour définir des blocs que l’on pourra surcharger selon le contexte (page d’accueil, page de job ou autre). Je crée donc un bloc header, un main et un footer. J’utiliserai les fichiers header.html et footer.html, vus précédemment dans l’arborescence, dans les blocs correspondants et le main dépendra du contexte.

Pour créer un bloc, rien de plus simple, il suffit d’utiliser dans nos fichiers :

{{ block “nomDuBlock” }}<! — Contenu par défaut ->{{ end }}

Et voilà, un joli bloc prêt à être utilisé. Vous pouvez aller voir dans le fichier baseof, vous retrouverez les blocs que j’ai cités.

Pour revenir sur l’arborescence créée, nous avons vu un répertoire partials. Une explication rapide sur ces partials car nous allons jouer avec tout de suite. Il s’agit d’éléments que l’on peut inclure sur n’importe quelle page. Ce sont des sortes de composants. Ceci est très pratique lorsque l’on a du code qui se répète.

Donc dans le répertoire partials, par défaut, nous pouvons trouver header.html et footer.html. Nous allons donc commencer par valoriser ces fichiers. Je vous passe le contenu du footer qui est porté tel quel. En revanche, dans le header, nous avons des liens vers les réseaux sociaux et autres comptes associés à Slickteam. Il s’agit là d’un premier cas d’utilisation pour rendre cela un peu paramétrable.

Utiliser la configuration pour récupérer du contenu

Un point d’entrée pour pouvoir utiliser des paramètres est le fichier config.toml. En effet, on peut y stocker beaucoup de choses et on peut surtout les réutiliser.

Nous allons donc y ajouter des paramètres personnalisés. Pour ce faire, il faut utiliser l’attribut [params]. Comme j’aurai sûrement d’autres paramètres à catégoriser plus tard, je vais apporter de la hiérarchisation sous cet attribut. J’ajoute donc une entrée [params.social] pour catégoriser tous ce qui est propre au réseaux sociaux.

J’ajoute donc dans config.toml :

[params]
— [params.social]
—— facebook = “”
—— twitter = “”
—— linkedin = “”
—— medium = “”
—— youtube = “”
—— instagram = “”
—— github = “”

Comme nous pouvons le constater, dans les sous hiérarchisations, il faut rappeler les niveaux précédents. Ici, nous avons [params] puis [params.social] qui indique qu’il s’agit d’une sous-catégorie.

Maintenant que nous avons ajouté ces paramètres, nous pouvons les prendre en compte au niveau de header.html.

<ul>
{{ with .Site.Params.social.facebook }}<li><a href=”{{ . }}”></a></li>{{ end }}
{{ with .Site.Params.social.twitter }}<li><a href=”{{ . }}”></a></li>{{ end }}
{{ with .Site.Params.social.linkedin }}<li><a href=”{{ . }}”></a></li>{{ end }}
</ul>

Quelques explications rapides :

  • {{with}} teste la présence d’un attribut. S’il n’est pas déclaré, le contenu englobé ne sera pas traité
  • .Site permet de dire que l’on utilise les paramètres du fichier config.toml
  • .Params indique notre entrée [params] dans ce même fichier
  • .social La hiérarchie personnalisée que j’ai créée
  • .facebook.twitter etc. Les paramètres de réseaux sociaux
  • {{.}} récupère le contexte courant. Dans notre cas, il s’agit de la valeur de l’attribut.

Voilà, vous pouvez choisir les informations que vous voulez afficher. En effet, si un attribut n’est pas remplit, il n’apparaîtra pas dans la liste. Vous pouvez donc déclarer plusieurs variables mais ne pas toutes les utiliser.

Le but est de rendre notre thème paramétrable. Nous allons donc faire en sorte que chaque composant du thème d’origine soit paramétrable à sa façon, soit par le fichier de configuration, comme pour les URLs des réseaux sociaux, soit par d’autres moyens que nous verrons plus tard.

Je ne m’attarderai pas sur le paramétrage de chaque section de la page d’accueil car, pour la plupart, elles reprennent le principe de l’utilisation de paramètres dans le fichier config.toml. Je vous laisserai donc découvrir les sources pour les voir toutes.

Gestion du contenu dynamique

En revanche, je vais m’attarder sur la partie « Jobs » car il s’agit du principe même des CMS et indirectement des générateurs statiques, les articles ou les pages de contenu. En effet, dans cette partie, la page d’accueil sert à avoir un texte d’introduction dirigeant vers un « article », dans notre cas, des pages pour la présentation des emplois proposés par Slickteam.

Comme je viens de l’indiquer, il y a donc un affichage sur la page d’accueil qui mène à un contenu grâce à un lien. Nous allons donc commencer par ajouter ce contenu. Pour ce faire, nous allons créer des fichiers de type Markdown dans le répertoire content de notre projet dans des sections que nous allons créer. Ces fichiers peuvent avoir le nom que vous voulez mais sachez que celui-ci est utilisé dans l’URL donc, choisissez-le bien !

Par exemple, nous avons comme titre d’emploi, « L’IOTeam needs you ! ». J’ai choisi liot-needs-you.md comme nom de fichier. Notre URL aura donc la forme https://slickteam.fr/job/liot-needs-you/ /job/ correspond à la section de contenu du même nom.

Pour le portage de notre contenu en Markdown, je vous laisse aller faire un tour sur la page de documentation afin de vous familiariser avec sa syntaxe si vous ne la connaissez pas déjà.

Maintenant que nous avons nos pages de contenu, nous pouvons y faire référence depuis la page d’accueil. Afin de parcourir le contenu de notre répertoire job, nous allons utiliser la commande range.

{{ range where .Data.Pages “Section” “nom-de-la-section” }}…{{ end }}

Où :

  • {{range}} est une fonction permettant de parcourir une collection
  • where permet d’appliquer un filtre à une collection
  • .Data.Pages permet de récupérer toutes les pages de contenu
  • "section" "nom-de-la-section" est le filtre sur une section

Toujours en faisant un tour dans les sources, vous pourrez voir comment je l’ai utilisée.

Un des plus gros problèmes que j’ai rencontrés est que Hugo ne permet pas d’avoir une « accroche » (texte de présentation) d’article différente de son contenu. La documentation ne fait référence qu’à une fonction .Summary, qui se contente de prendre les X premiers mots d’un texte afin d’en créer un “résumé”.

Pour pallier à ce problème, comme il est possible de créer ses propres variables dans nos documents dans une partie dédiée (appelée le « Front matter »), nous allons en profiter. Donc dans chaque fichier de contenu « job », dans le Front Matter (l‘entête du fichier), j’ai ajouté une variable abstract, que j’ai valorisé avec le contenu d’accroche de l’article associé.

L’utilisation de ces variables, dans le contexte d’affichage du contenu, se fait via l’appel à .Params.nomDeLaVariable. Une remarque, ici, .Params ne fait pas référence aux attributs du fichier config.toml mais aux attributs présents dans le Front Matter du fichier de contenu. Il s’agit de subtilités de contexte que je vous laisse découvrir dans la documentation.

Qui parle de gestion de contenu, parle d’utilisation de liens. Et pour accéder au contenu des jobs depuis la page d’accueil, Hugo propose la fonction .Permalink qui gère de manière transparente les URLs de nos contenus.

Nous venons d’aborder plusieurs aspects pour l’affichage d’un résumé des jobs depuis la page d’accueil et voici un code très simple les reprenant.

{{ range where .Data.Pages "Section" "job" }}
<article>
<header>
<h2><a href="{{ .Permalink }}"> {{ .Title }}</a> </h2>
<div></div>
</header>
{{ .Params.abstract }}
</article>
{{ end }}

A ce stade, un problème est apparu. Le lien vers l’article me menait à une page 404. Ceci était dû au fait que le fichier single.html était resté vide. Ce fichier étant utilisé pour gérer l’affichage d’une page de contenu, il m’a fallut le remplir. J’y ai donc défini un bloc main (pour être utilisé par mon fichier baseof cité en début d’article) contenant les variables .Title et .Content (variables par défaut que Hugo sait valoriser à la volée en fonction du contenu consulté). Maintenant en suivant les liens de la page d’accueil, plus de 404 et une belle page présentant les jobs.

Dans le même genre, il y a aussi le fichier list.html qui doit être remplit. Si dans l’URL vous saisissez seulement le nom d’une section de contenu (ex: /job/ pour Slickteam), une erreur 404 est aussi retournée. Même problème que précédemment mais dans ce cas ci, ce fichier comme son nom l’indique, sert à lister tous les fichiers contenus dans une section.

A la suite de tout ceci, j’ai recopié les styles du thème WP du site actuel vers mes fichiers Hugo afin d’avoir mon aspect “ISO fonctionnel”. Dans un cas réel, j‘aurai repris le code du front parce que ce n’est pas joli joli mais comme ce n’était pas l’objectif de cet article, je ne me suis pas penché dessus.

Voilà, notre site étant assez simple, je n’irai pas plus loin dans les explications car nous avons couvert les principes de bases utilisés pour mener à bien notre projet.

Générer les sources de notre site

Maintenant que nous en sommes arrivés là, il nous reste tout de même un point capital à aborder, la génération des fichiers sources pour l’utilisation du site en environnement de production. Et oui, dans l’état actuel des choses, votre serveur local fait bien le boulot mais si ces fichiers se retrouvaient chez un hébergeur, ils seraient totalement inexploitables.

Il va donc maintenant être nécessaire de les compiler afin de générer notre site statique prêt à l’emploi. Pour ce faire, il vous suffit de saisir la commande suivante :

hugo server

C’est tout ! Un répertoire public va alors apparaître dans l’arborescence. Il suffit de prendre son contenu, de le transférer chez un hébergeur tel quel et votre site sera fonctionnel.

Voilà, cette fois nous en avons vraiment terminé avec la présentation.

La partie technique n’a pas été des plus poussée mais mon but était plus de faire une initiation qu’une vraie présentation technique. En effet, la documentation de Hugo est assez bien faite pour pouvoir y retrouver ses petits. Je voulais plutôt vous inviter à vous pencher sur ce genre de techno.


Retour d’expérience

En tant que développeur, je ne me suis pas retrouvé confronter à trop de problèmes mais il est vrai que si je ne l’avais pas été, cela aurait été une autre paire de manches. Il faut régulièrement passer par l’utilisation de la ligne de commande, ce qui n’est pas trivial pour le commun des mortels.

En soit, la mise en place d’un thème sous Hugo se fait comme pour WordPress. Il s’agit beaucoup de paramétrage. Mais vu leur faible visibilité, les générateurs de sites statiques ont de la marge pour en proposer autant que WP.

Une fois les choses configurées, et qu’il n’y a plus que le contenu à gérer, les choses ne sont toujours pas si simples. L’apprentissage de Markdown n’est pas un problème en soi et générer du nouveau contenu ne l’est pas plus. En revanche, pour le côté versionnage, il faut utiliser un gestionnaire tel Git ou Subversion, ce qui n’est pas trivial pour un utilisateur non habitué à ces préceptes.

Un des plus gros problèmes, pour les non technophiles et pour l’automatisation, est qu’il n’y a pas d’interface centrale (du genre back-office) contenant les outils proposant les fonctionnalités de bases d’un gestionnaire de contenu (automatisation du redimensionnement d’images, versionnage, éditeur de texte …).

Avec toutes ces critiques négatives, vous devez penser que cela ne vaut pas le coup de passer à un générateur de sites statiques mais les choses évoluent très vites. Et en plus, s’il y a des critiques, c’est qu’il y a des choses à améliorer et que les choses vont changer.

Le futur

L’année qui vient de s’écouler a vu de nombreuses évolutions et les critiques que je présente ici, se trouvent gommées par certains acteurs, tel Netlify. Ils mettent à disposition un hébergement gratuit pour un site personnel, proposant cette interface centralisée que j’ai abordée, proposant leur propre CMS statique. Ils mettent aussi à disposition tout un tas d’autres options en rapport avec la génération de contenu statique.

Des méthodologies comme Jamstack sont de plus en plus en vogue et permettent de déléguer, tout ce qui est dynamique et que les sites statiques ne peuvent pas gérer, au navigateur via Javascript et ses API. La gestion de contenu peut s’effectuer via des CMS headless et rendre le versionnage transparent.

Si vous commencez à vous intéresser à ce sujet, vous verrez que ceci n’est qu’une infime partie de tout ce qui se passe autour des générateurs de sites statiques car le marché est en pleine ébullition. Aux vues des enjeux (sécurité, performances, …), je vous invite vraiment à vous pencher dessus, que ce soit en tant que simple utilisateur ou en tant que contributeur, qui sait.