Au démarrage (vers 2012), ce blog était un site Wordpress. Bien que Wordpress soit très utilisé, maintenu, et bénéficie d’un écosystème très riche, c’est aussi une plateforme de publication assez lourde, surtout pour un blog personnel :

  • Il faut un serveur de base de données (MySQL)
  • Il faut avoir PHP d’installé

D’autre part, Wordpress inclut énormément de fonctionnalités qui ne sont absolument pas utile pour mon usage, et son extensibilité affecte également la sécurité de l’installation.

Au fil des années, et après avoir maintenu près d’une dizaine de site Wordpress (pour des clients, des ami·es, de la famille…), je me tourne depuis quelques années vers des solutions plus légères lorsque c’est possible.

Un blog statique avec Jekyll

Depuis deux ou trois ans, maintenant, eliotberriot.com est un site entièrement statique, basé sur Jekyll. Concrètement, au lieu de me connecter sur l’administration d’un Wordpress, Drupal ou autre pour écrire des articles, le contenu du site est stocké dans un dépôt Git.

J’ajoute et modifie le contenu en local, au format Markdown avec mon éditeur de texte favori, commite cela dans la dépôt et pousse le tout. Le serveur Gitlab sur lequel est hébergé le dépôt va ensuite construire puis servir le site statique en HTML à partir des fichiers Markdown en entrée, avec la configuration suivante:

image: ruby:2.3

pages:
  script:
  - bundle install --path vendor/bundle
  - bundle exec jekyll build -d public --config "_config.yml,_config.prod.yml"

  artifacts:
    paths:
    - public

  cache:
    paths:
    - vendor/

  only:
    - master

Cette configuration dit à Gitlab de construire mon site avec Jekyll, et de le déployer avec Gitlab Pages.

Un site statique c’est bien mais…

…Devoir travailler avec un éditeur de texte et git n’est pas toujours adapté ni possible. Typiquement, pour écrire une brève rapide, ou un article qui contient plusieurs images, ou depuis son téléphone, l’expérience n’est pas très agréable.

D’autre part, travailler en local avec Git est inaccessible pour la plupart des personnes.

Netlify-CMS entre en piste

Il y a quelques jours, ma mère m’a demandé si je pouvais lui faire un blog pour qu’elle publier ses textes. Ne voulant pas mettre en ligne et maintenir un énième site Wordpress, j’ai commencé à chercher de côté des solutions alternatives, plus légères, pour finalement me demander s’il n’était pas possible d’utiliser un CMS avec un site statique.

Et c’est possible ! Netlify-CMS est un projet qui fait exactement cela : fournir une interface web pour ajouter ou modifier le contenu d’un site statique. Le projet fonctionne avec Jekyll ou n’importe quel autre système de site statique.

Avant de proposer cette solution à ma mère, j’ai décidé de la tester sur mon blog personnel, et voici mon retour d’expérience.

Comment ça marche ?

En gros, Netlify-CMS est une application javascript qui va utiliser les informations de votre dépôt Git pour générer une interface d’administration.

Le dossier admin/

La première étape, c’est de créer un dossier admin à la racine du projet, qui contiendra un fichier index.html, comme suit :

<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Content Manager</title>
</head>
<body>
  <script src="netlify-cms.js"></script>
</body>
</html>

C’est la ligne <script src="netlify-cms.js"></script> qui est importante, car c’est elle qui charge le javascript nécessaire au fonctionnement de l’application.

Dans la documentation officielle, le script est référencé depuis un CDN, mais je préfère l’héberger moi même. En local, il me suffit d’exécuter curl -L -o admin/netlify-cms.js https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js pour avoir ce javascript, et et rajouter cette commande dans mon .gitlab-ci.yml pour bénéficier du script lors du déploiement.

Une fois ces fichiers créés, il est désormais possible de visiter https://eliotberriot.com/admin/.

Écrire la configuration requise pour Netlify-CMS

À ce stade, Netlify-CMS ne peut pas fonctionner, car il ne sait pas comment est structuré mon site, où se situent les sources, comment se connecter au dépôt Git, etc.

On doit donc écrire un ficher de configuration, dans admin/config.yml :

backend:
  name: gitlab
  base_url: https://code.eliotberriot.com
  repo: eliotberriot/eliotberriot.com
  auth_type: implicit
  app_id: <id_application_gitlab>
  api_root: https://code.eliotberriot.com/api/v4
  auth_endpoint: oauth/authorize

site_url: https://eliotberriot.com
media_folder: assets/posts
collections:
  - name: "blog"
    label: "Blog post"
    folder: "_posts"
    create: true
    slug: "---"
    preview_path: "blog////"
    preview_path_date_field: "date"
    fields:
      - {label: "Layout", name: "layout", widget: "hidden", default: "post"}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Publish Date", name: "date", widget: "datetime"}
      - {label: "Body", name: "body", widget: "markdown"}

Analysons cette configuration ensemble.

La partie backend (Documentation officielle) est celle qui indique à Netlify-CMS comment intéragir avec le dépôt Git :

backend:
  # Le type de backend. Dans mon cas, c'est gitlab, mais Netlify-CMS fonctionne aussi avec Github et Bitbucket
  name: gitlab
  # L'URL de mon instance Gitlab
  base_url: https://code.eliotberriot.com
  # Le nom du dépôt sur mon instance Gitlab
  repo: eliotberriot/eliotberriot.com
  # les paramètres pour la connexion entre Netlify-CMS et mon instance Gitlab. 
  auth_type: implicit
  app_id: <id_application_gitlab>
  api_root: https://code.eliotberriot.com/api/v4
  auth_endpoint: oauth/authorize

Pour que la connexion fonctionne, il faut créer une application Gitlab, récupérer l’id fourni par Gitlab et le placer dans la configuration.

Le reste de la configuration indique à Netlify-CMS comment est structuré votre site statique :

# L'adresse de votre site, pour affichage dans l'interface
site_url: https://eliotberriot.com
# Le chemin ou stocker les fichiers et images envoyés via le CMS
media_folder: assets/posts

# Les collections indiquent à Netlify-CMS les différents types de contenus 
# présents sur votre site qui sont affichés et éditables via l'interface. 
# La documentation complète est disponible sur 
# https://www.netlifycms.org/docs/collection-types/
collections:
  # Ici, je crée donc une collection "blog", qui correspond à mes articles de blog
  - name: "blog"
    # Label affiché dans l'interface
    label: "Blog post"
    # Dossier dans le dépôt Git où sont stockés les fichiers
    folder: "_posts"
    # Est-ce que la création de nouveaux contenus est possible, ou seulement la mise à jour de contenus existants ?
    create: true
    # le template à utiliser pour le nom des fichiers crées
    # avec le template ci-dessous, un article écrit dans Netlify-CMS
    # se retrouvera dans un fichier "2019-05-06-netlify-cms.md"
    slug: "---"
    # (optionnel) Le chemin à utiliser pour afficher le lien final de l'article
    preview_path: "blog////"
    preview_path_date_field: "date"
    # Les champs à afficher dans l'interface du CMS
    fields:
      - {label: "Layout", name: "layout", widget: "hidden", default: "post"}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Publish Date", name: "date", widget: "datetime"}
      - {label: "Body", name: "body", widget: "markdown"}

Le champ fields est particulièrement intéressant, car il contrôle les champs affichés dans l’interface du CMS. Les contenus saisis dans ces champs se retrouvent dans le frontmatter des articles, et sont donc directement utilisés par Jekyll (ou les systèmes de sites statiques compatibles).

Si votre thème Jekyll est capable d’utiliser une image d’en-tête sur les articles, vous pourriez rajouter un champ {label: "Image d'en-tête", name: "feature-image", widget: "image"} qui vous permettrait d’avoir un joli champ en HTML pour uploader votre image. Il existe de nombreux types de champs que vous pouvez utiliser pour adapter le CMS à votre site.

Déployer tout ça et profiter

Une fois que la configuration est écrite, il reste à la commiter au dépôt, et à essayer le tout.

Lorsque je visite https://eliotberriot.com/admin/, voici ce que j’obtiens :

Accueil de l'interface d'administration de Netlify-CMS

Un clic sur le bouton `Login with Gitlab` me renvoie bien vers mon instance Gitlab, ou je m’authentifie, puis je suis redirigé vers le CMS :

Accueil de l'interface Netlify-CMS, avec la liste de mes articles

Voici le rendu de l’éditeur pour cet article :

Éditeur d'article de Netlify-CMS

Et la galerie de média :

Galerie de média de Netlify-CMS

Comme vous pouvez le constater, le rendu est simple mais fonctionnel. Si on vérifie du côté de mon dépôt Git, on constate que les images uploadées via Netlify-CMS ont bien été commitées dans le dépot :

Capture d'écran des commits effectués par Netlify-CMS

Conclusion

Je suis assez satisfait par mes premiers tests et par la simplicité de configuration de l’ensemble. Au final, il suffit de copier/coller/adapter deux ou trois snippets pour avoir une interface fonctionnelle. Je conserve la possibilité de manipuler mon contenu en local, ou via Gitlab, ou n’importe quel autre outil de mon choix.

Je pense qu’il est possible d’industrialiser l’ensemble et de déployer en quelques minutes des sites statiques avec HTTPS sur Gitlab Pages, modifiables sans connaître Git, le tout dans un environnement totalement controlé, open-source, et avec une faible empreinte écologique (parce qu’un site statique pré-généré consomme beaucoup moins qu’un CMS).

Avec la connexion GitLab et l’intégration Git, il est du coup possible de travailler à plusieurs sur le même site sans problème, d’être alerté en cas de conflits, d’avoir une copie locale du site, de restaurer une version antérieure d’un article, etc. Et comme tout est stocké dans GitLab, il me suffit de backuper l’instance GitLab pour backuper tous les sites qui sont dessus !

Il y a eux points à prendre en compte cependant qui vont affecter l’expérience utilisateur.

Premièrement, Le CMS lui même n’est disponible qu’en anglais pour le moment. Visiblement, c’est un travail en cours, mais c’est à garder à l’esprit.

Deuxièmement, tomme Netlify-CMS fonctionne avec des sites statiques, cela implique qu’il y a un délai entre le moment où l’on clique sur le bouton “publier” dans le CMS et le moment où le contenu est effectivement publié. Dans mon cas, il faut environ 30 secondes pour que mon instance GitLab effectue le rendu et la publication avec Jekyll.

Dans un monde de l’instantané, cela ressemble à un retour en arrière. En pratique, c’est un peu déstabilisant au début, mais tout à fait gérable.

Pour conclure je ne pense pas que Netlify-CMS remplacera complètement mon éditeur de texte local, mais je trouve le projet extrêmement bien pensé et agréable à l’utilisation !