Django-CMS, le meilleur outil de gestion de contenu (CMS) ?

- Article in english

Django CMS Logo

Au sein de Naeka, notre objectif principal n'est pas la conception de simples sites web, nous nous orientons plutôt vers ce que l’on appelle “applications”, qui apportent leurs spécificités, leurs complexités, leurs lots de surprises, qui en font des projets intéressants sur lesquels nous aimons plancher. Généralement, nous avons de tels besoins que nous sommes amenés à tout gérer en propre, si bien que pour plusieurs de nos projets nous n’employons Django que pour le backend en donnant part belle aux frameworks Javascript que sont Angular ou Ember (notre chouchou) pour le frontend. Certains clients ont cependant le besoin d’avoir la main sur leur application web, pouvoir la faire évoluer en fonction du développement de leur organisation et ne souhaitent pas seulement modifier le contenu, mais aussi pouvoir modifier la structure et démontrer leur dynamisme sans repasser par la case prestation de développement. Nous étions familiers avec les précédentes versions de Django-CMS avec lesquelles nous avions été amenés à travailler auparavant. Au début de l’année, nous avons découvert, testé, beaucoup testé, puis apprécié la toute nouvelle et majeure version de Django-CMS, alors en “beta 3.0”. Depuis sa sortie, nous avons réalisé deux applications web qui en tirent profit. Cet article est en quelque sorte un retour d’expérience sur une (re)découverte captivante tant les nouveautés et améliorations sont nombreuses.

Django-CMS est open-source, un grand nombre de contributeurs ont participé à son développement, en grande partie sous l’impulsion de Divio, une agence web Zurichoise dont l’équipe est à l’origine de plusieurs autres projets Django. Et quoi de mieux pour cette agence que de baser son développement selon des besoins concrets de leurs (importants) clients ? Le succès et la reconnaissance sont là, en plus de sept ans de loyaux services, le CMS a été largement adopté par la communauté Django.


Que permet-il de réaliser ?

Django-CMS gère parfaitement tout ce que l’on trouve généralement parmi les fonctions d’un CMS, à savoir :

  • Une gestion hiérarchisée des pages
  • Un éditeur de contenu simple et puissant
  • Une gestion de médias, du drag ‘n drop, du “clic-clic”
  • Un workflow de publication, de la modération puis des rôles et permissions fines
  • Le versionnage, accompagné d'outils de “roll back”
  • Une isolation de la version en ligne et du brouillon, la prévisualisation de ce dernier
  • Une version multilingue des pages, le “fallback” automatique et configurable
  • Un système de recherche

Il suit la même philosophie et tire donc parti de fonctions de Django et gère par exemple le “Sites Framework”, le contenu peut être commun à plusieurs sites et être issu d’une source commune. Il tire également profit de l’administration Django qui permet de générer automatiquement l’interface de configuration rendant le développement d’extensions particulièrement rapide. Il possède son cache, à plusieurs niveaux (pages, menus, etc.), basé sur Django qui permet de considérablement réduire la charge tant certaines pages peuvent générer grand nombre de requêtes en base de données. Pour finir, Django-CMS ne réinvente pas inutilement la roue et sait tirer parti de très bonnes apps Django pour ses propres besoins tels que hvad pour le contenu multilingue, haystack pour une recherche facile et efficace, mptt pour une modélisation hiérarchique ou encore django-polymorphic pour certains modèles exotiques.


Les avantages

En un mot : la personnalisation.

Django-CMS a été construit comme une base qui ne demande qu’à être étendue. Étant donné que c’est très basique, l’apprentissage peut être long, mais on ne se retrouve pas dans une situation bloquante à un certain point, ce qui en définitive s’avère positif.

L'approche des menus est intéressante : ce sont eux qui structurent l’application. Lors de la création d’une page, une entrée de menu lui est automatiquement affectée.

À partir de là, plusieurs options sont offertes aux développeurs et intégrateurs :

  • Une page peut être ou non présente dans la navigation
  • Les menus sont auto-générés sur plusieurs niveaux (simplement adaptable pour Bootstrap par exemple)
  • Le nombre de niveaux à afficher est personnalisable, si bien qu’il est parfaitement possible d’avoir différentes zones de navigation :
    • Le menu principal dans un header à un ou deux niveaux pour un accès rapide et simple aux différentes catégories
    • Un menu secondaire, dans une sidebar par exemple, à un ou deux niveaux basé sur le contexte courant. Ainsi si l’on est au second niveau de notre site, il listera les enfants du second niveau courant.

Ainsi, une navigation avec une profondeur de 4 niveaux comme celle-ci

django-cms tree

peut etre simplifiée avec cette approche :

django-cms representation

Et ce qui est magique, c’est qu’il n’y a rien à coder pour arriver à ses fins, et de nombreux autres cas d’utilisation sont facilités de la même manière.

Les menus utilisent des templates intelligemment splités, ce qui permet de les override au minimum pour les adapter au toolkit graphique utilisé. Enfin, parce que l’on peut souhaiter une structure différente pour un menu secondaire (telle que la sidebar) ou pour un menu dédié au tactile ou aux petits écrans, le tag show_menu (et ses dérivés) acceptent tous un argument template.

Bref, du côté de l’intégration, on n'est pas limité et on se trouve vraiment libre de concevoir une navigation simple et efficace lorsque l’on a une structure complexe et fortement imbriquée. Côté Python, en revanche, on se souviendra que la structure repose sur MPTT, on veillera donc à ne pas abuser de la profondeur afin de ne pas ralentir la navigation en complexifiant les requêtes SQL.

Concernant les breadcrumbs, on ne les utilise pas toujours, mais selon la structure, c’est quelque chose qui peut s’avérer vraiment utile. La gestion est simple, repose sur les menus et se personnalise très rapidement en fonction des besoins.

Gérer un site de pages statiques est somme toute assez banal et bien heureusement, Django-CMS ne se limite pas à ça. Il offre en effet deux moyens pour étendre le CMS :

Les plugins : basiques mais incroyablement simples.

Ils peuvent être placés à plusieurs endroits du site et seront par exemple : la liste des 10 derniers utilisateurs inscrits, une visionneuse de PDF, un lecteur Dailymotion, etc. Ils ont leur propre modèle, utilisé pour leur configuration (celle-ci se fait dans une popup directement sur le frontend, et repose sur l’admin Django : tout est auto-généré !). Ils ont également leur propre vue et template pour présenter leur contenu et peuvent accéder au contexte de la page sur laquelle ils sont inclus). En définitive, tout ce qui se met dans un placeholder est plugin : texte, lien, image, colonnes. Un truc puissant et spécifique avec cette version 3 ? Les plugins peuvent être imbriqués, ça apporte pas mal de possibilités (sliders, etc.) !

Les “App-hooks” : le grand jeu.

Ils permettent ni plus ni moins d’inclure une app Django en tant que descendant d’une page. Les apps peuvent être tirées de son propre projet ou bien provenir des milliers d’apps Django disponibles. L’urlconf de l’app peut être directement employée pour générer la navigation ou peut être recréée dans un fichier cms_app.py qui contiendra la configuration de l’app-hook.

Avec les app-hooks, le CMS n’a plus de limite et il devient tout à fait possible d’inclure un développement très spécifique à un site institutionnel.

Il y aurait tellement à dire, tant les possibilités sont diverses et nombreuses, mais on resterait dans l’abstrait et ce serait assez rébarbatif. C’est pourquoi je vous invite, si vous souhaitez en apprendre davantage là-dessus, à regarder cette présentation vidéo condensée des app-hooks (en anglais, 56min, par Martin Koistinen, core developer Django-CMS).

Quand j’évoquais la personnalisation un peu plus haut, il fallait bien comprendre que tout peut être modifié : les pages, les menus (également au runtime selon le contexte), l’admin et aussi la “toolbar” utile au staff pour administrer le site.

Enfin dernier avantage qui mérite d'être souligné : leur API.

C’est une API interne (n’allez pas imaginer du REST) qui va vraiment faciliter la gestion du CMS lors de traitements automatisés. C’est simple, très simple même, mais ça contient les procédures qui vont bien pour par exemple créer une page, (dé)publier une page, gérer les plugins de ses placeholders.

Ça nous a particulièrement été utile à deux occasions pour deux de nos projets :

  • Quand on a intégré une API REST (avec Tastypie cette fois) : il nous a fallu par exemple publier/dépublier telle ou telle page en fonction de la présence ou non d’objets.
  • Quand on a eu à migrer du contenu issu de Spip. Funky.

Django-CMS : les pistes d’amélioration

  • Un système générique pour une version draft/live qui puisse être utilisé pour tout app-hook avec un PlaceholderField. Car actuellement, quand un utilisateur édite le contenu d’un placeholder, ça part directement en live. Pour l’utilisateur final (pas forcément à l’aise avec l’informatique), le comportement n’est pas cohérent avec celui des pages classiques ou des placeholders statiques où l’on édite le brouillon tranquillement et autant de fois que l’on veut, puis on le publie de manière explicite en cliquant un bouton. C'est alors assez complexe comme amélioration, ça demande une approche différente car il faut deux placeholders (un draft, un public, si on conserve la logique de Django-CMS, ça pourrait éventuellement être composé via un mixin), mais il faut surtout revoir la procédure de publication et ça j’ai bien peur que ce ne soit pas une mince affaire...

  • Référencement du contenu externe (issu des app-hooks) depuis l’éditeur de texte. Il est en effet impossible de faire un lien vers un contenu enfant d’un app-hook, alors même qu’on lui attache un menu. Bon, c’est pour la simple et bonne raison que le plugin Link a une FK vers une Page. C’est tout de même assez déroutant pour ceux qui ne font pas forcément la distinction entre une page en propre du CMS et celle gérée par un app-hook. D’autres plugins comme “styledlink” s’adressent à cette problématique, mais c’est regrettable de ne pas avoir une solution out of the box.


En conclusion

Si Django-CMS ne révolutionne pas particulièrement le monde des CMS par son interface, sa complétude puis ses possibilités en terme de personnalisation font de lui un très bon CMS, à recommander. Et c’est certainement pour cette raison qu’il serait le CMS le plus utilisé parmi les très bons propulsés par Django (Mezzanine, FeinCMS ou encore le récent mais très prometteur Wagtail pour ne citer qu’eux).

Par ailleurs, son importante communauté, l’aide accessible sur Google Groups, Stack Overflow, les tutoriels complets à disposition en font un système facile et rapide à prendre en main. Les plugins sont également simples à réaliser et on peut compter sur tous ceux existants, plus nombreux de jour en jour, comme source d’inspiration dès lors que l’on atteint un point de complexité, non détaillé par la doc ou les tutos, voire bloquant.

Enfin, nous trouvions Django-CMS 2.x difficile d’accès pour certains utilisateurs. Depuis la 3.0, le frontend-editing et l’utilisation de CKEditor, c’est plus clair, plus simple, plus fonctionnel.