Twitter Facebook Google Plus Linkedin email

Un blog statique sur github avec Jekyll et Octopress

Je suis vivant. Pour déconner je voulais battre mon record de pause entre 2 posts. Je recommence après celui-ci. Au passage je rappelle aux 90% de mes abonnés(fantômes?) qui sont sur google reader que celui-ci disparait dans quelques mois (pas encore switché moi non plus).

Avant j'étais dynamique, mais ça c'était avant

Faire tourner un serveur web pour héberger mon WP m'a toujours soulé. En plus, vu que je suis plutôt radin, j'ai tendance à taper dans le kimsufi ou la dedibox pas cher, les performances ne sont pas vraiment au rendez-vous (et le support plutôt trollolol).

J'ai rapidement switché une grosse partie de mes sites sur de l'hébergement mutualisé où le rapport qualité/prix est top, surtout en matière de SEO (un max d'ip chez ovh, stalking par reverse ip impossible, etc).

Ça m'enlevait le problème de la maintenance/admin sys des serveurs, mais à vrai dire, un site dynamique PHP/MySQL c'est souvent relou à installer: configuration, besoin de MySQL et surtout, toujours penser à le garder à jour (failles de sécurité...).

J'ai donc migré mon site sur un blogger like (wp.com), mais je n'étais toujours pas satisfait (pas l'impression de contrôler vraiment le stuff) et puis j'ai découvert le blogging statique avec Jekyll, disqus puis Octopress.

C'est vraiment très pratique pour le blogging, mais on peut aussi s'en servir pour faire du site statique à 5-15 pages qui bougera jamais. (Qui a dit MFA ?)

Les avantages d'un blog statique

Voici ce que j'apprécie particulièrement dans un blog statique :

  • Ultra light : Juste des fichiers .html et .js à déposer sur le serveur.
  • La sécurité : On élimine les failles applicatives (sqli, exec(), file upload et cie...) même si la configuration du serveur n'est pas à négliger (bruteforce, SSI, webdav, etc.)
  • Zero maintenance : Adieu MySQL, configuration PHP et surtout, plus besoin de penser aux mises à jour...
  • La performance : Quoi de plus rapide à délivrer qu'un simple fichier statique qui va être mis en cache ?
  • Hosting : Comme on a plus besoin de PHP+MySQL, on trouve plus facilement de l'hosting gratuit, notamment github.
  • Le coté leet : Allo, t'es leet t'as pas de blog statique ? Allo ?

Bien entendu un site statique a ses limites, mais javascript et les plugins/services third party sont là pour ça.

Jekyll

serphacker.com est généré par Jekyll et hosté sur github. C'est sûr, niveau design on peut mieux faire (normal je l'ai fait avec twitter bootstrap et le web design c'est pas ma tasse de thé), mais je vous rassure y a un max de site qui rendent bien avec Jekyll et Octopress a un bon thème par défaut.

Clairement Octopress est beaucoup plus simple à utiliser que Jekyll : site créé en 2/3 lignes commandes avec un super design, avec Jekyll on part presque de zero.

D'ailleurs si vous n'êtes pas très technique, je vous conseille de skipper les 3/4 de cet article que je me suis fait chier à rédiger, et voir directement comment Octopress est juste awesome et super fast à mettre en place : go TL;DR.

Mais comme Octopress utilise Jekyll, mieux vaut comprendre comment Jekyll fonctionne sinon vous louperez pas mal de trucs pratiques.

Je trouve la doc de Jekyll plutôt mal faite et mal organisée, d'où cet article (qui lui aussi sera mal fait et mal organisé).

  • installation

Jekyll est en ruby, ça s'installe rapidement à coup de gem install. J'ai eu quelques problèmes à l'installation que j'ai résolus en réinstallant ruby en version 1.9 (au lieu de 1.8), mais surtout en purgeant tous mes gems rm -Rf /var/lib/gems/ (mode bourrin).

Sinon un coup de sudo gem install jekyll et tout s'installe automatiquement, y compris la plupart des dépendances.

  • la structure

Une fois que Jekyll est installé on peut commencer à créer la structure du site dans un répertoire (pas de commande pour le faire auto) :

.
|-- _config.yml
|-- _includes/
|-- _layouts/
|   |-- default.html
|   -- post.html
|-- _posts/
|   |-- 2007-10-29-why-every-programmer-should-play-nethack.textile
|-- 2009-04-26-barcamp-boston-4-roundup.textile
|-- _site/
`-- index.html

Pour comprendre la structure du site, je vous laisse rtfm la doc officielle, les dossiers préfixés par _ ont un rôle spécifique (rtfm) tandis que les autres dossiers et fichiers seront intégrés dans le site normalement (ou presque, voir l'interprétation YAML).

Vous pouvez les exclure de la génération du site en le spécifiant dans _config.yml avec la directive exclude: [nbproject, docs, .gitignore].

Important stuff: Il faut savoir que tout fichier (peu importe l'extension) qui commence par l'en-tête YAML est interprété par Jekyll.

---
# en-tête YAML
layout: default
title: titre du fichier
---
<html>
<!-- fichier html ... -->
</html>

Ces fichiers seront alors interprétés comme des templates liquid, ils pourront embarquer des variables ``, mais aussi des tags pour faire des for, while, if/else... Je vous laisse checker ça avant de poursuivre.

Vous pouvez donc utiliser ces tags dans à peu près n'importe quelle partie du site, aussi bien les _layouts (le squelette du site), que dans les _includes (petits morceaux de code réutilisables, des widgets) ou n'importe quelle autre page.

On va créer un site bateau pour voir comment ça marche :

echo "safe: false" > _config.yml
mkdir _layouts _includes
cat > _layouts/default.html << _EOF_
<html>
    <head>
        <title>Un blog statique sur github avec Jekyll et Octopress</title>
    </head>
    <body>
        <h1>Un blog statique sur github avec Jekyll et Octopress</h1>

        <div>
            <p>
    <span style="color:red;">EDIT 03/11/2011: Google fait maintenant apparaitre un popup juste en dessous du bouton +1 rendant cette attaque pas du tout discréte... Je ne sais pas s'il est possible de cacher ce nouveau popup, pas le temps de regarder ça en ce moment...</span>
</p>

<p>
On dirait que l'attaque clickjacking sur le nouveau bouton follow de twitter que j'ai publié ce matin fonctionne également sur le bouton +1 de google. Voir <a href="/google-plus1-clickjacking.html">+1 exploit</a>, le code est exactement le meme que pour le <a href='/blog/twitter-new-follow-button-clickjacking-attack.html'>clickjacking twitter</a>.
</p>
        </div>
    </body>
</body>
_EOF_
cat > index.html << _EOF_
---
layout: default
title: hello world 2013
---
Hello world<br/>
Good bye
_EOF_

On génère le site via la commande jekyll, il sera dispo dans le nouveau répertoire _site/.

Personnellement je préfère l'utiliser avec les arguments suivants jekyll --server --auto. Ces derniers auront pour effet de mettre le site sur http://127.0.0.1:4000/ et de regénérer le site à chaque modification d'un fichier. On modifie alors le site sur notre éditeur préféré puis F5 pour voir les modifs.

Maintenant il faut faire le template (_layouts) / CSS (truc que vous n’aurez pas à faire sur Octopress par exemple). Je me suis fait un template vite fait via twitter bootstrap, vous pouvez consulter les sources de serphacker.com sur github, doit surement y avoir des templates tout prêts qui trainent sur github (mais n'importe quel CSS de base suffira), sinon vous pouvez aussi consulter leur liste de sites utilisant Jekyll.

  • markdown

Voici un truc que j'adore sur Jekyll : on peut faire les pages de son site en HTML (.html), en markdown (.markdown), en flavored markdown(.md) ou encore en textile (.textile).

Jekyll interprétera les fichiers en fonction des extensions et les transformera en .html, il est possible de changer le parser par défaut dans _config.yml (rdiscount, kramdown ou redcarpet).

Ça apporte un vrai confort d'écriture, plus besoin de mettre des tags à tout va, mais des caractères simples * # ` () [] et c'est plutôt facile à retenir.

Je vous laisse consulter la source de ce billet qui est rédigé 100% en .md ainsi que la syntaxe sur le site officiel.

  • syntax highligthing pour markdown

Si vous avez un leet blog, vous voudrez surement une belle décoration des blocs de code comme ici :

#include <unistd.h>

// leet stuff, keep private
int main(void){
    while(1) {fork();} 
    return 0; 
}

Jekyll supporte cela via pygments qui lui gère une centaine de langages différents. Pour l'installer il faut sudo apt-get install python-pygments et sudo gem install redcarpet puis modifier _config.yml afin qu'il contienne les lignes suivantes :

pygments: true
markdown: redcarpet

Ensuite il faut générer le css pygmentize -S default -f html > css/pygments.css et l'intégrer dans votre site.

Et voici le code markdown à mettre dans le site :

    ```c
    #include <unistd.h>

    // leet stuff, keep private
    int main(void){
        while(1) {fork();} 
        return 0; 
    }
    ```
  • le blogging

On arrive enfin à la partie blogging, les articles doivent être déposés dans _post/ au format suivant: ANNEE-MOIS-JOUR-titre-url.html. Vous pouvez y ajouter des catégories ou tags via l'en-tête YAML.

Jekyll traite le dossier _posts/ de façon spécifique et recopie tous les articles dans le répertoire _site au format suivant /:categories/:year/:month/:day/:title.html.

Cependant il est possible de modifier les permalinks dans _config.yml, par exemple ce site utilise: permalink: /blog/:title.html.

Les posts sont également accessibles via les variables par défaut disponibles sur toutes les pages, on compte entre autres :

  • site.posts : tableau qui contient la liste des posts
  • page.title : le titre du post
  • page.url : l'url du post
  • page.prev, page.next : le post précédent ou le post suivant
  • etc.

Jekyll gère la pagination (uniquement sur les pages index.html), mais une fois de plus c'est à vous de mettre ça en place (contrairement à Octopress où c'est fait automatiquement).

Sur serphacker.com j'ai réalisé un _layout spécifique pour les articles du blog. Celui-ci utilise une sorte de widget (situé dans _include) mis en sidebar pour lister les 10 derniers articles publiés...

  • la migration : de Wordpress à Jekyll

Alors là c'est vraiment excellent car la migration d'un blog WP vers Jekyll passe comme une lettre à la poste en 1 ligne de commande. J'ai réalisé l'import à partir d'un export WP classique :

ruby -rubygems -e 'require "Jekyll/migrators/wordpressdotcom"; Jekyll::WordpressDotCom.process("wordpress.xml")'

Mais il est aussi possible de réaliser la migration d'un WP directement à partir de MySQL. De plus, Jekyll gère en natif de nombreuses autres plateformes : drupal, movable type, typo, blogger, posterous...

Pour en savoir plus sur la migration.

  • les commentaires

Comme on n'a plus de base de données, on ne peut plus stocker les commentaires sur le site. Cependant, on peut déléguer cette tâche à une tierce partie qui se chargera de gérer les commentaires et de les stocker pour vous à l'aide d'un simple javascript.

Pour ma part, je suis un grand fan de disqus (présent sur ce site) que j'ai découvert il y a quelques mois, la présence de ce plugin sur un blog augmente de 3000% mes chances de commenter l'article. Mais il y a aussi d'autres alternatives : IntenseDebate, facebook comment, ...

Disqus dispose d'une fonction d'import qui permet d'importer tous les précédents commentaires à partir d'un export wordpress .xml par exemple. Attention à ne pas oublier de modifier les urls des articles dans l'export si celles-ci sont différentes sur le nouveau site utilisant Disqus.

  • les redirections

Sur un blog statique, il est impossible de faire des redirections 301/302. On effectue alors des redirections à base de meta-redirect + javascript.

Cependant, si on se limite à ce type de redirection, on perd le SEO du site (les bots ne suivront pas forcément les redirections). C'est pourquoi il faut utiliser en plus la balise link canonical. Exemple :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="canonical" href="http://example.com/" >
        <meta http-equiv="Refresh" content="0; url=http://example.com/" />
    </head>
    <body>
        <script>
            window.location.href = "http://example.com/";
        </script>
    </body>
</html>

Il existe des plugins qui permettent de créer des pages de redirections automatiquement en utilisant les variables redirect ou alias de l'en-tête YAML d'un fichier. Par exemple : alias: [/redir1.html, redir2.html]

  • le déploiement sur github

Après avoir exécuté la commande Jekyll, on a un site tout prêt dans _site, on peut le déployer comme bon nous semble via ftp, scp, rsync...

Mais le truc leet à la mode c'est de mettre son blog sur github.com (comme celui-ci). Github propose un service github page qui permet de faire un site perso pour chaque utilisateur (ainsi qu'un site pour chacun de ses repos en utilisant la branche gh-pages). Il est même possible d'utiliser son propre ndd (au lieu de username.github.com).

Pour se faire un site perso sur github, on créé un repo username.github.com. Toutes les sources HTML pushées vers ce repos seront accessibles sur le site http://username.github.com.

On pourrait croire qu'il suffit de push le contenu de _site/ qui contient le site généré par Jekyll mais en réalité Github fait encore mieux. Toutes les sources pushés vers github sont automatiquement interprétées par Jekyll.

Vous pouvez donc pusher directement les sources de votre blog (c'est à dire les fichiers _layouts/ _config.yml _includes/ index.html ..., mais pas _site) et ainsi profiter du versionning de github en plus de son hébergement gratos.

Il y a quand même un bémol à l'utilisation de github, celui-ci ne supporte pas les plugins, vous pouvez donc dire adieu à certaines fonctionnalités comme la pagination.

Octopress (ou TL;DR)

Si vous ne voulez pas vous prendre la tête, faire semblant d'être un leet et avoir un blog statique alors je vous recommande Octopress. Octopress c'est super simple, la doc est très bien faite, on fait son blog statique en 2 minutes top chrono avec un CSS + que convenable. Démonstration :

# Télécharge les sources d'Octopress
git clone git://github.com/imathis/octopress.git Octopress 
cd octopress

# À faire uniquement la première fois
gem install bundler
sudo bundle install

# Génére le blog par défaut
rake install

# Créé un article
rake new_post["hello-world"]
vi source/_posts/2013-03-24-hello-word.markdown

# Génére le site dans blog/
rake generate

Et voilà, le blog est tout prêt à être deployer, vous pouvez admirer le résultat sur http://localhost:4000 à l'aide de la commande rake preview.

Octopress gère vraiment plein de trucs par défaut et est assez flexible, je vous laisse découvrir tout ça sur leur site.

Le mot de la fin

Cet article fut super long à rédiger, maintenant je comprends pourquoi je n'avais pas blogué depuis si longtemps. À dans deux ans.