Processwire au banc d’essai
Il y a quelques mois, nous avons eu l’opportunité de travailler avec le CMS Processwire pour lequel j’avais écrit une première analyse. J’avais déjà utilisé cette plateforme à trois reprises pour des sites personnels. J’étais donc très heureux de pouvoir enfin le mettre à profit pour un projet d’entreprise.
Le projet
La Zone de ski de l’Estrie est un organisme à but non lucratif qui « a pour mission de promouvoir le ski alpin de compétition […] et de favoriser l’émergence de skieurs élites dans la région. Elle représente les intérêts de ses cinq clubs membres (Bromont, Orford, Owl’s Head, Sutton) incluant son équipe élite régionale (ÉÉAE) auprès des instances provinciale (SQA) et nationale (ACA). »
Le site web de la Zone avait vieilli et sa vocation première qui est d’afficher calendriers et résultats de course n’offrait pas la convivialité que l’on s’attend de nos jours. Les gestionnaires du site étaient limités à ne présenter que des fichiers PDF presque dans le désordre et dans un format pas du tout adapté aux appareils mobiles.
Notre tâche consistait à présenter l’information de la manière la plus vivante possible, de mettre en valeur l’équipe élite régionale et de permettre une gestion sans souci des résultats.
Les demandes et le résultat
- La documentation
Permettre l’affichage et la gestion de nombreux documents (règlements, avis de courses, résultats officiels)
- Les albums photos
Permettre à des utilisateurs choisis de pouvoir créer rapidement des albums photos des divers événements de l’équipe élite.
- Le calendrier des courses et l’affichage des résultats
Afficher un calendrier facile d’utilisation minimisant les clics. Il faut comprendre qu’il existe six catégories de skieurs (basées sur l’âge : U8, U10, U12, U14, U16, U18, une nomenclature familière dans le monde du ski) et qu’il arrive que des parents aient un enfant dans une catégorie et l’autre skiant dans une autre catégorie. La volonté de la Zone était que le parent puisse lire rapidement ce qui l’intéressait sans avoir à naviguer d’une section à l’autre. Dans la foulée, le calendrier devait permettre d’afficher tant les documents pertinents à une course (comme les avis de course) que les résultats. Notons que chaque catégorie de course possède sa logique d’attribution de points servant au classement final.
- Le classement général
À la suite de l’importation des résultats de courses, le site devait afficher un classement automatiquement mis à jour.
- Être autonome
La Zone voulait également prendre le contrôle du site et ne pas avoir à demander constamment notre aide pour, soit changer une image de fond, soit ajouter une page, un album photo, etc.
Le choix de Processwire
De nos jours, les utilisateurs de site web s’attendent à retrouver les mêmes fonctionnalités qui font la force des médias sociaux. Tout doit être facile à opérer. Comme je le décrivais dans mon précédent article, Processwire possédait les qualités recherchées tant pour la programmation, l’intégration que pour l’administration.
Un CMS facile à apprendre
Pour la designer, nul besoin de connaître Processwire. Nous lui avons laissé carte blanche afin qu’elle conçoive l’interface souhaitée par la Zone. Les seules limites imposées étaient celles inhérentes à l’affichage d’une page web. Le reste était sky is the limit, même si le plafond du ciel était tout de même tributaire d’un budget !
Une fois la maquette approuvée, nous nous sommes mis à la programmation le module d’importation et à l’intégration du site.
L’équipe dut apprivoiser, dans un premier temps, Processwire. Le programmeur, un habitué de Drupal, a vite fait le tour de l’API qui tient sur une page. Il a été enthousiasmé par la cohérence et la robustesse de la solution. Précisons que Processwire est construit en PHP et son API est inspirée de jQuery.
Pour l’intégration, c’est dans la philosophie de Processwire de ne pas contraindre l’utilisation d’un moteur de rendu (templating) particulier. Processewire n’injecte aucun code HTML dans une page Web, la responsabilité nous incombe d’utiliser ce que bon nous semble. Commençons par comprendre comment Processwire opère.
La structure du site
La structure des fichiers d’un site est minimale en PW. Il y a le répertoire wire réservé au CMS, c’est d’ailleurs le seul répertoire remplacé quand vient le temps de mettre à jour. Le reste du code, le nôtre, est placé dans le répertoire site.
À l’intérieur de site, le répertoire assets contient ce qui est téléchargé (par exemple les images) et ce qui est généré par la compilation de Processwire (entre autres le cache). On pourrait également y placer nos scripts et fichiers CSS. Comme nous l’avons mentionné plus haut, Processwire ne se mêle pas de notre méthode de travail, en autant que cela réside dans le répertoire site et que le fichier config.php annonce les chemins à suivre.
Le répertoire modules porte bien son nom. C’est là que notre programmeur a placé son module d’importation des résultats et aussi son module de fonctions générales.
L’intégration HTML se passe dans le répertoire templates. À signaler qu’il n’existe qu’un répertoire de modèles. Comme pour la plupart des CMS, Processwire utilise un thème d’administration et un thème pour le visiteur. Au besoin, on peut se créer un thème d’administration, mais il sera placé à l’extérieur de templates, dans un autre répertoire.
Pour l’intégration, nous avons voulu nous rapprocher du modèle MVC, à savoir séparer la présentation du contrôle et de l’administration de la donnée. Nous avons installé pour ce faire le module Template Engine Factory qui permet de choisir entre Smarty, Jade et Twig ou conserver le moteur de rendu de Processwire. Nous avons opté pour Twig. Template Engine Factory s’attend à trouver sous templates les répertoires controllers et views.
À la base, Processwire ne demande pas une telle séparation d’autant que le CMS n’a besoin de fichiers de rendu (templates ou modèles) que si c’est nécessaire. Les « modèles de page », qui contiennent x nombre de champs, peuvent exister sans affichage.
Tout est page dans Processwire. Contrairement à d’autres CMS, Processwire ne fait pas de distinction entre une taxonomie, une page affichée, une variable. L’arborescence du site est faite de pages associées à des modèles. Dans la section des paramètres, on peut décider de soustraire ces pages à la vue du visiteur. On peut ainsi utiliser ces pages à des fins de programmation et de classement. On a besoin d’une liste d’endroits de courses (des montagnes) ? On crée une section, cachée ou non, et on crée des pages enfants sous cette section. Par la suite, grâce à un champ de type page, on peut lister ailleurs cet ensemble de pages comme une sélection (comme le champ node reference dans Drupal, mais contrairement à ce dernier, les tags ou taxonomies sont traités de la même façon dans Processwire, ce sont des pages).
La beauté de la chose est que rien ne nous empêche de créer un affichage pour ces lieux de course. Ce sont des pages qui peuvent avoir le nombre de champs voulu. Ces lieux de courses pourraient ainsi servir à la fois de liste de sélection, mais aussi de pages décrivant les montagnes.
Des pages structurées comme une base de données relationnelle
On peut ainsi monter un ensemble de pages comme s’il s’agissait d’une base de données relationnelle et la mission du CMS est de fournir les outils pour traiter cette donnée. Par la suite, on peut bonifier ces fonctions à l’aide de fichiers contrôleurs. Une page possède invariablement un modèle (template) qui lui, contient des champs. On peut structurer un site en limitant l’usage à certains modèles pour des parties spécifiques de l’arborescence. Par exemple, la section Album de photos ne peut contenir que des pages de type Album. Cette hiérarchie facilite grandement la mise en relation des pages et de leurs données et un utilisateur ne pourra mélanger les choses lorsqu’il voudra créer un album photo. D’autres parties du site peuvent être plus libres. On peut ainsi offrir un choix de modèles pour la création de telle ou telle partie d’un site. Tout cela est gouverné par la logique de chaque installation. Encore une fois, Processwire offre les outils pour encadrer la mise en place des pages et il revient aux concepteurs d’organiser comme bon lui semble un site.
Comme notre projet consistait à importer des résultats de courses, la logique adoptée pour la structure du site fut la suivante : si un skieur qui a fait une course ne possède pas déjà sa page dans le CMS, créons-la sous la page parent Skieurs. Inscrivons par la suite le résultat sous la page parent Résultats. Cette page de résultat possède un champ qui fait la relation avec ledit skieur. Dans le même temps, cette table possède d’autres champs du même style en lien avec d’autres types de pages tels la course, la journée de course, les clubs, etc.
Au final, on obtient des pages à la fois indépendantes et reliées entre elles. On peut les appeler d’où l’on veut dans le code, les afficher, et on peut effectuer des recherches plus ou moins complexes tant par le code que par l’interface d’administration et décider par la suite de les afficher sur une page précise.
Notre site possède la structure de pages suivante en ce qui a trait aux courses :
- Saisons (modèle season_landing)
- Saison (modèle season) => affiche le classement général
- Calendrier des courses (modèle calendar) => affiche le calendrier et autres informations glanées ailleurs
- Jours de course (modèle day_race)
- Courses (modèle race)
- Saison (modèle season) => affiche le classement général
- Skieurs (modèle skiers_landing)
- Skieur (modèle skier) (information du skieur)
- Résultats (modèle results_landing)
- Résultats de chaque joueur (modèle result)
- Variables (modèle invisible)
- Lieux de courses (modèle location)
Seules les pages en caractère gras affichent réellement des données. Ainsi, le fichier calendar.php est le fichier contrôleur correspondant au modèle calendar et le rendu de la page est fourni par calendar.html.twig.
Puisque les pages invisibles sont tout de même des pages, on pourrait décider d’offrir ultérieurement un affichage, par exemple, pour chaque skieur. Il suffirait d’ajouter une page contrôleur skier.php et un fichier de rendu skier.html.twig. Processwire reconnaîtra automatiquement la présence de ce nouvel affichage.
Nous avons utilisé Twig. Comme il a été dit plus haut, nous aurions pu utiliser un autre moteur de rendu. D’ailleurs, Processwire proposera bientôt une approche basée sur des « régions » et qui rappellera les blocs utilisés dans Twig et autres.
La légèreté du code et du rendu
Malgré l’apparente complexité du processus — une donnée sera toujours compliquée à organiser, peu importe ce qu’on utilise —, le résultat tient en fichiers compacts et peu verbeux. Cela est rendu possible grâce à l’efficacité de l’API. L’exemple qu’il me plaît de donner en parlant de ce site est une requête pour chercher une liste de skieurs de catégorie élite U16. "U16" est dans la variable $categorie :
On remarquera que nulle part on a dit que categorie_elite et equipe étaient des champs. Comme on ne peut avoir deux champs portant le même nom, PW sait quoi fait quoi.
En comparaison, un code similaire dans Drupal pourrait ressembler à ceci :
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'skier')
->fieldCondition('field_categorie_skier', 'tid', $node->field_skieur[LANGUAGE][0]['tid'], '=')
->fieldCondition('field_equipe', 'tid', $node->field_equipe[LANGUAGE][0]['tid'], '=');
->fieldOrderBy('field_date_album', 'value', 'DESC');
$result = $query->execute();
$empty = empty($result['node']);
if (!$empty) {
$pages = $result['node'];
foreach ($pages as $page) {
$ski = node_load($page->nid);
[...]
Mais revenons à Processwire. Le résultat obtenu est un tableau (array) de pages contenant l’information de chaque page. Inutile par la suite de charger chacune des pages pour en extraire la donnée.
Ce résultat, demandé dans la page/contrôleur de l’équipe élite U16, nous permet de coder la suite dans le fichier twig. On voit que la variable skieurs contient toute l’information requise :
{% for skieur in skieurs %}
- {{skieur.prenom}} {{skieur.nom_famille}}
{% endfor %}
La partie contrôleur donne l’occasion de reformuler la donnée et de l’assigner à une variable personnalisée. Il suffit d’évoquer l’objet $view et de lui ajouter ce dont on a transformé.
// set template variables
$view->set('extra', $calendar['extra']);
$view->set('season', $calendar['season']);
$view->set('months', $calendar['months']);
$view->set('races', $calendar[‘races']);
Les variables extra, season, months, races seront dorénavant reconnues par twig.
{% for month_key, month in months %}
[…]
{% endfor %}
Le débogage
Le langage de PW est le PHP. On s’attendrait donc à ce qu’on puisse utiliser des outils tels xDebug. En théorie, cela est possible, mais nous avons éprouvé quelques difficultés dans phpStorm. S’ils étaient respectés, les points d’arrêt ne fournissaient peu ou pas de données valables, les objets de Processwire semblant disparaître au moment de l’interruption du programme. Nous n’avons pas exploré davantage le problème, mais nous ne serions pas les seuls sur ce plan. Heureusement, il existe une adaptation de l’environnement Tracy qui facilite grandement la tâche.
La zone d’administration (backend)
Une excellente programmation ne pourrait à elle-même briller si elle n’était pas appuyée par une interface d’administration facile à utiliser. Encore une fois, Processwire offre cette aisance qui plaît tant aux usagers. On peut se référer à l’article précédent pour de plus amples détails.
J’ajouterai que l’administrateur peut comprendre très facilement ce qui a été mis en place en observant ce que l’arbre des pages lui fournit (première chose que l’on voit en se connectant à l’administration). L’arborescence montre autant les pages visibles que les pages structurelles. Puisque nous travaillons en suivant la philosophie Agile, le client a pu suivre les étapes de construction du site et il a pu valider la démarche. Nous lui avons également fourni, à même le site, un bref rappel des procédures conçues et nous avons pris soin d’éviter tout jargon technique.
Nous avons porté un soin particulier au mécanisme d’importation. Grâce aux outils offerts par Processwire, nous avons conçu un draguer/déposer pour importer un fichier de résultat. En déposant le fichier, un script de validation s’assure que le nom du fichier correspond à ce qui a été convenu (ce nom de fichier procure l’information pour diriger le script d’importation et il est basé sur les divers mots-clés entourant une course si bien que l’administrateur n’a pas eu de mal à bien nommer ses fichiers).
L’arbre des pages peut également être adapté selon le type d’usager inscrit. Puisqu’il y a des utilisateurs qui ne sont responsables que des albums photos du site, ils ne se voient présenter que l’arborescence des photos au moment de se connecter.
L’ajout de quelques modules payants
Bien que Processwire soit gratuit, en code libre, son équipe de concepteurs propose quelques solutions payantes très bon marché. Nous avons ainsi eu recours à deux de ces modules. Le premier, ListerPro (49 $ US), permet l’affichage complexe de n’importe quelle donnée, ce qui facilite grandement la recherche. Les filtres de ListerPro peuvent être établis d’avance, mais on peut laisser aussi le choix à l’administrateur de modifier ces filtres.
Le second module utilisé est ProCache (49 $ US). Il s’occupe essentiellement de convertir en page statique les pages du site, rendant ce dernier extrêmement réactif.
J’ai déjà eu l’occasion d’utiliser pour un autre site personnel le module FormBuilder (devinez son prix). Puissant module de création de formulaires !
D’autres modules Pro ont vu le jour depuis un an et nous nous promettons de les explorer, notamment un module de profilage (maximisation de la performance) et un autre étendant grandement les capacités des champs.
En conclusion
Nous avons éprouvé que très peu de problèmes à utiliser Processwire. Les écueils existeront toujours dans n’importe quel CMS et la qualité d’un cadriciel (framework) s’évalue beaucoup par le soutien de sa communauté de développeurs. Processwire ne déroge pas de cette règle et le temps de réponse à nos questions fut toujours très court.
Le site de la Zone de ski de l’Estrie semblait facile à développer, à première vue. Les règles d’affaires qui sous-tendent le cumul des points et le défi de présenter les résultats de manière cohérente et facile nous ont causé quelques maux de tête et nous étions heureux de ne pas devoir à nous battre contre un CMS contraignant ou verbeux.
Il nous reste à pousser l’aventure avec un site plus gros. Le démonstrateur en ligne de ce CMS semble prouver qu’il est capable de bien des choses.
Le concepteur du CMS, Ryan Cramer, est volubile et nous informe hebdomadairement des progrès accomplis. Jamais une solution proposée ne s’écarte de l’élégance qui fait partie de la marque de commerce de Processwire. C’est rassurant pour des développeurs !
Processwire s’est avéré un CMS hautement professionnel, soigné, soutenu par une communauté de développeurs ingénieux. C’est une solution facile à programmer, mais cette simplicité ne diminue en rien sa puissance. Au contraire ! Bien que la quantité de modules de contributeurs soit limitée, cela n’a nullement nui au développement de notre site d’autant qu’il est préférable et sage de coder soi-même que de tenter de déconstruire des modules conçus pour pallier à toutes les éventualités souvent étrangères au site que l’on élabore.
Pour nous, l’expérience est à refaire !