Un site multilingue avec Pelican

Publié le 22/04/2016

Pour un petit projet perso, on m'a demandé de développer un petit site de location de chambres. En soi, j'aurais pu simplement créer quelques pages HTML statiques, copier le tout sur un serveur et le tour aurait été joué. Il y avait cependant quelques contraintes à prendre en compte:

  • Besoin d'un site multilangues (en, fr, nl)
  • Besoin d'une gallerie d'images, une gallerie devant √™tre associ√©e √† une page.
  • Besoin d'une carte, pour pr√©senter les choses int√©ressantes √† voir dans le quartier.
  • Et beaucoup de discussions, pour arriver √† un r√©sultat convaincant.

Il me fallait quelque chose de flexible, permettant de gérer facilement les images, de mettre le texte en forme, de gérer l'affichage des informations, ... Le tout, sans que cela ne prenne trop de temps.

En parcourant les diff√©rents CMS existants, je me suis rendu compte qu'il existait assez peu de solutions autorisant ces trois contraintes nativement. Wordpress le permet, mais seulement gr√Ęce √† l'installation de plusieurs plugins; Drupal me semblait trop compliqu√© √† appr√©hender; PluXML n√©cessiterait sans doute trop de param√©trage, ... Celle qui m'aurait le plus bott√© √©tait Wagtail, mais le temps fait (un peu) d√©faut pour le moment... En gros, j'avais le choix entre les deux solutions suivantes:

  1. Un vrai CMS dynamique, o√Ļ mon utilisateur ador√© pourrait se d√©brouiller tout seul. Il aurait alors fallu renforcer la s√©curit√©, configurer la base de donn√©es, configurer les backups, v√©rifier la coh√©rence des donn√©es au restore, le former √† la manipulation des donn√©es et aux traductions
  2. Ou alors, partir sur un site statique présentant les informations de manière fixe, nécessitant relativement peu de paramétrage, mais l'obligeant à me contacter pour toute modification.

Puisqu'on parle d'une personne (très) proche, je suis parti sur la seconde option. Et puisqu'on parle d'un site statique, je suis parti sur Pelican.

Multilinguisme

Pour gérer un site multilangue, il y a deux solutions:

  1. Soit utiliser les métadonnées lang et slug dans chaque article/page. Cette solution ne convient qu'à moitié, car la langue principale du site reste inchangée, quelle que soit l'entrée sur laquelle l'utilisateur se trouve: si le visiteur clique sur un lien, il arrivera donc sur la page traduite dans la langue par défaut, mais s'il se trouvait sur une page traduite dans une autre langue. Ce qu'on souhaite, c'est que le site soit en fait un sous-site du site principal, avec sa langue spécifique: en traduisant la page dans une langue, on resterait dans cette langue-ci.
  2. Soit utiliser le plugin i18n_subsites, qui permet de définir un site principale (basé sur une langue), puis un ensemble de sous-sites, chacun d'entre eux correspondant à une langue.

En gros, la structure devient la suivante:

pages/
  en/
    page1.md
    page2.md
  fr/
    page1.md
    page2.md
  nl/
    page1.md
    page2.md

Ceci colle d√©j√† plus √† ce que l'on souhaite. Pour activer le plugin, il suffit de cloner le d√©p√īt pelican-plugins (ou de copier le plugin dans un sous-r√©pertoire de l'installation, √† la hussarde). Attention qu'on trouve quelques probl√®mes de compatibilit√© entre greffons: i18n_subsites pose plus ou moins probl√®me avec le plugin gallery si des images d'albums diff√©rents portent le m√™me nom.

Gallerie d'images

Pour la gallerie d'images, je suis parti des plugins gallery et thumbnailer. Le premier permet de créer une gallerie et y copiant un ensemble de photos; le second permet de créer des thumbnails pour chacune des images (au format square, wide ou cropped). Dans chaque page, j'ajoute une métadonnée gallery: , qui indique le nom du répertoire dans lequel les images doivent être récupérées. Dans le template (également fixé au niveau des propriétés de la page), on peut alors parcourir les différentes images et les afficher. En associant ce mécanisme avec un plugin Lightbox pour jQuery, on peut ainsi charger les miniatures à l'affichage, et présenter l'image originelle lorsque l'utilisateur cliquera sur le thumbnail.

{% for image in page.galleryimages %}
    <a class="thumbnail" data-lightbox="pictures-set" href="/pictures/gallery/{{page.album}}/{{ image }}">
        <img class="img-thumbnail img-responsive" src="/thumbnails/thumbnail_wide/{{ image }}" alt="">
    </a>
{% endfor %}

Index

La page d'accueil est fixée et ne se base pas sur du contenu. Je l'ai configurée directement au niveau du thème. La navigation pour l'utilisation est la suivante: lorsqu'il se connecte au site, il arrive sur la page d'accueil - quelques images, menu en anglais par défaut. Il peut alors sélectionner une langue, ce qui l'enverra vers la page {lang}/index.html. Cette page-ci correspond à du contenu rédigé en Markdown, dans lequel on trouve les métadonnées suivantes:

Title: Around us
Slug: index
Lang: en
Translation: true
Template: pagewithmap
Gallery: brussels

A priori, toutes les propriétés spécifiées ont une utilisé:

  • Le titre est utilis√© dans le template et dans les menus de navigation
  • Le slug permet d'overrider le nom du fichier (mais on aurait aussi pu passer par la propri√©t√© save_as). Il s'agit aussi de la cl√© qui associera tous les contenus ayant le m√™me slug.
  • La propri√©t√© Lang d√©finit la langue
  • Le template permet d'associer la pr√©sentation √† une page HTML sp√©cifique. Celle-ci est plac√©e dans le r√©pertoire themes/{theme_name}/templates/pagewithmap.html.
  • La propri√©t√© gallery est utilis√©e par le plugin gallery que l'on a charg√© plus haut. Celui-ci va charger toutes les images qui se trouvent dans le r√©pertoire pictures/gallery/{gallery_name}/.

A améliorer

Plut√īt que d'avoir des pages statiques, toutes li√©es √† un template, j'aurais appr√©ci√© pouvoir structurer mes donn√©es dans des blocs. Par exemple, dans une page, j'aurais pu avoir un bloc description, un bloc comment nous joindre, un bloc prix, ... A r√©p√©ter dans les diff√©rentes langues. Wagtails le permet (et c'est m√™me son mode de structuration par d√©faut - √† coupler avec Django Medusa). Je crois que Hyde fonctionne un peu selon le m√™me principe, avec l'avantage qu'il g√©n√®re par d√©faut du contenu statique. En fait, il y a des propri√©t√©s globales au site que j'aurais aim√© pouvoir d√©finir (dans les diff√©rentes langues :-)) et r√©utiliser √† des endroits pr√©cis.

En même temps, j'aurais aimé pouvoir associer plusieurs galleries d'images à une même page. Le plugin gallery ne permet d'associer qu'un répertoire; il ne gère pas les sous-répertoires (la méthode utilisée est un listdir et pas un walk - et cela impliquerait de modifier la structure de retour pour associer le nom du sous-répertoire aux images, en plus du répertoire initial).