Pelican : Mon workflow avec git

Ce blog est construit autour de différentes solutions dont Pelican qui en est le moteur. Lorsque j'ai commencé à me renseigner sur Pelican (documentation, blogposts, etc…) il s'est trouvé que la plupart des articles détaillaient seulement son installation et l'écriture d'un article : ce que fait très la documentation officielle. Le plus gros problème, de mon point de vue, c'est qu'il manque leur workflow. Je vais essayer de détailler au mieux le mien…

Pelican

Pelican est un générateur de site statique écrit en Python couplé à des templates Jinja pour générer les pages HTML. Le contenu peut être écrit en Markdown ou en reStructuredText. L'intérêt par rapport, par exemple, à WordPress ? On se passe de PHP et de base de données tel que MySQL : on gagne alors en sécurité, fiabilité et rapidité. Il n'y a pas de traitement côté serveur pour générer les pages, tout le site n'est qu'un ensemble de pages HTML.

Après cette courte explication, je vais détailler rapidement comment initier un premier projet.

Installation

Certaines commandes seront à exécuter avec sudo.

Pelican requiert Python 2.7.x ou Python 3.3+, idéalement python3. J'utilise également pip et les virtualenv.

On commence par récupérer pip, créer un venv et se placer dedans.

apt install python3-pip python3-venv -y
#pip3 install virtualenv # c'est mieux avec --user mais bon :)
#virtualenv ~/.virtualenvs/pelican
python3 -m venv ~/virtualenv/pelican
cd ~/.virtualenvs/pelican
source bin/activate

On peut enfin installer Pelican, Markdown et créer son projet.

pip install pelican markdown
mkdir blog && cd blog

La commande suivante permet de générer les premiers fichiers nécessaires au lancement de Pelican

pelican-quickstart
[]
> Do you want to upload your website using SSH? (y/N) y

De mon côté, je choisis de transférer mes fichiers via rsync/ssh.

Les fichiers suivants sont générés :

├── content
├── develop_server.sh
├── fabfile.py
├── Makefile
├── output
├── pelicanconf.py
├── publishconf.py

Compilation

Le dossier content contient les pages bruts en Markdown.

Le Makefile va permettre, entre autre, de générer le HTML et lancer un serveur web local (port 8000) et/ou d'envoyer le contenu de output vers son serveur.

make devserver # générer les pages html et lance un serveur web local
make rsync_upload # envoyer les pages va rsync/ssh
make # affiche l'aide

Sur FreeBSD, il faudra gnu-make pour exploiter le Makefile.

pkg install gmake
gmake devserver

Le contenu généré se retrouve organisé dans le dossier output et comme expliqué au-dessus c'est ce dossier qui contient le rendu HTML à héberger.

On vérifie que le serveur local tourne

curl -I 127.0.0.1:8000
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.6.4

Bien :) On utilise son navigateur web favoris (Firefox ?) pour vérifier que le rendu est bien celui escompté.

Une dernière chose essentielle est le fichier de configuration principale : pelicanconf.py.

Ce fichier de configuration contient les variables de votre projet afin de le personnaliser. Les réponses données suite à la commande pelican-quickstart ont servies à alimenter ce fichier. Une partie du mien :

#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

# Main stuff
AUTHOR = 'Pierre Boesch'
AUTHOR_DESCRIPTION = 'Mon blog'
SITENAME = 'Pierre Boesch'
SITEURL = ''
SITEDESCRIPTION = 'Page personnelle'
FAVICON = '/favicon.ico'

# Content generation
PATH = 'content'
STATIC_PATHS = ['images', 'pdf', 'static'] # les dossiers qui n'auront pas de .md
EXTRA_PATH_METADATA = {
      'static/robots.txt': {'path': 'robots.txt'},
      'static/favicon.ico': {'path': 'favicon.ico'},
} # les fichiers à poser directement à la racine

# Artcile/Archives
AUTHOR_SAVE_AS = ''
AUTHOR_URL = ''
ARTICLE_URL = '{date:%Y}/{date:%m}/{slug}/' # les "permaliens" de wordpress
ARTICLE_SAVE_AS = ARTICLE_URL + 'index.html'
YEAR_ARCHIVE_SAVE_AS = 'archives/{date:%Y}/index.html'
DEFAULT_PAGINATION = 5

Le fichier publishconf.py contient les variables spécifiques pour la production. Les variables définies dans pelicanconf.py peuvent être overridées dans ce fichier.

Il ne reste plus qu'à définir un workflow et de publier le tout… Je ne passerai pas en revu l'utilisation de thèmes, écriture d'articles, format Markdown, etc… tout est très bien expliqué dans la documentation officielle.

Workflow

arborescence

Dans un premier temps, j'ai décidé d'organiser le contenu de la façon suivante :

content
├── articles
│   └── article1.md
│   └── article2.md
├── images
│   ├── image.png
├── pages
│   └── page.md
├── pdf
│   └── fichier.pdf
└── static
    ├── favicon.ico
    └── robots.txt
  • articles : articles en markdown (ce que vous êtes en train de lire…)
  • images : toutes les images
  • pages : les pages statiques du blog (À propos par exemple)
  • pdf : les pdfs
  • static : tous les fichiers qui ne devraient pas bouger Pour les dossiers "statiques" il faudra les définir en utilisant la variable EXTRA_PATH_METADATA (comme déjà dit c'est très bien expliqué dans la documentation de Pelican).

versionning

Je gère les sources via git sur un repo privé. De cette façon, je peux récupérer les sources rapidement sur n'importe quel poste et versionner chaque modification.

On initie son projet actuel comme un nouveau repo :

git init
git add .
git commit -m "first commit"
git remote add origin ssh://git@monrepo-git.com/namespace/monblog.git
git push -u origin master

Le .gitignore qui va bien :

*.pid
*cache*
output

Pour le thème, le même principe peut être appliqué.

Pour résumer l'idée : lorsque je suis sur un nouveau poste et dans un virtualenv, j'ai seulement besoin de cloner le repo pelican du blog et le thème.

les brouillons

Il est possible de mettre un status draft aux articles lors de l'édition. Avec ce status, Pelican ne génèrera pas le html et ne sera pas dans le dossier output et donc publié. Donc la prévualisation de l'article est difficile.

Une solution simple, utilisant git, et de créer une branche draft pour gérer les… brouillons. Quand je commence un article, je bascule sur la branche draft. Les articles sont stockés dans le répertoire habituel, si j'ai besoin d'une prévualisation il me suffit d'exécuter make devserver. Une fois l'article terminé :

git checkout master
git checkout draft -- content/articles/article-draft.md
git commit
git push

publication

Le Makefile contient les informations de connexion SSH vers le serveur.

SSH_HOST=mon_host
SSH_PORT=22
SSH_USER=mon_user
SSH_TARGET_DIR=/usr/local/www/mon_blog

Pour publier :

make clean
make publish
make rsync_upload

Il reste à mettre en en place une configuration basique nginx (ou Apache) d'un virtualhost pour servir les pages HTML, et le tour est joué.

server {
  listen 80;
  server_name www.pboesch.fr;

  access_log /var/log/nginx/access_pboesch.log combined;
  error_log /var/log/nginx/error_pboesch.log;

  root /usr/local/www/pboesch/;
  index index.html;

  location / {
    try_files $uri $uri/ =404;
  }
}

Terminé \o/.


Commentaires