Passer de WordPress à Jekyll – Deuxième partie

La semaine dernière, je vous ai présenté les raisons pour lesquelles j’ai changé le moteur de ce blog pour passer de WordPress à Jekyll. Le changement a été relativement simple, cependant j’ai tout de même rencontré quelques problèmes. Voici donc un petit guide pour vous aider à faire le transfert si vous le souhaitez.

Pour ceux qui ont encore des doutes, je vous invite à (re)lire mon premier article : Passer de WordPress à Jekyll – Première partie. Allez-y, jetez-y un coup d’oeil, je vous attends !

Prérequis

Avant de commencer, quelques bases.

  • Si vous choisissez Jekyll, vous devez être confortable avec l’utilisation de votre éditeur de texte. Choisissez le bon, et soyez-en sûrs, parce que vous allez passer encore plus de temps avec à partir de maintenant ! Un des paramètres importants selon moi est d’avoir des options d’auto-complétion : vous commencez à écrire un tag, il vous le termine. C’est aussi intéressant d’avoir un éditeur qui vous permet d’intégrer des snippets de code avec des raccourcis clavier. C’est le cas par exemple de Coda ou de Textmate.
  • J’ai déployé mon blog perso sur Github. Vous n’êtes pas obligés de le faire de cette façon, mais je ne vais pas couvrir le déploiement sur un autre serveur dans cet article. Si vous souhaitez héberger vos fichiers sur un serveur perso, je conseillerais d’utiliser Github tout de même, et ensuite d’utiliser leurs service hooks pour mettre à jour les fichiers sur votre serveur à chaque fois que vous poussez sur Github.
  • Puisque nous utilisons Github, je pars du principe que vous avez déjà créé une public key pour pouvoir push et pull sur Github facilement.
  • Dans ce tutoriel, je prends comme prérequis le fait que vous maîtrisez Git. Vous pouvez utiliser un autre système de gestion de versions, mais étant donné que nous déployons sur Github, ce serait un peu stupide d’utiliser autre chose.

Jekyll Skeleton, un thème pour votre sous Jekyll

Installer Jekyll sur votre machine

<h3<Installer la Gem Jekyll

La première étape est d’installer Jekyll sur votre ordinateur. En effet, la génération du blog, et le développement en général va se faire en local. Nous allons aussi en profiter pour installer les dépendances dont vous aurez besoin.

Jekyll est basé sur Ruby, il vous faudra donc avoir Ruby sur votre machine pour commencer. L’installation est ensuite très simple :

sudo gem install jekyll

Le package comprend aussi les premières dépendances, qui seront installées en même temps : liquid, le langage utilisé pour gérer vos templates, mais aussi Maruku, directory_watcher, open4, classifier.

Rdiscount, une meilleure option que Maruku pour vos articles avec Markdown

Vous devez déjà avoir décidé du markup que vous utiliserez pour vos articles. Que ce soit Textile, Markdown ou du simple HTML, nous avons tous nos favoris. J’utilise personnellement Markdown, et j’ai ajouté une option à mon installation Jekyll pour utiliser Rdiscount plutôt que Maruku (le package et l’option de base délivrée avec Jekyll pour interpréter markdown).

Pour cela, il vous faudra donc installer RDiscount sur votre machine :

sudo gem install rdiscount

Pygments

Pygments est une librairie basée sur Python, vous permettant de mettre en valeur vos insertions de code correctement. Jekyll et Liquid vous permettent d’insérer votre code très facilement dans vos articles, mais aussi de colorer celui-ci correctement de numéroter vos lignes.

A chaque insertion, vous pouvez préciser le langage de ce code, et avec le paramètre lineos, vous pouvez numéroter vos lignes.

Pour installer Pygments sur votre machine, rien de plus simple :

sudo easy_install Pygments

GSL, pour générer votre site plus rapidement

Lorsque vous lancerez jekyll pour la première fois, vous recevrez comme moi le message suivant pendant le build :

Notice: for 10x faster LSI support, please install http://rb-gsl.rubyforge.org/

LSI est une option de Jekyll qui vous permet de générer une liste d’articles relatifs à chacun de vos articles, pour les afficher au bas de chacune de vos pages. Malheureusement, la génération de cette liste ralentit la génération de votre site. C’est là que GSL intervient, pour accélérer la génération du site. Pour cela, il vous suffit d’installer :

sudo gem install gsl

Créer un repository sur Github pour votre site

Une fois que Jekyll est prêt sur votre machine, nous pouvons créer la base de votre site sur Github. Afin de vous faciliter la tâche, j’ai créé une base de site Jekyll, disponible ici :

Comme vous pouvez le voir, c’est une base très simple, mais vous allez pouvoir vous baser sur ce produit, et l’étendre pour créer votre propre site. En utilisant le Less Framework pour le CSS, je me suis assuré que cette base s’adaptait à toutes les tailles de navigateur. Essayez donc de réduire la taille de votre fenêtre pour voir la taille du site d’adapter :)

Commencez donc par forker cette base pour créer votre propre repo :

Forker sur GitHub

Puisque vous allez utiliser les Github pages pour héberger votre site, nommez votre nouveau repo de la manière suivante : votre-username.gthub.com

Une fois que c’est fait, vous allez pouvoir cloner ce repo sur votre machine en local, afin d’effectuer les changements.

Créez votre repo en local, et votre site en local

Première étape : cloner votre projet sur votre machine, en utilisant l’adresse donnée par GitHub sur la page de votre repo (exemple ici avec mon repo de base) :

Cloner Jekyll Skeleton sur votre machine

	git clone [email protected]:votre-username/le-nom-de-votre-repo.git

Avoir avoir cloné le repo, il vous faut tout de même ajouter un remote supplémentaire afin de rester au courant des changements et bugfixes que j’apporterai sûrement avec le temps ! Cela vous permettra aussi de proposer d’éventuelles pull requests, je suis preneur :)

cd jekyll-skeleton
git remote add upstream git://github.com/jeherve/jekyll-skeleton.git
git fetch upstream

Petit rappel, vous pouvez donc aller chercher les mises à jour de la base à n’importe quel moment en éxécutant un simple git fetch upstream. Si les changements vous plaisent, il vous suffira de les merger avec votre master.

Une fois que c’est fait, passons donc en revue tout ce que vous avez dans ce repo, et ce que vous allez devoir changer.

Examen des différents composants du site

Eléments de base

Commencons par les éléments les plus importants :

Le dossier _layouts, et l’organisation en templates de Jekyll

Ce dossier contient les templates de base de votre site. Le fichier layout.html est le fichier de base pour le moment, celui à partir duquel un grand nombre des pages de votre site seront générées. En effet, grâce au YAML front matter, un en-tête que vous allez rajouter à chacun de vos fichiers, vous allez définir quel template utiliser pour ce fichier. Cela va donc vous permettre d’utiliser des structures différentes pour différentes pages, un design différent…

Dans notre cas, layout.html est le layout de base, et post.html est utilisé comme layout pour les articles. Comme vous pouvez le voir, post.html possède lui aussi un en-tête, comme suit :

---
layout: layout
---

Cela veut tout simplement dire que le fichier post.html utilise le layout layout comme défaut.

index.html

Ce fichier est la page d’accueil de votre site. Il fait lui aussi partie du système de templates.

_config.yml

Ce fichier es l’un des plus importants pour votre site, car il détermine la manière dont Jekyll va être éxécuté. Il contient deux types d’information : d’une part, les paramètres d’éxécution de Jekyll. En effet, lorsque vous lancez la génération de votre site, vous pouvez préciser un grand nombre de paramètres différents dans la ligne de commande que vous lancez. Et si vous souhaitez éxécuter certains de ces paramètres à chaque fois que vous lancez la génération, il vous suffit de les ajouter à _config.yml pour qu’ils soient toujours pris en compte.
D’autre part, vosu pouvez y ajouer votre propres paramètres, auxquels nous ferons appel dans les templates.

CNAME

Ce fichier vous est utile lorsque vous hébergez votre site Jekyll sur Github, et que vous souhaitez utiliser votre propre nom de domaine plutôt que le sous-domaine de github.com. Une fois que votre site est généré sur GitHub, vous pouvez spécifier votre domaine dans ce fichier, et ensuite ajouter un nouvel enregistrement CNAME pour ce domaine pointant vers votre-username.github.com.

Vos articles

Tous vos articles sont situés dans le dossier _posts, avec le markup que vous choisissez. On y reviendra tout à l’heure pour y ajouter nos articles importés depuis WordPress.

Si vous ouvrez l’article exemple que j’ai fourni, vous pouvez voir que l’en-tête YAML front matter est plutôt bien fourni :

---
layout: post
title: Article test
meta-description: &quot;Description de cet article test.&quot;
categories: Jekyll
tags:
- Jekyll
- tutoriel
published: true
---

Chacun de vos articles devra comprendre cet en-tête avec toutes ces infos, puisque votre site y fera appel dans les templates.

RSS feed

Je ne peux que vous conseiller d’utiliser Feedburner pour votre feed RSS, et de proposer l’adresse de feed de Feedburner à vos utilisateurs, rien d’autre. Comme ça, si vous changez de CMS ou si vous changez l’emplacement de votre feed, si vous migrez votre site sur un nouveau domaine, il vous suffit ensuite de mettre à jour votre feed feedburner avec le nouvel emplacement du feed.

Dans le cas de notre install Jekyll, le feed est ici :

atom.xml

Votre sitemap, avec style

Un sitemap est essentiel à votre blog, listant vos pages (que vous devrez rajouter manuellement), et vos articles (qui viennent se rajouter à chaque fois que vous publiez un nouvel article). Et afin de donner un peu de style à celui-ci, j’y ai rajouté une feuille de style de base.

sitemap.xml
css/sitemap.xsl

Votre code, lui aussi stylé

Nous avons vu plus tôt que Jekyll utilise Pygments pour colorer les bouts de code que vous incorporez à vos articles. Cependant le style et les couleurs de chaque élement sont votre choix. J’ai donc incorporé à la base une feuille de style pour chaque langage géré par Pygments. Tout le mérite revient à Richleland pour ce travail !

css/syntax.css

Bien sûr, vous pourrez modifier cette feuille de style à votre convenance, en fonction de votre thème.

Le reste des fichiers est suffisamment clair je pense. Si vous avez des doutes, n’hésitez pas à me le dire en commentaires !

Modifier Jekyll Skeleton pour y apporter vos données

Maintenant que nous avons fait connaissance avec la bête, nous pouvons donc importer nos anciens articles et ajuster le tout pour pouvoir faire le switch en toute sécurité.

On va d’abord commencer par effectuer quelques changements à la base. Allez dans _config.yml, et changez les valeurs pour vos propres réglages, en fonction de votre site actuel. Pour les permalinks par exemple, référez-vous à cette page pour plus d’infos.

Une fois que c’est fait, faisons un test ! Ouvrez un terminal, placez-vous dans le dossier de votre site Jekyll, et lancez la commande suivante :

jekyll --server --auto

Vous allez donc voir votre site se générer, et une fois que c’est fait, vous pourrez accéder à votre site à l’adresse suivante : http://0.0.0.0:4000/ . La valeur server lance en effet le webserver fourni avec Jekyll, et la valeur auto permet de regénérer les pages de votre site que vous allez modifier sans avoir à relancer Jekyll à chaque fois.

Si vous êtes satisfaits du premier résultat, commitez les changements que vous avez fait, et passons donc à l’importation de vos anciens articles depuis WordPress.

Importer vos posts de WordPress

De nombreuses solutions existent, l’équipe de Jekyll en propose d’ailleurs certaines dans la documentation, je vous laisse donc choisir celle qui vous plaît le mieux. Personnellement, j’ai migré mes articles à partir du fichier d’export .xml proposé par l’exporter de WordPress et le script ruby suivant.

#!/usr/bin/env ruby

# Input: WordPress XML export file.
# Outputs: a series of Textile files ready to be included in a Jekyll site,
# and comments.yml which contains all approved comments with metadata which
# can be used for a Disqus import.
# Credits: @ecerulm https://gist.github.com/500506
# Changes from the original gist: http://gist.github.com/268428
# 1. Handles titles containing special characters. Those have to be YAML escaped 
# 2. Use the original permalinks in wordpress.

require 'rubygems'
require 'hpricot'
require 'clothred'
require 'time'
require 'yaml'
require 'fileutils'
require 'uri'

WORDPRESS_XML_FILE_PATH = &quot;#{ENV['PWD']}/wordpress.xml&quot;
OUTPUT_PATH = &quot;#{ENV['PWD']}/_posts&quot;
ORIGINAL_DOMAIN = &quot;http://example.com&quot;

class Post
  attr_accessor :title, :post_date, :created_at, :slug, :post_id, :content, :textile_content
  attr_accessor :hpricot_element, :permalink, :categories

  def initialize(item)
    @hpricot_element = item

    @title = item.search(&quot;title&quot;).first.inner_text
    @permalink = item.at(&quot;link2&quot;).inner_text.gsub(/^#{ORIGINAL_DOMAIN}/,'').gsub(//$/,&quot;/index.html&quot;)
    @permalink = URI.unescape(@permalink)
    puts &quot;permalink #{@permalink}&quot;
    
    @post_date = item.search(&quot;wp:post_date&quot;).first.inner_text
    @created_at = Date.parse(post_date)

    @slug = item.search(&quot;wp:post_name&quot;).first.inner_text
    
    @categories = []
    item.search(&quot;category&quot;).each { |cat| 
      @categories &lt;&lt; cat.inner_text
    }
    @categories.uniq!
    
    p @categories

    @post_id = item.at(&quot;wp:post_id&quot;).inner_text

    @content = item.search(&quot;content:encoded&quot;).first.inner_text
    text = ClothRed.new(content)
    @textile_content = text.to_textile
  end

  def to_jekyll
    buf = &quot;&quot;
    buf &lt;&lt; &quot;---n&quot;
    buf &lt;&lt; &quot;layout: postn&quot;
    buf &lt;&lt; &quot;title: #{title.to_yaml.gsub(/^--- /,'')}&quot; #escape character in title
    buf &lt;&lt; &quot;permalink: #{permalink.to_yaml.gsub(/^--- /,'').chomp}n&quot;
    buf &lt;&lt; &quot;post_id: #{post_id}n&quot;
    buf &lt;&lt; &quot;categories: #{categories.to_yaml.gsub(/^--- /,'').chomp}n&quot;
    buf &lt;&lt; &quot;---nn&quot;
    buf &lt;&lt; textile_content
  end

  def save(root_path)
    File.open(&quot;#{root_path}/#{created_at}-#{slug}.textile&quot;, &quot;w&quot;) { |file| file.write self.to_jekyll }
    self
  end

  def save_comments(path)
    comment_elements = @hpricot_element.search(&quot;wp:comment&quot;).reject do |c|
      c.search(&quot;wp:comment_approved&quot;).inner_text != &quot;1&quot;
    end

    File.open(&quot;#{path}/comments.yml&quot;, &quot;a&quot;) do |yaml_file|
      comment_elements.collect { |el| Comment.new(self, el) }.each { |comment| comment.write_to yaml_file }
    end
  end

  class &lt;&lt; self
    def parse(element, path)
      return nil unless element.is_a?(Hpricot::Elem)
      post = Post.new(element)
      puts &quot;saving post: #{post.title}&quot;
      post.save(path)
    end
  end
end

class Comment
  attr_accessor :author_name, :author_email, :author_url, :content, :post

  def initialize(post, element)
    @post_id = post.post_id
    @post_title = post.title
    @author_name = element.search(&quot;wp:comment_author&quot;).first.inner_text
    @author_email = element.search(&quot;wp:comment_author_email&quot;).first.inner_text
    @author_url = element.search(&quot;wp:comment_author_url&quot;).first.inner_text
    @content = element.search(&quot;wp:comment_content&quot;).first.inner_text || &quot;&quot;

    comment_date = element.search(&quot;wp:comment_date_gmt&quot;).first.inner_text
    @created_at = Time.parse(&quot;#{comment_date} GMT&quot;)
  end

  def write_to(file)
    file.write self.to_yaml + &quot;n&quot; unless @content.size == 0
  end
end

# main

file = File.open(WORDPRESS_XML_FILE_PATH,&quot;rb&quot;);
contents = file.read
# Hpricot will destroy &lt;link&gt; contents as it expecting a &lt;link href=&quot;&quot;&gt;
# so we change link to link2 and Hpricot will leave it alone. 
contents.gsub!(/link&gt;/, &quot;link2&gt;&quot;) 



doc = Hpricot(contents)

FileUtils.mkdir_p OUTPUT_PATH
File.open(&quot;#{OUTPUT_PATH}/comments.yml&quot;, &quot;w&quot;) { |f| }

(doc / &quot;item&quot;).each do |item|
  next unless item.search(&quot;wp:status&quot;).first.inner_text == &quot;publish&quot;
  post = Post.parse(item, OUTPUT_PATH)
  post.save_comments(OUTPUT_PATH)
end

Il vous suffit de placer le fichier .xml de WordPress et le script dans le même dossier, de modifier le script pour l’URL de votre site, et ensuite de le faire tourner. Une fois que c’est fait, tous vos articles sont disponibles dans le dossier _posts/ qui a été créé. Il vous suffit de le copier dans le dossier de votre site, et de regénérer Jekyll une nouvelle fois. N’oubliez pas de supprimer mon article de test avant, vous n’en aurez certainement pas besoin !

Si vous êtes satisfaits du résultat, un nouveau commit est de rigueur ! :)

Modifer les chemins URL de vos images si nécessaire

Suivant votre installation de WordPress, il est possible qu’il soit préférable de changer le chemin URL de vos images. Par défaut, il sera sûrement de la forme wp-content/uploads/...

Deux solutions s’offrent à vous : soit vous crééz un dossier wp-content/uploads à la racine de votre site Jekyll, dans lequel vous venez copier toutes vos images, soit vous changez le chemin de toutes vos images dans tous vos articles. A vous de voir. Personnellement, mon installation WordPress était multisite auparavant, mes images se situaient donc dans un dossier files/, ce qui me convient très bien. Je n’ai donc rien changé de ce côté-là.

Importer vos commentaires

Comme je le disais dans la première partie de cet article, l’un des inconvénients de Jekyll est l’absence de gestion des commentaires. C’est aussi ce qui fait sa force puisque le chargement des pages est d’autant plus rapide, mais si vous souhaitez garder vos pages ouvertes à la discussion, il vous faudra réfléchir à une alternative.

Après avoir regardé les différentes solutions possible, je me suis très vite reporté sur Disqus pour plusieurs raisons :

  • Le plugin WordPress de Disqus est très bien intégré, et vous permet d’importer vos commentaires existants sur WordPress en quelques minutes.
  • Il était hors de question pour moi de ne proposer que Facebook comments, d’une part parce que je ne souhaitais pas limiter les commentaires aux personnes ayant un compte Facebook, d’autre part parce que mon expérience avec l’API de Facebook ne me donne pas confiance pour les laisser gérer mes commentaires.
  • Je souhaitais avoir quelque chose de simple à gérer, et qui pourrait permettre aux gens de choisir avec quel compte commenter : anonymement, via Twitter, via Facebook
  • Même si la possibilité de laisser les gens soumettre une pull request dans mon repo avec leur commentaire semble marrante, en pratique je suis sûr que personne ne le ferait (je ne le ferais pas moi-même, ce qui est un bon critère d’élimination.

Je me suis donc tourné vers Disqus. J’ai commencé par installer le plugin sur mon blog WordPress, et j’ai suivi les étapes pour importer mes commentaires existants. Une fois que ceci était fait, il m’a suffit d’insérer le code dans mon template post Jekyll, et voilà : rien d’autre à gérer ! Je ne peux donc que vous conseiller cette alternative.

Commit, push, et le site est live !

Une fois que les commentaires sont impotés, que vos articles sont tous sur votre machine avec des URLs similaires à ce que vous aviez sous WordPress, et que vous êtes satisfaits du look de votre site, le temps est venu de passer en live ! Il vous suffit donc de commiter tous vos changements, et d’une simple commande tout passer en live sur votre site vore-username.github.com*.

git push

Et voilà ! Un dernier détail cependant : rediriger votre domaine vers votre nouvelle installation. Pour ça, rien de plus simple : dans l’interface d’administration de votre domaine, il vous suffit de créer un nouvel enregistrement CNAME, avec comme valeur votre-username.github.com. Attendez que les changements se propagent, et vous pouvez commencer à en parler autour de vous !

Conclusion : résultat, et ce qui manque

Mon site tourne désormais donc entièrement grâce à Jekyll, et est hébergé sur GitHub. Les premières semaines d’utilisation ont été intéressantes : les derniers articles que j’ai écrits sont tous passés par Jekyll, et je dois dire que j’y ai pris plaisir. Combien de temps cela va durer, je ne sais pas, mais je préfère cette manière d’écrire. Etant donné que la plupart de mes articles prennent un peu de temps à écrire, et que je n’utilisais pas les apps pour mobile de WordPress, cela me convient tout à fait.

Qu’est ce qui me manque ?

L’une des premières choses qui m’ont manqué est l’absence de gestion des catégories et des pages de tags. J’ai cherché des solutions pour y remédier, et j’ai trouvé des solutions intéressantes, mais pour le moment, je n’ai rien déployé en live. Je souhaite profiter de cette occasion pour revoir mes pages catégories pour leur donner plus d’utilité, et les rendre vraiment intéressantes pour ceux qui arrivent sur ces pages directement depuis Google. A voir dans le futur donc !

Autre élément manquant : un formulaire de contact. J’ai toujours fonctionné avec des formulaires de contact plutôt que de laisser mon adresse en clair sur le web, notamment par peur des spammeurs. Je suppose que je pourrais trouver une solution de rechange, mais je n’ai pas fait trop de recherches sur le sujet pour le moment. Si vous avez des idées, je suis donc preneur !

C’est donc terminé pour cet article qui commence un peu à traîner en longueur. A vous de jouer maintenant ! Si vous avez des questions, n’hésitez pas à m’en faire part en commentaires, et si vous vous lancez dans le switch, dites-le moi, je suis curieux ! Posez donc l’URL de votre site une fois que vous avez migré !

5 replies on “Passer de WordPress à Jekyll – Deuxième partie”

Mère Teresa says:

Pourquoi ne pas proposer de te contacter par twitter ?

Jeremy says:

Me contacter par twitter comme système de commentaires tu veux dire ? Le problème, c’est que je n’aurais pas d’historique des conversations twitter à propos de cet article par la suite. Mais tu as raison, je pourrais mettre twitter plus en avant en fin d’articles.

Je vais modifier Jekyll Skeleton dès que possible pour une meilleure intégration de twitter !

[…] à jour : la seconde partie de cet article avec les détails pour passer de WordPress à Jekyll est en ligne. Si vous êtes déjà convaincu et que vous souhaitez switcher, je vous conseille de […]

MoOx says:

Pourquoi ton site n’est plus sous Jekyll après ci peu de temps ?

Jeremy says:

Je suis du genre a experimenter beaucoup de choses, et j’avais envie d’essayer WordPress.com, qui est une solution en relation avec mon boulot actuel, c’est tout !

Jekyll reste une super solution a mon avis, si tu es devant ton ordi la plupart du temps, et que tu as donc accès à un terminal et un éditeur HTML pour poster.

Le seul désavantage de cette solution est qu’elle ne permet pas de poster depuis un mobile, ce que des CMS comme WordPress permettent très facilement.