J'ai récemment effectué la migration de ce site internet du CMS WordPress au générateur de site statique Middleman. J'explique dans cet article mes motivations, la marche à suivre pour faire cette migration et livre mes impressions sous forme d'un premier bilan.

Pourquoi quitter WordPress ?

Disclamer : J'utilise WordPress au quotidien, pour mes besoins personnels sur d'autres projets et pour des sites clients et l'outil répond parfaitement à ces différents besoins.

Le choix de cette migration vient d'ailleurs. L'activité du site n'est pas soutenue, en nombre de publications ou autres. Pourtant WordPress m'obligeait à une certaine maintenance : update des plugins, de Wordpress, vérifications que rien ne casse, alerte du plugin de sécurité qui tendait à devenir disproportionnée par rapport à mon nombre de connexions à l'admin pour rédiger un article ou mettre à jour du contenu.

L'idée de migrer vers une solution zéro maintenance me plaisait beaucoup et me ferai mieux dormir les nuits où on te couche en ayant entendu parler de failles de sécurité dans un plugin qu'on utilise.

L'autre raison est un peu plus geeky :) J'ai démarré le ruby et Ruby on Rails il y a quelques temps. J'ai découvert pas mal de choses qui me correspondaient plus en terme de workflow et qui n'étaient pas tout à fait applicables à un projet Wordpress. Parmi ces choses il y a Slim, un langage de templating qui une fois adopté rend compliqué le retour au html standard et ses chevrons :) Big up à @cecilitse et @_flexbox

J'avais donc envie d'un système sans maintenance, sans base de données, rapide, dans lequel je pourrai retrouver des morceaux de Rails comme l'asset pipeline, des vues en Slim, du markdown… Après de brèves recherches le candidat retenu fut Middleman

Middleman, un générateur de site statique

Middleman est donc un générateur de site statique qui n'utilise que des fichiers .html. Ca ressemble beaucoup au début du web mais ne nous y trompons pas, il y a en amont tout un système qui rend le développement et la publication agréables. (pas question de reprendre les fichiers un à un pour changer un mot dans le footer par exemple)

Il existe une quantité importante de générateurs de site statique, le choix de middleman c'est fait sur quelques critères très simples : c'est du ruby, c'est bien documenté, ça vient des petits gars de chez Toughtbot et j'aime leurs produits (Bourbon, Neat) :)

Comment ça marche ?

Tout va se passer en local à l'aide du terminal, d'un éditeur de texte et de quelques lignes de commande. L'étape d'installation passée, on a un squelette de site auquel on va ajouter nos fichiers. On crée principalement des fichiers au format .html.erb pour pouvoir embarquer du ruby et exécuter du code. (.html.slim si on utilise Slim).

Middleman embarque un grand nombre d'helpers qui vont faciliter l'affichage de différentes variables, d'images ou de liens. Il permet également l'utilisation de layouts et de partials, facilitant la réutilisation de fragments de pages pour en composer de nouvelles.

Une fois le site terminé en local, on procède au build du site et on se retrouve avec un dossier dans lequel ne figurent que des fichiers html 'compilés', prêts à être mis en ligne.

Quels avantages ?

Le premier avantage c'est qu'un site statique n'a pas besoin de générer ses pages avant de les envoyer au navigateur, on gagne donc en rapidité (un bon plugin de cache permet d'approcher cette rapidité).

Le second c'est qu'il n'y a plus de base de données qui pourrait être corrompue, plus de page de login prise d'assaut par des robots, bref on peut avoir l'esprit tranquille.

Le troisième c'est qu'il a des besoins en hébergement très modestes. On peut par exemple directement l'héberger sur github-pages et profiter de sa gratuité.

Les autres avantages sont au niveau workflow. Niveau versionning je dois toujours jongler un peu avec WordPress, entre le thème, les plugins tiers, les plugins persos et le contenu qui se trouve en ligne en base de données et plus en local. Avec une solution comme Middleman, le codebase est centralisé, et je préfère ça.

Niveau développement front-end, j'ai deux workflows avec WordPress, l'un où j'utilise CodeKit pour son LiveReload performant, la compilation des fichiers SASS, les concaténations, minifications avant la mise en production. L'autre où j'utilise Gulp pour les mêmes choses et deux ou trois autres fonctions.

Middleman intègre nativement ces fonctions ou permet de les ajouter grâce au gems, je n'ai donc pas à m'en soucier et gagne donc du temps.

Sauvegarder une dernière fois son WordPress

On y va ! Je récupère un dernier_backup_ de ma base de données WordPress, et je copie tout mon ftp pour en garder une sauvegarde. Le dossier dans lequel était placé mon site sur mon hébergement sera ensuite vidé pour accueillir le build middleman.

Middleman, installation, gemfile et choix techniques

Middleman nécessite d'avoir Ruby et Rubygems d'installés sur son poste ainsi que quelques outils en ligne de commande. Supposant que tout soit bon à ce niveau, il suffit de faire un simple :

gem install middleman

L'installation faite, on se place dans notre dossier de travail et on peut rapidement démarrer un nouveau projet avec cette commande :

middleman init nom_du_projet

Dans le dossier crée au nom du projet on aura un certain nombre de fichiers (le présent article n'étant pas un tutoriel, je ne vais pas tous les expliquer). Parmi eux Gemfile et config.rb. Dans le premier, on va indiquer les gems que l'on souhaite utiliser pour le projet. Dans le second on va simplement les configurer.

Ci après la liste des gems que j'utilise pour ce site, dont certains sont installés par défaut :

  • middleman: la base
  • middleman-blog: l'extension pour gérer la partie blog et folio
  • middleman-livereload: recharge la page dans le navigateur à chaque sauvegarde
  • middleman-autoprefixer: ajoute les préfixes navigateurs utiles
  • middleman-syntax: permet d'afficher des blocs de code
  • middleman-protect-emails: crypte les liens emails
  • middleman-google-analytics: ajoute le script google analytics
  • middleman-deploy: facilite le déploiement du site
  • middleman-dotenv: permet d'ajouter un fichier .env
  • middleman-sitemap: génère le sitemap
  • middleman-favicon-maker: automatise la création de favicon
  • slim: pour écrire les vues en Slim
  • bourbon: librairie de mixins SASS
  • neat: grille responsive qui repose sur Bourbon

Conversion du site vers middleman

La base étant prête, il faut maintenant réécrire ou adapter mon thème WordPress et y réintégrer les différentes pages et articles.

De MySQL à YAML

Dans WordPress tout était stocké dans la base donnée, du nom du site, au contenu des articles en passant pour les options de configuration et ou les champs personnalisés et leur contenus. Middleman n'utilise pas de base de données type MySQL mais permet de stocker des informations similaires dans des fichiers YAML situés dans le dossier /data mais également dans les entêtes des fichiers grâce à Frontmatter.

Dans le cas présent, j'utilise un fichier dans /data contenant les informations relatives au site, à mes réseaux sociaux, google analytics… Et par exemple, pour un article de blog, je place dans l'entête le titre de la page, le titre seo, la meta description, le thumbnail à utiliser, la catégorie…

On accède ensuite très simplement à ces infos dans les vues ou fichiers ruby :

# Récupère le code GA dans le fichier settings.yml
ga.tracking_id = data.settings.google_analytics.tracking_code

# Affiche le titre de la page en Slim
= current_page.title

Quoi qu'un peu déroutant au début, ce système permet une grande liberté dans la manière d'architecturer ses données et se révèle rapidement très efficace.

De php/html à Slim

On arrive à la partie que j'ai le plus aimé lors de cette migration, transformer mon thème qui comportait des pages en php/html mélangés en Slim. Je ne vais pas faire une présentation complète de Slim, (la documentation est bien faite) mais juste illustrer par un bout de code à quoi ça ressemble dans le cas de l'affichage d'un article :

main.site__container
    .post__header
      h1.post__title
        / Affiche le titre
        = current_page.title

  article.blogpost role="main"
    ul.blogpost__meta
      / Affiche les métas
      li.blogpost__meta--date
        | Article plublié le
        = current_page.date.strftime('%d %B %Y')
        '  dans
      li.blopost__meta--categorie
        - current_page.tags.each do |tag|
          = link_to tag, tag_path(tag)
    / Affiche le contenu de l'article 
    == yield

Slim permet un énorme gain de temps car il n'y a ni chevrons pour les balise html ni balises fermantes. L'ajout de code ruby se fait à l'aide de signes comme - ou = et étant donné qu'il utilise une indentation stricte, si on indente mal, ça ne compile pas et on sait tout de suite où est l'erreur.

Comme dit plus haut, Middleman utilise un système de layout et de partials pour composer les pages, j'ai donc pu facilement recréer mon thème en le découpant plus ou moins de la même façon que dans WordPress.

J'ai un layout pour les pages, un pour le blog et un pour le portfolio. Ce qui correspondrait aux pages index.php, single.php et single-portfolio.php dans WordPress.

J'utilise ensuite des partials pour les éléments répétés de pages en pages comme le header, le footer, les éléments de navigation…

Des articles en Markdown

Parmi les raisons de cette migration il y a avait la possibilité d'écrire mon contenu en Markdown. Il me semble qu'il existe des solutions pour écrire un markdown dans Wordpress mais il aurait fallut passer par un plugin, ici c'est natif !

J'utilise de manière générale assez peu l'éditeur visuel de WordPress, lui préférant l'éditeur texte intégré qui permet, à mon sens, un meilleur formatage. Désormais je ne quitte plus mon éditeur de code en local et je ne me soucie plus des balises, du formatage, de l'admin de WordPress ou des prévisualisations.

Je mets côte à côte mon éditeur et la page de mon site en local, je tape en Markdown et à chaque cmd + S, le livereload intégré rafraichit la page. C'est top !

N'ayant pas beaucoup de contenu à exporter et souhaitant en plus y faire quelques modifications, j'ai réadapté mes articles à la main. On peut largement se faciliter la vie avec un outil en ligne de commande qui s'appelle wp2middleman qui fera ça très bien.

Mettre son site en ligne avec middleman

La conversion n'a pas pris trop de temps, un peu plus de 2 jours, en passant la plupart du temps dans la doc ou dans les dépôts github de projets middleman pour comprendre comment ça marche. Puis essais, erreurs, corrections, essais… Bref, le site fonctionne comme il faut en local.

L'étape de build

Pour le moment, le site réside dans le dossier /source du projet et on ne voit en local (http://localhost:4567) que l'interprétation de nos fichiers Slim. Il faut donc passer par l'étape de build qui va compiler les sources en fichiers html.

Cette étape se fait en une seule commande mais on va d'abord configurer le build dans le fichier config.rb pour indiquer à Middleman ce qu'on attend de lui. En l'occurrence : activer la minification des fichiers, la concaténation des .js, la compression gzip, l'usage de liens relatifs, la génération des images pour le favicon et le sitemap. Puis, en ligne de commande :

middleman build

J'ai omis les extensions d'optimisation d'images et création de thumbnails car je le fais en amont mais elles peuvent être ajoutées pour compresser et recadrer les images.

Le déploiement

Après le build, on se retrouve avec un nouveau dossier /build qui contient les fichiers qui seront en production. Il faut maintenant déployer le site vers le serveur. J'utilise pour ça la gem middleman-deploy qui permet de déployer automatiquement via rsync, ftp, sftp ou git si on utilise Github Pages. De la même manière, il existe aussi des extensions pour déployer vers AWS, BitBallon…

Dans mon cas, je continue d'utiliser mon hébergement mutualisé et me sert de sftp pour le moment. Pour cela il suffit simplement de configurer la connexion dans le fichier config.rb et de lancer la commande suivante :

middleman deploy

Il ne reste plus qu'à suivre l'avancée du transfert dans le terminal. Après quelques secondes, minutes selon la taille du site, il se retrouve en ligne !

Update en une ligne de commande

Le site est à nouveau en ligne et fonctionnel. Comment le mettre à jour, ajouter de nouveaux articles, du contenu, ou effectuer des modifications ?

C'est très simple, on crée un nouveau fichier dans le dossier source, article de blog, nouvelle page ou entrée dans le portfolio, on vérifie que tout est bon dans le navigateur en local et on tape la ligne de commande qui suit et on passe à autre chose.

middleman build && middleman deploy

Optimiser son site généré avec middleman

J'avais essayé d'optimiser mon site au mieux avec WordPress, en utilisant différents plugins pour le cache, la minification. Je chargeais mes .js dans le footer; les images en lazyload… En utilisant des outils de tests de performances comme GTmetrix, Pigdom Tools ou WebpageTest, j'avais des résultats plutôt, au dessus de 90.

Pas de gros changements en passant à Middleman sinon qu'il a fait tout le travail tout seul. En testant à nouveau sur ces mêmes outils les notes d'appréciation se tiennent, le temps de chargement est par contre un poil plus rapide et c'est en partie ce que je voulais.

Pour le défi ou challenge que ça représente, j'irai bien essayer de décrocher le 100% prochainement. Je pourrais commencer par externaliser les images sur un cdn ou dans un sous-domaine pour paralléliser les téléchargements. Ca fera plaisir à Yslow et Webpagetest.

J'ai des fichiers .png de petite taille, ça peut valoir le coup de les convertir en base64 pour éliminer quelques requêtes.

Je pourrais aussi réintégrer le lazy-load des images. Je ne l'ai pas remis car j'espérai trouver une solution sous forme de gem. Supprimer la dépendance Jquery serait aussi un plus…

Un premier bilan

Middleman demande une petite prise en main et même si la doc est bien faite, qu'il y a un forum et des gens sympas pour partager leur code, ça peut prendre un peu de temps avant d'être à l'aise. D'autant que cela remet en question pas mal de concepts quand on est habitué aux CMS classiques.

Une fois passé le cap, c'est franchement sympa, pour toutes les raisons évoquées plus haut! Même si comme pour tout, il y a quelques revers :

Le build && deploy c'est presque magique sauf quand il faut corriger un mot et qu'on doit recommencer l'ensemble. J'ai beau me relire, il y a toujours des fautes qui passent.

La gestion des images à la WordPress disparait et les solutions sous formes de gem ne m'ont pas forcément convaincu. J'utilise un petit utilitaire mac pour faire ça mais c'est moins rapide.

Comme il n'y a plus rien de dynamique, il est moins évident d'ajouter des éléments basés sur des formulaires. Ceci inclut le formulaire de contact pour lequel il m'a fallut trouver une parade et les commentaires de blog qui ont pour le coup disparus. On peut utiliser bien sûr des solutions comme Disqus, mais je n'ai pas souhaité le faire. Un email, facebook, un DM sur twitter ou un message privé sur Slack sera tout aussi efficace. L'article peut ensuite être mis à jour avec le fruit des discussions.

J'ai fait la migration du site à un moment où j'avais du nouveau contenu à publier en me disant que cela serait ça de moins à adapter par la suite. L'expérience en terme de rédaction / publication vécue pour le précédent article et celui-ci me plait bien. Je n'ai pas besoin de rédiger en mobilité. Et si d'aventures je devais le faire avec mon laptop je peux toujours faire un git pull pour récupérer facilement mon code source.

Bref, pour conclure je dirai simplement qu'il y a du bon à prendre dans middleman et que cela peut répondre à pas mal de projets, donc foncez !

Article précédent : Rails, des livres à la première application
Article suivant : Bureau debout (standing desk), mon hack Ikea

Je suis disponible pour des missions longues / CDD / CDI Cliquez pour en savoir plus