Image mise en avant pour l'article

Carnets de Développeur : pourquoi je ne reviendrai plus sur WordPress après avoir essayé Drupal ?

21 octobre 2020
CMS - Drupal - Technologies Web
Quel CMS choisir : WordPress ou Drupal ? L'éternelle question ... Jean-Pascal nous explique pourquoi il a choisi Drupal plutôt que WordPress.


Note : Par essence, cet article peut sembler être à charge contre WordPress. Il n’aborde en effet qu’un seul axe : en quoi Drupal est plus intéressant que WordPress pour développer. La réalité n’étant jamais binaire, un second article viendra prochainement contrebalancer celui-ci pour identifier dans quels cas il serait, selon moi, plus utile de se tourner vers WordPress.

Développeur depuis 2011, principalement sur des CMS, j'ai travaillé pendant plus de 5 ans sur WordPress.

Lorsqu’il y a 2 ans j'ai eu l'opportunité de travailler sur Drupal, j'étais curieux. Je ne compte pas faire machine arrière et être à nouveau principalement sur WordPress. Voici les raisons pour lesquelles je préfère désormais Drupal.

 

Drupal : vers un code de meilleur qualité

 

Utilisation de la POO et des fonctionnalités de PHP 7

Chez Automattic, l'éditeur de WordPress, l'accent est mis sur la compatibilité du CMS, qui doit pouvoir tourner avec n'importe quel type d'architecture technique. Si c'est arrangeant pour les propriétaires de sites qui n'ont pas à se soucier des caractéristiques techniques de leur hébergement, cela restreint le développement de plugins WordPress. En effet, avec Wordpress, vous ne pouvez pas exploiter les avantages des dernières versions de PHP et notamment de PHP7 (notons entre autres : déclaration des types dans les fonctions, l'opérateur de fusion nulle, les fonctions array_key_first() et array_key_last() ...) au nom de la nécessaire compatibilité avec PHP5.

De son côté, Drupal 8 comme Drupal 9 ont comme pré-requis PHP 7.3 dans sa version actuelle. Cette contrainte technique permet néanmoins d'exploiter toutes les potentialités de la programmation objet. Ainsi, via un système de Plugin Managers vous pouvez ajouter des implémentations différentes de celles existantes sur différents éléments (exemple : les blocs).

WordPress est ainsi très en retard sur la programmation orientée objet en raison de sa compatibilité voulue avec PHP 4. Une refonte complète en objet (comme cela a été le cas entre Drupal 7 et 8) n'est toujours pas à l'ordre du jour. En résulte un code peu extensible, uniquement modifiable via des accroches (hooks).

Drupal 9 a, à sa suite, nettoyé une grande partie du code qui permet la compatibilité entre Drupal 8 et 9 et d’améliorer les performances du CMS.

À cela s'ajoute l'utilisation d'outils ayant fait leurs preuves...

 

 

Utilisation des bibliothèques Symfony et développement orienté services

Drupal, en passant à sa version 8, s'est équipé de plusieurs services du framework Symfony. Il s'agit d'un des principaux Framework PHP à l'heure actuelle, et ses composants pour les fonctionnalités les plus communes sont développés, maintenus et éprouvés par une communauté solide.

Plusieurs de ces composants ont été utilisés par Drupal qui les a incorporés dans le développement de modules. Le conteneur de services permet de segmenter les développements en une multitude de services réutilisables. Ces services peuvent aussi être tagués pour devenir des fournisseurs de Breadcrumb ou des services de traduction.

Ces services, gérés via une déclaration dans les fichiers de configuration YAML, peuvent être injectés rapidement dans les contrôleurs et dans les Plugins Drupal (et être injectés les uns dans les autres).

Les développements peuvent notamment bénéficier des services injectés depuis les modules de Drupal, ce que ne permet absolument pas Wordpress.

 

Utilisation de Composer

Si des projets permettent désormais d'installer WordPress via composer, celui-ci n'est globalement pas prévu pour bénéficier de cet outil. Pour gérer les modules liés au projet, il faut les ajouter directement via l’administration de WordPress. Il est donc impossible d'utiliser composer (récupération des dépendances du module, gestion fine des versions, possibilité de ne pas versionner leurs sources, …).

Or Composer est un avantage indéniable pour la gestion des mises à jour, des montées de version et la maintenance des sites Internet.

La mise à jour du cœur de WordPress continue à se faire intégralement via l’administration et est même, dans la configuration de base, lancée parfois automatiquement (avec les risques que cela représente...). C'est considéré comme un avantage pour des développeurs un peu bricoleurs, mais c'est pour moi un vrai risque pour la disponibilité du site Internet.

Depuis Drupal 8, l’installation du CMS et de ses modules peut se faire intégralement via composer : le composer.json fourni avec Drupal et configuré pour récupérer un module parmi les contributions publiques. Composer permet aussi via composer-patches d'appliquer des patchs sur les contributions à chaque installation (si celles-ci souffrent d’un bug ou si vous avez besoin d’y ajouter une fonctionnalité et que le module n'est pas suffisamment extensible).

"extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            }
        },
        "patches": {
            "drupal/core": {
                "email constraint": "patchs/saml_bypass_email_constraint.patch"
            },
            "drupal/admin_toolbar": {
                "#3168654-4 : Fix apostrophes not being encoded in admin tool bar taxonomy menys": "https://www.drupal.org/files/issues/2020-11-05/admin_toolbar-apostrophe-3168654-4.patch"
            },
            "drupal/samlauth": {
                "remove notice": "patchs/saml_auth_remove_notice.patch",
                "translate locked account text": "patchs/saml_add_translation_text_for_account_locked.patch"
            },
            "drupal/views_bulk_operations": {
                "Notice : Undefined property: Drupal\\views\\ResultRow::$nid": "patchs/views_export_error.patch"
            },
            "drupal/antibot": {
                "IE11 fix": "patchs/antibot_ie11_fix.patch"
            }
        },

 

Un bugtracker par module avec une communauté active

Pour chaque module public, comme sur WordPress, Drupal propose un bugtracker où les bugs et demandes de fonctionnalités peuvent être reportés.

Contrairement à WordPress, le bugtracker Durpal offre la possibilité, sur chaque ticket, d'utiliser un patch en tant que fichier diff. Il peut directement être appliqué sur votre installation via composer afin de ne pas attendre la correction faite par l’auteur du module en question.

Le nombre de modules est plus restreint et il est en général plus fréquent d’avoir des contributeurs autres que le ou les auteurs sur un module. Il est possible de proposer, de discuter et de se mettre en commun pour travailler sur un nouveau module contribution si vous ne trouvez pas le module que vous cherchez.

Lorsqu'un besoin en développements custom se fait ressentir, il est possible de se tourner vers des outils en ligne de commande pour simplifier vos actions les plus courantes.

 

Deux outils CLI pour le développement : drush & drupal

Avec Drupal 9 sont fournis 2 outils à utiliser en CLI (Command Line Interface) dans les vendors.

Avec la commande Drupal, il est possible de :

  • Générer du code pour initier un module, créer un contrôleur, un formulaire de configuration, etc.,
  • Faire du debug sur un site en listant les routes actives, les services présents dans le conteneur, les mises à jours disponibles pour les modules,
  • Gérer les utilisateurs et leurs rôles.

Commande Drupal

La commande Drupal permet de générer automatiquement une base pour la majorité de vos développements

A cette commande s’ajoute drush, commande historique fournie par la communauté Drupal avant Drupal 8. Si celle-ci a des commandes en doublons avec la précédente, elle lui est aussi complémentaire avec des commandes supplémentaires. Elle permet notamment de :

  • Rafraîchir les caches du site,
  • Vider la base de donnée ou s’y connecter directement en utilisant les paramètres du site,
  • Générer un lien de connexion unique pour n’importe quel utilisateur du site.

Une autre commande dans l'outil drush permet aussi d’importer ou d’exporter la configuration d'un site.

 

Une configuration synchronisée entre les environnements

La configuration est exportable facilement sur Drupal. Le CMS propose de facilement transposer le schéma de la base de données, les combinaisons clé/valeur de configuration, la liste des modules installés … en fichiers YML. Ceux-ci peuvent être récupérés pour importer cette configuration sur une autre installation.

De la même façon, lors de la création d'un module, si celui-ci a besoin d’un type de contenu ou d’une clé de configuration, il suffit :

  • D’exporter cette configuration,
  • Et de placer les fichiers YAML liés dans le dossier config/install de votre module.

Pour gérer plus finement la configuration, des modules existent. Ils permettent de scinder la configuration par environnement ou d’ignorer certains éléments lors de l’import.

 

Des outils plus flexibles

 

Un système de routing plus clair et plus précis

Drupal 9 utilise, pour son routing, le composant de Symfony et gère les routes au format YAML. Ce système a plusieurs avantages vis à vis du système d’URL rewriting de WordPress :

  • Le système de routes est beaucoup plus lisible que les expressions régulières ;
  • Il est possible d’avoir des paramètres optionnels ou de forcer le type d’un paramètre (voire d’assigner 2 actions à une même route selon que le paramètre soit un entier ou non) ;
  • Il est possible d’appeler dans le code une URL directement via le nom de sa route. Cela permet de changer les URL sans aucune modification dans le code, simplement en changeant son pattern dans le YML ;
  • Il est possible de router une URL vers une action de contrôleur, mais aussi vers une classe de formulaire qui devient alors directement le contenu de la page.
comment.admin:
  path: '/admin/content/comment'
  defaults:
    _title: 'Comments'
    _form: '\Drupal\comment\Form\CommentAdminOverview'
    type: 'new'
  requirements:
    _permission: 'administer comments'
comment.admin_approval:
  path: '/admin/content/comment/approval'
  defaults:
    _title: 'Unapproved comments'
    _form: '\Drupal\comment\Form\CommentAdminOverview'
    type: 'approval'
  requirements:
    _permission: 'administer comments'
entity.comment.edit_form:
  path: '/comment/{comment}/edit'
  defaults:
    _title: 'Edit'
    _entity_form: 'comment.default'
  requirements:
    _entity_access: 'comment.update'
    comment: \d+
}

 

Champs personnalisés pour les contenus et les taxonomies

Sur WordPress, les champs supplémentaires liés à un content type ou à une taxonomie s’ajoutent via une metabox. Il faut donc coder l’affichage du formulaire pour l’admin, puis gérer la soumission de celui-ci. Et s’assurer de l’intégrité de la valeur de ce champ par rapport à nos besoins ! (Wordpress stocke tous ces champs dans une table meta, et il est impossible de typer plus précisément ces champs de base)

Sur Drupal, chaque champ d’un type de contenu ou d’une taxonomie peut être ajouté via l’administration.

Ainsi, un champ est la somme de plusieurs éléments administrables :

  • Un ID (le machine_name) et un libellé ;
  • La possibilité d’être un champ multiple ;
  • L’option de rendre ce champ obligatoire ;
  • Un type de champ (les plus courants sont fournis par Drupal, de l’entrée textuelle à la relation avec un autre élément) ;
  • Un widget d’affichage sur les formulaires d’édition. Chaque type a à sa disposition un ou plusieurs formats d’affichage à l’édition. Par exemple, une date pourra être affichée avec un simple champ texte, ou en séparant les champs jour, mois et année.

Ainsi il est facile d’administrer des champs personnalisés, d’en exporter la configuration, puis d’ajouter les YAML ainsi créés à un module. Ces éléments sont ainsi ajoutés lors de l’installation du module.

Il est également possible de créer ses propres types de champs et de les ajouter via le système de plugins Drupal dont nous reparlerons plus loin.

La gestion de l'affichage est également facilitée.

 

 

Affichage d’un contenu et de ses champs

Dans WordPress, toujours dans l’optique d’utiliser des champs personnalisés, il faut gérer l'affichage des templates. Et pour un même type contenu, il faut créer un template pour chaque type d’affichage voulu (par exemple, une version pour les utilisateurs anonymes et une autre pour les utilisateurs connectés).

Sur Drupal, il est possible de déclarer pour chaque type de contenu un à plusieurs types d’affichages, et pour chacun d’eux une interface qui permet de choisir les champs à afficher et leur ordre. Il est aussi possible de choisir, pour chaque champ, un type d’affichage parmi ceux liés au type de champ. Par exemple, pour une date, il est possible de choisir finement le format de date souhaité pour chaque affichage de celle-ci.

Bien entendu, il est possible de créer ses propres formateurs de champs pour personnaliser les sorties.

 

Gérer vos listes de contenus

Dans WordPress, l'affichage d’une liste de contenus se fait via la Loop. Loop est un outil utile quand elle renvoie un résultat classique. Mais l’ajout de filtres dynamiques ou de champs de recherche peut être rapidement compliqué. Il oblige à altérer la requête avant le passage dans la Loop et à s'assurer de n’altérer cette requête que dans les cas souhaités. De plus, la création d’une page avec une URL spécifique qui contient notamment une liste peut s’avérer compliquée si le reste du contenu n'est pas placé dans un template.

Drupal propose un système nommé views pour générer une liste de contenus. Créer une view permet de définir les conditions de tri et de filtre des contenus pour générer une liste et la manière dont s’affichent les résultats (via les types d’affichage, ou en listant les champs souhaités avec leur formateur). Au delà de cet affichage, voici une liste non-exhaustive des possibilités avec une view :

  • Récupérer pour chaque résultat une entité liée et utiliser ses champs. Par exemple, récupérer un champ couleur d’une taxonomie liée pour utiliser cette couleur sur le jeu de résultats ;
  • Créer un formulaire de filtres, simplement en choisissant quels champs mis à disposition de à l’utilisateur pour filtrer. L'utilisateur peut alors facilement choisir l’ordre des résultats, filtrer sur un champ personnalisé, etc. ;
  • Définir si une vue est une page (dont le choix de l’URL est libre) ou seulement un bloc (ce qui permet de l’intégrer au sein d’autres contenus).

drupal - gérer vos listes de contenus

Affichage d'une vue. Ici le champ "type de contenu" est exposé et générera donc
un formulaire de filtre pour l'utilisateur consultant la page.

 

Gestion des images

WordPress permet de définir des tailles d’images. Pour chaque image créée, une autre version est générée pour chaque taille définie dans le thème et les modules.

Sur Drupal, on définit des image style. Chaque image style permet d’appliquer un certains nombres de modifications : de la réduction en pourcentage au choix de la qualité de l’image. Chaque style peut cumuler les opérations, dans l’ordre de votre choix. Il est également possible d’en créer de nouveaux.

Autre avantage : la version d’une image pour un image style n’est créée qu’à l’appel de celle-ci, ce qui évite de générer des fichiers inutiles sur le serveur.

 

Héritage de thème sur plusieurs niveaux

WordPress, comme Drupal, permet l'utilisation du concept de thème enfant. Lorsqu’un thème est créé, on peut lui définir un parent, et ainsi bénéficier d’un héritage de ses templates (et l’appel de ses fonctions). Il est aussi possible de définir de nouveaux templates et de nouveaux comportements si besoin.

Toutefois, sur WordPress, cette possibilité n’existe que pour 2 niveaux, un parent et un enfant. Pour 3 niveaux d'héritage de thème, ou plus, il faut ajouter les modifications du deuxième niveau dans le thème du site.

Côté Drupal, il est possible d’enchaîner autant de niveaux de thèmes que nécessaire.

 

Plus de possibilités...

 

Créer des contenus personnalisés avec des contrôleurs

Sur Drupal, il est possible de créer facilement, via le code, une page complètement personnalisée. Contrairement à ce qui est généralement fait sur WordPress, il est donc possible de créer une page de contenu complètement codée sans générer un post dans lequel on glisserait un shortcode pour maîtriser la génération. Ceci évite notamment de polluer l’administration des pages avec un contenu créé uniquement pour y ajouter un shortcode comme contenu.

 

Des modules communautaires souvent extensibles

L’écosystème de modules de Drupal contient bien moins de choix que la quantité impressionnante de plugins WordPress. Il y a une bonne raison à cela ! Plutôt que de fournir plusieurs dizaines de modules différents pour un même besoin, Drupal propose généralement un seul module adapté à un besoin courant, parfois deux ou trois, mais très rarement plus.

Ce qui pourrait passer pour un manque de richesse est au contraire l’occasion pour la communauté de se regrouper sur un projet unique pour l’améliorer et l’enrichir. Chaque module est appréhendé de façon à le rendre le plus customisable possible. Un module principal fournit une structure avec de nombreux points d'accroche (hooks, plugins, eventSubscribers) et des sous-modules ajoutent des fonctionnalités à cette structure. Il est donc aisé pour un développeur qui utilise un module principal d'y greffer ses propres comportements métiers pour l’adapter à ses besoins.

Si certains plugins WordPress jouent très bien le jeu de l’extension, il m’est régulièrement arrivé de devoir contacter un développeur (que ce soit pour des plugins gratuits ou premiums) pour qu'il ajoute un filtre ou une action dans le module car celui-ci avait un comportement figé. Ceci génère des allers-retours avec le développeur et une perte de temps, etc.

 

Le système de Plugins

Créé avec Drupal 8, le système de plugins (à ne pas confondre avec les modules, qui correspondent aux plugins WordPress) permet une extension simple et élégante de comportements du site sur Drupal, qu’il s’agisse du coeur ou d’un module installé.

Le principe est simple : en implémentant une interface donnée, en respectant une convention de nommage et en utilisant les annotations, on crée une classe qui sera découverte par le site afin d’ajouter la classe de son choix dans le système.

Ainsi, pour créer un bloc au comportement personnalisé, il faut :

  • Créer dans le module un fichier dans le dossier src/Plugin/Block/MyBlock.php ;
  • Créer la classe qui doit implémenter BlockInterface (dont les méthodes sont relatives à l’affichage, l’accès et la configuration du bloc). La classe est alors reconnue par le BlockManager de Drupal et disponible à l’utilisation dans l’administration.

Pour aller plus loin, s’il est possible de créer un plugin (dans ce cas, un bloc) par classe, il est possible de créer un système (dit de Derivative) qui permet de générer une multitude de Plugins dépendant d’une seule classe. Dans notre exemple, Drupal a implémenté la BlockInterface avec une classe configurée pour générer un bloc par entrée dans la base de données dans la table block.

Ainsi, chaque module créé peut à loisir proposer des plugins aux managers de Drupal afin de proposer des comportements supplémentaires.

De la même façon que des managers existent dans Drupal, il est en plus possible de créer ses propres PluginManager afin de fournir un comportement extensible sans toucher au module de base.

 

Performances : DB / Cache granulaire

Drupal, bien que plus lourd que WordPress, offre de meilleures performances. Drupal a tendance à mieux tenir la montée en charge des données et du trafic.

Les choix d’architecture de la base de données sont très différents. Comme évoqué plus haut, WordPress stocke toutes les données relatives à un post dans une table unique de métadonnées, avec un jeu de clés (postId + nom de la méta) lié à une valeur. Cette table prend rapidement de l’ampleur. Les éléments tels que cette unicité de table, l’impossibilité de créer des jointures claires ou le non-typage des données empêchent à WordPress de rester fluide sur ses requêtes de données si la base de données grossit.

D’autre part, WordPress n’a nativement pas de système de mise en cache des contenus. WordPress recharge tous les contenus du site à chaque appel. Certains plugins, tels que wp-rocket permettent d’obtenir des affichages plus rapides. Mais ceux-ci ne vont généralement agir que sur le contenu disponible pour les utilisateurs anonymes, à moins d’une configuration poussée.

Du côté de Drupal, une gestion du cache présente nativement permet de choisir, pour chaque élément de contenu sur chaque page, le comportement de la mise en cache pour celui-ci.

Ainsi, il est possible de définir qu’un bloc aura une mise en cache :

  • Par contexte (exemple : un bloc peut être mis en cache pour chaque utilisateur),
  • Par durée,
  • Et/ou liée à un tag de cache, qu’il est possible d'invalider à tout moment (exemple : une page affichée sera mise en cache avec un tag correspondant à “type_de_page:id”, et à chaque édition de cette page, ce cache sera invalidé).

 

Multilingue

WordPress est nativement prévu comme étant monolingue. Des plugins (comme wpml) permettent d’ajouter la gestion de plusieurs langues. Ces plugins ne sont pas forcément simples d’accès et sont souvent incompatibles avec d’autres plugins installés sur le site.

Drupal est nativement prévu pour gérer une ou plusieurs langues. Tous les plugins contributions sont prévus pour ce multilingue et la configuration habituelle d’un site multilingue (domaines différents, bloc de switch de langue, croisement des différentes langues dans l’HTML avec les hreflang) est disponible simplement.

Pour un développeur PHP qui travaille sur des CMS, il est, pour de nombreuses raisons, plus agréable de travailler sur Drupal que sur WordPress.

Dans le cas de projets de moyenne à grande taille, le développement sur Drupal permet plus facilement une personnalisation totale des comportements et d'obtenir un résultat attendu plus rapidement avec un code plus maintenable pour les futures évolutions.

Image mise en avant pour l'article
Jean-Pascal Langinier Linkedin
Développeur @ADIMEO
De l'urgence de migrer sur Drupal 9 : conseils et bonnes pratiques
Voir le webinar !
WEBINAR
WordPress ou Drupal ? Faites le meilleur choix !
Voir le webinar !
Besoin de créer ou de refondre votre site Web, mais vous ne savez pas quelle solution technique choisir ?
Faites confiance à nos experts techniques. Selon vos besoins, ils vous orientent sur la meilleure solution pour votre projet.
Contactez-nous