'>

modules Features, Spaces et Context au drupal

Ceux qui ont suivi le lancement du projet Open atrium ( http://openatrium.com/ , un distribution drupal pour créer un intranet) auront sans doute entendu parler du trio de modules context, spaces et surtout features; autour desquels est structuré ce projet.

Il existe encore peu de documentation à ce sujet, voici donc un bref aperçu permettant de saisir dans les grandes lignes l'intéret, et le potentiel énorme de ces modules. Notons tout de même avant toute chose que le module features est plutôt destiné aux professionnels de Drupal.

A quoi sert features ?

La pierre angulaire d'open atrium est le module features, qui tente d'accomplir deux nobles objectifs : - faciliter le déploiement de projet drupal (réutilisabilité / transportabilité accrues) - faciliter le "staging" ("comment que je mets mon site en ligne à jour sans écraser la base de données et donc perdre le contenu rentré entre temps par mes visiteurs ??" )

En dehors de ces deux objectifs fort louables, on peut se risquer à dire qu'en plus, le paradigme proposé par features n'est pas sans élégance, mais nous y reviendrons.
Un peu de théorie

Features peut être considéré comme une "couche supplémentaire" de Drupal. Jusqu'ici on pourrait théoriser (à la hache) Drupal comme étant constitué en 3 niveaux principaux.

    PHP : le langage dans lequel est codé Drupal
    API de Drupal : codée en PHP, elle offre une librairie de fonctionnalités faciles à manipuler pour faciliter le développement de module (systeme de theming, hooks, tout ça)
    Modules : bâtis sur l'API, ils permettent de répondre à un certain besoin utilisateur. Ce niveau est le plus facile à manipuler puisqu'il ne nécessite pas de connaissances en php pour être mis en place

A partir de là, il est intéressant de noter que plus le temps passe, et plus drupal tends à nous fournir des modules qui ne sont que des petites briques, qui combinées à d'autres petites briques, permettent de reconstruire soi-même une macro-fonctionnalité / un besoin utilisateur. Par macro-fonctionnalité, j'entends par exemple : un gestionnaire de tâches, un blog, un forum ...

Par exemple les champs CCK, le module views, le module node reference sont des modules qui ne fournissent aucune fonctionnalité en eux même, en revanche ils vous permettent de créer , avec de l'huile de coude tout de même, un systeme multiblog, un gestionnaire de taches ... bref ce sont des legos techniques à la disposition de votre imagination délirante de drupalien fou. C'est d'ailleurs pour cela que drupal, plus qu'un CMS, est un CMF (content management framework).

Mais une fois toutes les vues, champs cck , blocs etc... crées pour notre macrofonctionnalité qui tue la mort, se pose une question terrible s'il en est : et si je veux refaire cette fonctionnalité sur un autre site ensuite ? il faut refaire toutes les vues, tous les champs CCK, que je replace tous mes blocs un par un ? Votre pomme d'adam s'étreint d'émotion à l'évocation de cette hypothese peu ragoutante.

Halte là ! features vous propose une solution : "enregistrer" et capturer, en quelques clics toute votre travail de configuration dans un module. Il vous suffira ensuite d'installer votre module sur une install vierge de drupal et ô joie ! toutes vos vues , vos champs CCK, vos blocs, vos presets imagecache se recréent tous seuls comme par magie. Features vous permet de "packager" vos configurations puis de les importer sur un autre site. Plus que ça, features fait de son mieux pour que votre configuration puisse en plus vivre "dans le code" uniquement, c'est à dire que votre vue peut parfaitement être utilisable en étant bien au chaud dans un hook, dans le code de votre module. Il n'est pas nécessaire qu'elle soit enregistrée dans une BDD. On retrouve donc doucement l'idée que la base de données doit servir à enregistrer le contenu de l'utilisateur tandis que la configuration reste dans le code.
Une autre approche de Drupal avec Features

Le module Features se propose donc d'ajouter un nouveau niveau à Drupal, qui ressemble alors à ceci :

    PHP
    API
    Modules
    Features

En combinant différents modules, on peut obtenir une fonctionnalité précise que l'on peut packager dans une features. Hélas, la portée de features reste encore relativement limité sur Drupal 6, la liste des modules compatibles étant plutôt restreinte : views, cck, context, panels, imagecache, menu, les droits d'accès (j'en oublie sans doute deux ou trois)

Néanmoins ne jetons pas le bébé avec l'eau du bain : si features est loin d'être la solution idéale, c'est aussi une des solutions les plus prometteuses et élégante de ce côté. De plus, malgré le nombre de module assez restreint supporté, cela reste toutefois suffisant pour construire de très jolies features. Open atrium reste une bonne démonstration des possibilités de ce paradigme. Enfin, il ne faut pas oublier qu'il est tout à faire possible de rajouter du code php dans une features puisqu'il s'agit d'un module comme un autre, si ce n'est que son fichier .info contient des informations permettant d'importer automatiquement des vues, des champs CKK etc...
Spaces

La notion d'espace est liée à celle de feature : une feature peut être activée, désactivée pour un espace particulier : ainsi si vous utilisez organic groups + spaces, vous pouvez proposer à chaque groupe d'activer ou de désactiver des features selon leur besoins, et cela indépendamment des autres types de groupe. Open atrium fonctionne principalement avec des espaces pour les organic groups et apparemment pour les profils (user-spaces).

Physiquement, la notion d'espace est en fait liée au module "purl" qui permet d'ajouter un préfixe à vos url. Ce préfix permet de déclencher l'espace et tous les paramètres de context ou des vues qui peuvent être sensibles aux espaces.

Exemple : avec user-space, l'url de votre compte devient "space-votrepseudo/user".

La notion d'espace est toute indiquée pour la gestion d'un intranet en particulier et a probablement été spécifiquement conçue pour ce besoin particulier, mais on peut imaginer bien d'autres applications, d'autant que spaces 3 promet (encore) une petite révolution conceptuelle.
Context

Context est un module permettant de facilement regrouper des éléments de configuration d'une feature. Exemple concret : si vous voulez faire une feature de blog, vous souhaitez que fasse partie de votre feature :

    une vue listant vos derniers billets
    un bloc listant les derniers commentaires
    que ce bloc apparaissent sur les types de contenus blogs et peut être aussi sur la vue

Qui n'a jamais révé d'expliquer par exemple simplement à Drupal que la vue listant vos types de contenu news fait partie de la même section du site que vos node news ? Et qu'il est en conséquence logique que votre item de menu "news" soit en surbillance quand vous vous trouvez sur la page de liste de news ? C'est typiquement ce genre de problématique à laquelle s'attaque context.

Context est un module permettant de centraliser et d'exporter tous ces paramètres de configuration et donc devient un élément clef pour composer votre feature. En général, pour composer votre feature vous avez besoin d'un contexte permettant de choisir quel blocs et vue font partie de votre feature, comment ils sont positionnés (plus d'autres paramètres intéressants proposés par context). Nulle obligation de passer par contexte, mais cela facilite la construction de votre feature.

Vous pouvez ensuite exporter dans la feature (en créant la feature dans le menu feature) en prime bien d'autres choses intéressantes comme un type de contenu, des champs CCK, un élément de menu, une permission utilisateur etc...
Impact sur votre workflow de production

Vous venez de changer une vue en local et vous souhaitez voir le résultat sur votre serveur de production ? si votre vue fait partie d'une features et que vous utilisez l'excellentissime module drush (si vous ne le connaissez pas, foncez tout de suite le télécharger), il vous suffit de mettre à jour votre features en une ligne de commande : - drush features-update votre_features

pour mettre à jour dans votre code la vue. Plus qu'à commiter sur le serveur de prod pour voir le résultat ! Utiliser drush et features reste le moyen le plus rapide et efficace de mettre le maximum de configuration dans le code et l'exporter / mettre à jour avec facilité. (une ligne de commande drush, y'a pas plus rapide, plus qu'à se préparer une tisane pendant votre "features-update-all").
Inconvénients du module Features :

    Tous les modules ne permettent pas d'être capturés par features; et cette logique de feature ne fait pas partie de la logique du coeur de Drupal. Ca reste donc une solution intéressante mais pas pleinement implémentée et fonctionnelle dans Drupal. Les modules doivent notamment implémenter certains hooks pour être découverts par features et disposer idéalement d'une configuration exportable/importable en php (comme le module views possède cette possibilité d'export); ce qu'ils ne proposent pas tous.

   

Prise en main détaillée des modules context et features
Introduction à Features and Context

Avertissement : cet article s'adresse plus particulièrement à des utilisateurs avertis ou des professionnels de Drupal. Il se veut une aide pour prendre en main le trio de modules spaces/context/features dont la documentation reste laconique pour le moment. Module requis pour suivre l'exemple donné dans cet article

    Context http://drupal.org/project/context

    Feature http://drupal.org/project/features

    CCK http://drupal.org/project/CCK

    Views http://drupal.org/project/views

    Image field http://drupal.org/project/imagefield

Il est fortement conseillé d'utiliser le theme Garland pour suivre cet article; tous les thèmes n'étant pas forcément compatible avec le module context. Je reviens sur ce point en fin d'article.
Théorie : Pourquoi utiliser context et features

Il y a peu de temps, la société Development Seed annonçait la sortie d'Open atrium, un intranet bâti sur Drupal et donc la structure repose en grande partie sur trois modules : spaces, context and features. Plus que de simples modules développés uniquement pour l'occasion, spaces context et features se veulent une véritable redéfinition de la manière de développer Drupal. Ces modules apportent en partie une solution aux problématique suivantes que rencontrent ceux qui font de nombreux sites avec Drupal :
1 - On refait souvent sur un site ce qu'on avait fait à l'identique sur un précédent site

On se retrouvent souvent à combiner puis configurer les même modules pour répondre au même besoin. Par exemple peut être que pour chaque nouveau site, vous créez un type de contenu « news », avec un champ CCK « image field », lui même utilisant un preset du module « image cache » afin que votre client puisse poster régulièrement des actualités sur son site, assortie d'une image retaillée à la volée par image cache. Ne serait-il pas pratique de pouvoir « sauvegarder » tout ce travail de configuration pour pouvoir ensuite l'importer sur un autre site sans avoir à tout refaire ? C'est ce que permet features.
2 - Probleme de mise à jour d'un site en ligne et de workflow de production :

Si vous diposez d'un site en ligne, et que vous souhaitiez importer sur celui-ci les dernières fonctionnalités développées dans un environnemt local, vous devrez faire deux choses :

importer en ligne les fichiers qui ont changés écraser la base de données du site en ligne pour la remplacer par celle du site en local

En effet votre base de données locale contient toute la configuration des modules que vous venez de savamment ajuster. Problème : écraser la base de données du site en ligne signifie aussi écraser le contenu (les articles) du site en ligne ! Features propose une alternative à cette manière de procéder en exportant la configuration de vos modules dans un fichier PHP (sous forme de module Drupal que l'on peut activer/désactiver). En uploadant ce fichier sur le serveur, vous pouvez mettre à jour la configuration de vos module sans être contraint d'écraser votre base de données de destination.
3 - Manque de lisibilité de l'administration d'un site Drupal :

Pour créer une fonctionnalité poussée sur un site Drupal, vous allez utiliser (par exemple) une combinaison plus ou moins complexe de champs CCK, de différentes vues, de placement de blocs avec leurs paramètres de visibilité; cela dans le but de répondre à un besoin utilisateur bien défini et facilement formulable tel que « créer une galerie d'images » ou « pouvoir poster une news sur le site ». Pourtant en ouvrant ensuite votre administration de Drupal; rien ne montre clairement que tels champs CCK + tel type de contenu + telles vues + tels blocs + tels modules travaillent ensemble pour permettre la création d'une galerie d'images. Vous êtes le seul à le savoir. Au fur et à mesure que votre site grossit, il devient de plus en plus difficile de s'y retrouver dans une administration devenue un véritable jungle de formulaires de configuration. Tous vos réglages sont physiquement éparpillées aux 4 coins de la base de données sans vous donnez aucune possibilité de vue d'ensemble de votre travail de configuration.

Context et features permettent en partie de retrouver une solution à ce souci de lisibilité. Si vous construisiez votre site en vous basant autant que possible sur ces modules, vous pourrez alors voir dans la page d'administration de features en un coup d'oeil toutes les features que vous avez développé pour le site; et en cliquant sur une feature en particulier vous pouvez observer la composition d'une features qui vous indique avec quels modules elle fonctionne, de quel module elle dépend etc.... De même, la page context permet également facilement de voir quels sont les blocs et type de contenus associés sur une section particulière du site.
En pratique : Comment utiliser context ?
Créer les éléments pour construire un blog simple

Prenons un exemple concret: Imaginons qu'un client, qui utilise Drupal pour son site vitrine, souhaite ajouter sur son site un espace réservé à un petit blog qui décrira au jour le jour l'activité de son entreprise. Pour ce faire, nous allons créer un type de contenu « billet_de_blog », et nous allons créer une vue « blog » avec pour chemin « blog », qui sera chargé de lister les teasers avec pagination de tous nos types de contenus « billet_de_blog ». Pour rendre le tout un peu plus sexy nous allons aussi ajouter :

un bloc avec les dernières commentaires postés sur le blog, en utilisant une vue de type bloc. un bloc « archive » qui va permettre au visiteur de voir tous les articles d'un mois particulier en cliquant sur le nom d'un mois. Une page « archive » fournie par une vue, qui permet de naviguer dans les articles d'un mois donné. (par exemple : voir tous les articles du mois de novembre)

Nous allons aussi utiliser le module image field afin d'ajouter à notre type de contenu un champ CCK qui permettra à notre client d'uploader une image pour chaque article. Pour la vue en archive, utilisez tout simplement celle (désactivée par défaut) que propose le module views, il vous suffit de l'activer pour qu'elle soit opérationnelle ainsi que son bloc avec la liste des mois cliquables. Il vous faudra simplement ajuster le filtre de la vue pour qu'elle ne liste que le type de contenu « billet_de_blog ».
Utiliser context pour mettre nos blocs en place

Une fois tout cela crée, nous allons entrer dans le vif du sujet et commencer par placer nos blocs « derniers commentaires » et « archive list » dans la colonne de droite de notre blog. Pour donner l'impression d'un espace homogène sur tout le blog, nous voulons logiquement que ces blocs s'affichent en réalité à trois endroits différents :

    sur notre vue listant nos articles

    sur nos articles proprement dit lorqu'il sont vus en « full node »

    sur notre vue archive

C'est l'assemblage de ces trois entités distinctes qui va définir l'espace de notre blog. Context va justement nous servir à créer une définition de cet espace, et à ensuite placer des blocs dans des régions lorsqu'on se trouve dans cet espace.

Surtout, c'est très important, ne vous rendez PAS dans la page des blocs classique de Drupal pour placer vos blocs car c'est avec le module context qui nous allons gérer désormais leur positionnement : or context ne peut gérer le positionnement d'un bloc que si celui-ci n'est PAS positionné au prélable par la page de gestion classique des blocs.

Installez donc le module context si ce n'est pas déjà fait puis rendez vous dans l'onglet construction du site où frétille maintenant d'impatience un nouveau lien « context ». Ajoutez un nouveau context qui va nous servir à définir notre contexte « blog ». Alors là normalement si c'est la première fois que vous utilisez context vous devriez lever votre sourcil gauche en marmonnant un grognement circonspect à la vue des trois premiers champs qu'on vous demande de remplir pour la création d'un context : « namespace », « attribute» « value ». On boit une gorgée de café et on garde son sang-froid.

En gros imaginez d'abord cela comme un systeme pratique de classement : tous les contextes qui auront un « namespace » et « attribute » identiques seront classés ensemble. Si vous avez une quinzaines de contextes sur un site, ils seront regroupés par espace (namespaces) / attributes identiques. A cela s'ajoute le fait que features pouvant fonctionner de paire avec le module spaces, il semblerait que la convention de nommage « spaces » pour le namespace et « feature » pour attribute permettent au delà du simple classement de tirer parti du module « space », mais je n'en suis pas sûr ...

Le module space mériterait en lui même un article et n'a pas de rapport direct avec notre problématique pour le moment. Toufefois, pour satisfaire les plus curieux, vous pouvez concevoir les « spaces » comme des sections de votre site pour lesquelles vous pourrez activer ou désactiver des features. Chaque espace pouvant activer une feature sans que la même feature sur un autre espace soit activée. C'est ce qui vous permet dans Open Atrium d'activer ou de désactiver de grosses fonctionnalités (blog, casetracker, shoutbox) en fonction d'un organic group; car le module spaces dispose d'une extension spécifique pour organic groups. Donc les espaces sont à imaginer comme des « prises » pour brancher les features, une section du site où elles deviennent valides. Physiquement, les espaces peuvent être visibles grâce à un préfixe d'url ajouté par le module « purl » (requis pour faire tourner spaces).

Mais revenons à notre contexte :

Pour l'instant, un remplissage possible de 3 propriétés de votre contexte serait par exemple :

    namespace : « communication » (Le blog est un outil dont le client se servira pour communiquer en temps réel sur la vie interne de sa société.)

    attribute : « blog » (peut être mettrez vous plus tard à disposition de votre client d'autres outils de communication, comme une galerie photo ou des podcasts etc...)

    value : « partie_publique » (on peut imaginer que vous créiez un autre contexte ensuite qui auront le même namespace et attribute mais avec pour value « partie_admin »; contexte que vous utiliseriez pour offrir au client une page d'admin lui permettant de gérer son blog comme sur un vrai blog de type wordpress).

Vous avez aussi un petit champ description pour exprimer avec une prose condensé l'essence intime de ce contexte à vos yeux. Si vous avez un seul contexte sur votre site, vous auriez tout aussi bien pu marqué dans chacun des champs « blog » et cela aurait tout aussi bien fonctionné. Mais sur un site plus important, il sera bon de rationnaliser comme je viens de le faire vos contextes pour gagner en clarté. De plus, ce travail de formulaire oblige à une certaine clarification / classification des besoins utilisateurs à développer, ce qui ne peut pas faire de mal.

Maintenant on s'attaque au plus fun : configurer votre contexte. Vous allez notamment vous apercevoir à l'usage que context permet de placer/déplacer des blocs beaucoup plus vite que par l'interface classique des blocs, (qui en plus rame particulièrement et s'avère peu ergonomique quand un site dispose de nombreux blocs).

L'interface de configuration de context se divise en trois grandes parties :

    les conditions : qu'est ce qui va déclencher l'activation de votre contexte « communication > blog > partie publique «  ?

    les réactions : qu'est ce qu'il se passe quand ce contexte est actif ? Elles sont assez limitées pour l'instant; on peut désactiver une région entière du template, envoyer 3 nouvelles variables à notre page.tpl.php , rendre un item de menu actif. Les variables sont intéressantes puisqu'elle permettent d'afficher dans votre theme le titre de la section à travers tout le contexte. Dans notre cas, on pourrait afficher « le blog de la société ».

    Le placement / la visibilité des blocs dans ce context. Quels blocs va afficher notre contexte et dans quelle région ? Choisissez un bloc dans la partie droite plus cliquez sur « add » dans la partie gauche de la région visée.

Concernant les conditions et les réactions, les développeurs seront ravis d'apprendre que le module context vous proposent une séries de hooks permettant de créer très rapidement et très facilement de nouvelles conditions / réactions pour enrichir context sans hacker le module.

Nous voulons que notre contexte soit actif dans les conditions suivantes :

    quand on se trouve sur un type de contenu « billet_de_blog ». cliquez simplement sur « node pages » puis cochez le type de contenu pré-cité.

    Quand on se trouve sur la vue « archive » et la vue « blog ». Cliquez sur « views » et sélectionnez les vues. (déjà à ce stade vous devriez déjà vous rendre compte qu'en 4 clics vous faites la même chose, et bien plus rapidement, qu'avec un paté de 10 lignes de php pas lisible dans la configuration de visibilité d'un bloc).

Maintenant choissiez dans les blocs votre bloc « derniers commentaires » ainsi que le bloc « archive list » généré par la vue archives. Et voilà ! En vous rendant sur les types de contenu blog et sur vos vues, vous constaterez la présence studieuse de vos blocs.

Au passage on peut signaler un autre avantage de context qui n'est pas des moindres : si pour une raison X ou Y vous devez afficher ces mêmes blocs sur un autre type de contenu, l'affaire sera réglée en quelques secondes. En passant par l'interface classique des blocs, il vous faudra ouvrir chaque bloc, modifier votre code php dans la visibilité des blocs, ce qui conduit assez vite à la déprime si cela concerne dix blocs.

note importante : pour placer les blocs, il est impératif que votre theme n'utilise pas un override de la fonction « theme_blocks » (dans template.php). Si c'est le cas, le placement des blocks de context ne fonctionnera pas. A noter aussi un conflit avec le module i18n, car il n'est pas possible d'afficher un bloc avec context en fonction de la langue. Toutefois il reste possible de placer des blocs dont l'affichage est indépendant de la langue, à condition toutefois d'allouer un poids supérieur au module context dans la table system.

Pensez aussi maintenant à ajouter votre champ CCK sur le type de contenu « billet_de_blog » afin que l'utilisateur puisse uploader une photo sur son blog.
premières conclusions :

L'utilisation de context nous a permis en seulement quelques clics de définir des conditions complexes de visibilité pour nos blocs qui demanderait en temps normal un peu de php; tout en offrant en plus une interface (la page d'administration de notre contexte) permettant de voir en un coup d'oeil quels sont les blocs et vues qui travaillent ensemble pour définir notre espace de blog. Mais le plus grand intérêt de toute ceci n'est pas là : en utilisant context nous trouvons surtout le plus fidèle allié du module features, c'est à dire que tous ces réglages vont pouvoir désormais être exportés, et c'est là tout l'intérêt de notre démarche, qui permet de résoudre en partie le probleme de la mise à jour d'un site en ligne Drupal. Bref, tout ceci n'était que la première étape de notre plan machiavélique.
Exporter votre fonctionnalité blog avec le module features

C'est maintenant l'heure de vérité : installez le module features, puis rendez vous dans le menu « construction du site » et cliquez sur le nouveau lien « features ». Comme vous n'avez pour l'instant créer aucune feature, cette page doit être vide, nous allons donc nous empressez d'ajouter une feature pour y remédier. Choisissez le nom de votre feature : ce sera le nom du module que vous obtiendrez ensuite. Indiquez également la version, car vous exporterez sans doute votre feature plusieurs fois au cours de votre développement. Ignorez pour le moment le champ « update feed » : il vous servira quand vous travaillez avec un serveur de features qui s'avera un outil extrement pratique pour stocker de façon ordonnée et sûre vos créations (et qui, si il est en ligne, vous permettra de partages vos features avec les autres utilisateur de Drupal ).

Nous allons définir notre feature; c'est à dire que nous allons expliquer à feature quels sont les éléments composant notre fonctionnalité blog afin qu'il puisse exporter tout ça dans un fichier php (un module); ce qui nous permettra de l'installer ensuite en un seul clic sur n'importe quel installation Drupal sans avoir à recréer manuellement tout ce que nous venons de faire.

Vous devez disposez dans le formulaire de création de feature d'une liste déroulante pour choisir les « objets » faisant partie de votre feature : node, context, views, users etc... Sélectionnez en premier votre context, qui permettra de récupérer automatiquement un grand nombre d'informations concernant notre fonctionnalité blog. Ajoutez-y le type de contenu « blog » afin de récupérer les informations concernant le champ CCK que vous avez ajouté. Vérifiez que tous les éléments liés à votre blog aient bien été détectés et ajoutez ce qu'il manque au besoin. Vous remarquez que l'objet « user » de la liste déroulante vous permet d'exporter la configuration de certaines permissions Drupal ! Cela vous évitera d'avoir à passer par la page permission pour reconfigurer les droits lors de l'installation de votre feature sur un nouveau site ou lors d'une mise à jour.

Enfin, c'est une partie à laquelle il faut être très attentif, vérifiez que toutes les dépendances de votre features ont bien été détectées (c'est à dire les modules dont votre fonctionnalité blog à OBLIGATOIREMENT besoin pour fonctionner), et ajoutez en si vous pensez qu'il en manque une. Sinon, lorsque vous installerez une feature plus complexe, rien ne marchera comme vous l'espérez et rien ne vous indiquera que vous avez tout simplement oublier d'installer puis d'activer un module indispensable à son bon fonctionnement.

Une fois tout cela fait : cliquez sur le bouton « download » et, magie ! Vous pouvez télécharger votre features en tant que module !

Une fois cela fait, décompressez le fichier obtenu (une erreur se produit à la décompression mais pour ma part avec winrar cela n'affecte pas le fonctionnement de la feature, c'est un bug connu actuel qui devrait être résolu à la prochaine release), puis installez le, comme tout module qui se respecte dans votre répertoire modules. Ll'idéal est de créer un sous-dossier dans « sites/modules » permettant de rassembler toutes vos features, histoire de ne pas les confondre avec les modules classiques. Ensuite, il vous reste à activer cette feature; pour cela vous devez vous rendre à nouveau dans construction du site > features; ou vous devez voir maintenant apparaître votre nouvelle feature.

En réalité, ce que vous venez de faire ne change strictement rien au fonctionnement actuel de votre site; si ce n'est que désormais vos vues et contextes dispose de boutons « revert » fort pratiques vous permettant désormais de revenir à tout moment à la configuration contenue dans votre module. A partir de maintenant, si vous commencez à modifier une vue ou un contexte; en vous rendant sur la page feature vous verrez le statut de la feature passer de « defaut » à « overriden »; ce qui indique que vous avez apporté des modifications à votre fonctionnalité entre temps. En installant le module « diff » vous serez même en mesure de visuellement les changements que vous avez apportés par rapport à la feature originelle. Il vous est possible de revenir à l'état de la feature lors de son export en cliquant sur Revert. Si en revanche vous êtes satisfait des améliorations apportées entre temps à votre feature, il ne vous reste à l'exporter à nouveau puis à écraser l'ancien fichier avec le nouveau (en passant par l'onglet update dans la configuration de feature).

Voilà, vous disposez désormais d'une feature « blog » que vous pouvez installer à présent sur une nouvelle installation de Drupal. Celle-ci se chargera de replacer automatiquement vos blocs et de recréer vos vues. Ce petit exemple devrait vous permettre d'imaginer facilement comment tirer parti des modules context et features pour vos sites.
Conclusion

Il est temps maintenant de mesure les implications concrètes de ce que nous venons de faire :

    il vous suffit d'installer votre feature sur une nouvelle installation de Drupal pour pouvoir réactiver votre blog tel que vous venez de le configurer, en un seul clic. C'est un temps énorme économisé pour vos prochains sites qui rencontreront un besoin similaire.

    vous pouvez désormais mettre à jour le placement des blocs, des champs CCK, views etc.. uniquement en écrasant le fichier de votre module. Il n'est donc plus nécessaire d'exporter votre base de données pour communiquer des changements de configuration de modules.

    Vous disposez de la possibilité de revenir à la configuration par défaut de la feature en cas de gros pépins. Donc si vous sabotez involontaire votre super code php qui tue dans l'argument d'une vue, plus besoin de vous défenestrez parce que vous aviez oublié de sauvergarder la base de données ou d'exporter votre vue : cliquez sur « revert ». Il en va de même pour vos contextes.

    Vous pouvez partager votre feature avec les autres; donc vous pouvez aussi télécharger les features des autres. On conçoit les avantages qu'un tel module de normalisation des exportations de configuration de modules Drupal se mette en place. Tout le monde y gagnerait.

    Vous pouvez facilement faire un versionning dans vos features importantes : En installant un serveur de features (un profil drupal existe permettant de faire cela en 5 minutes), vous pourrez aisément centraliser les différents releases de vos features et entrez des notes primordiales quand à certaines choses importante à notifier pour le bon fonctionnement de la feature. Comme par exemple le theme dont elle dépend. Et puis comme le monde n'est pas parfait, il vous faudra aussi parfois tout de même retoucher deux ou trois paramètres de configuration à la main, features n'étant malheureusement pas compatible avec tous les modules; mais seulement actuellement avec quelques modules clefs pour le développement de site avec Drupal. Il est donc bon de noter sur votre serveur de feature, dans la description, les petits changements qu'il sera peut être nécessaire d'apporter une fois la feature activée pour que celle-ci fonctionne pleinement.

Limitations connues actuelles

    Le module features n'est pas magique et ne peux pas exporter la configuration de n'importe quel module. Actuellement vous ne pouvez vous en servir que pour exporter la configuration de views, les champs CCK, image cache, context (ainsi vous pouvez exporter le positionnement de blocs et leur visibilité). Concrètement, imaginons que vous exportiez votre feature en indiquant une dépendance au module « blog theme ». Blog theme permet à l'utilisateur de votre site de choisir son propre theme pour un blog. Peut être avez vous touché la configuration de blog theme pour indiquez à quel type de contenu s'adaptera le theme du blog. Ce paramètre ne sera pas exporté par features car blog theme n'est pas supporté par feature. Il vous faudra donc retoucher ce paramètre à la main ou, ou bien ajouter dans votre feature un petit module qui sera chargé lors de son activation d'automatisé ces réglages avec quelques hooks et requêtes sql.

    Le module context peut facilement être overridé par le theme au niveau du theme_blocks. Or le module context se sert justement de la fonction theme_blocks pour pouvoir placer les blocs dans votre theme. Si context s'aperçoit que le theme utilise déjà un override de la fonction theme_blocks (dans son fichier template.php), alors il laissera la priorité au theme et ne placera plus simplement aucun bloc. Sans vous le dire, ce qui peut surprendre.

    J'ai eu à faire à un cas ou la condition « path » refusait de marcher, sans doute un conflit avec un autre module mais je n'ai pas pu trouver lequel ni la raison de ce bug.

    Le module context est en conflit avec i18n : de plus, un bloc placé avec context s'affichera à la fois en anglais et en français si ce sont les deux langues utilisées sur votre site.

Ayez aussi bien à l'esprit la chose suivante : un contexte est lié à son theme. C' est un pacte signé par le sang; car context doit connaître les régions d'un theme pour pouvoir placer ses blocs. C'est tout à fait logique mais cela implique que pour vous servir de votre context; vous devez utilisez le thème pour lequel il a été crée; et donc qu'il est dépendant d'un theme en particulier. A noter tout de même également que beaucoup de themes ont en commun les région $left et $right; donc vous avez un une probabilité assez élevé que les blocs que vous avez placé dans la barre de droite se retrouve au bon endroit en utilisant un autre theme.

Autre point : Il n'est actuellement pas possible de choisir pour quel theme activé de Drupal votre contexte s'applique : il s'applique forcément sur votre theme par défaut. C'est très dommage car cela limite la puissance potentielle de ce module, mais cela sera très certainement corrigé dans la prochaine version du module car intrinsèquement il est tout à fait capable de gérer ce point sans problemes. Sur le dernier projet sur lequel j'ai travaillé, j'ai contourné cette limitation en renommant les régions de mon deuxieme theme avec les mêmes noms de régions que celle de mon premier thème. C'est parce que context a besoin de connaître votre theme pour afficher les régions disponibles qu'il n'est pas possible d'afficher actuellement un theme particulier en fonction du context. C'est une demande fréquente mais c'est en fait quasiment un contre-sens pour l'instant étant donné la manière dont le module fonctionne.

Malgré les mises en gardes que je vous adresse, qui sont parfois handicapantes, ne jetez pas trop vite le bébé avec l'eau du bain : ces limitations peuvent ne pas peser très lourd en comparaison des bénéfices apportés par le module: à vous de voir selon les situations. Context est un module encore jeune destiné à évoluer. Mais ça peut valoir le coup, quand vous avez plusieurs manières de procéder pour developper une fonctionnalité; de privilégier les modules exportables par context.
Autres modules existants pour exporter votre configuration

Les moyens suivants permettent comme features d'exporter vos paramètres puis de les importer. Ils ne sont pas forcément antagonistes avec features et peuvent sans doute être complémentaires. Je n'ai pas testé toutes ces possibilités je ne peux donc pas faire une comparaison.

    Le profil d'installation drupal. Très puissant mais un peu difficile à appréhender : il est l'outil idéal pour packager votre installation Drupal d'une manière ou d'une autre. Par exemple vous pourriez vous faire un profil d'installation « boutique-en-ligne » qui comprendrait ubercart et tous les modules nécessaires pour réaliser une boutique en ligne. Le profil d'installation se charge principalement d'activer et de paramètrer vos module selon vos instructions. Il vous suffit ensuite de faire une nouvelle installation de Drupal, de copier coller dans un dossier votre nouveau profil d'installation dans le répertoire profil, et de sélectionner le profil «boutique-en-ligne » à la place du profil « drupal ». Le profil d'installation peut surement faire très bon ménage avec le module features :-)

    module patterns : pas testé

    module deployment pas testé

Pour ma part, si je m'intéresse plus particulièrement aux modules context et features; c'est qu'ils sont utilisés par la société Development Seed et que de ce fait leur avenir et leur maintenance me semble assez sûr.



Comparaison du module patterns et du module features
N'hésitez pas à corriger les informations données ici , je n'ai pas la prétention de faire une véritable comparaison définitive, je donne simplement des pistes de réflexions pour ceux qui hésitent entre les deux.
Cet article ne demande qu'à être amélioré et ajusté par ceux qui connaissent bien le module patterns.

Vous trouvez en fichier attaché au bas de l'article un petit tableau comparatif, surement incomplet pour l'heure

http://drupalfr.org/sites/default/files/comparatif.png

Vous pouvez téléchargez le module patterns ici.
http://drupal.org/project/patterns

Notez enfin qu'il est tout à fait envisageable d'utiliser à la fois patterns et features en même temps sur un site selon le type de routine à automatiser.

Introduction

Patterns est un module très intéressant et ingénieux permettant d'écrire un fichier xml qui permettra, à son import, de configurer automatiquement des pans de votre site avec des informations de configurations très poussées. En rédigeant votre code xml (ou yaml ou php), vous pouvez créer des types de contenus, des champs CCK, des presets image cache, des nodes, des blocks, de la taxonomie, des utilisateurs. Son champ d'action est très large et le degré de précision impressionant. Je vous conseille vivement de lire l'article suivant sur drupalistic pour d'autres renseignements et un exemple sympa de pattern:
http://www.drupalistic.net/module/patterns

Comment fonctionne pattern ? exemple

Pour faire fonctionner pattern, nous devons rédiger un document xml que nous importerons ensuite dans l'administration du module patterns. Un pattern (et le fichier xml) est divisé en trois gande parti : description du pattern, modules requis, actions à effectuer lors qu'on lance le pattern.

cas utilisateur : nous voulons créer automatiquement un type de contenu news, en y ajoutant un champ image field.
La description de notre pattern

Ces quelques lignes permettent de décrire notre pattern. Ils sont indispensables.
<pattern>
  <info>
    <title>Actualités</title>
    <description>Créer une feature actualité sur un site</description>
    <author>Colonel Moutarde</author>
    <author_email>colonel.moutarde@gmail.com</author_email>
    <version>0.1</version>
    <category>Features</category>
    <core>6.x</core>  
  </info>
</pattern>
Les modules requis pour le fonctionnement de notre pattern

Maintenant on doit réfléchir aux module dont nous avons besoin : dans mon cas utilisateur je veux utiliser une champ image avec image field et controler la retaille d'image avec image cache. Image cache dépend de image api, image field dépend de file field et de content. On va aussi inclure le module Image cache UI pour pouvoir retoucher dans une interface utilisateur nos presets au besoins.
J'insére ceci juste après la balise de fermeture , pour déclarer les dépendances à activer :
<modules>
    <module>content</module>
    <module>imagefield</module>
    <module>filefield</module>
    <module>imageapi</module>
    <module>imagecache</module>
    <module>imagecache_ui</module>
    <module>views</module>
    <module>views_ui</module>
  </modules>
Les actions de notre patterns

On entre dans le vif du sujet. Créeons notre type de contenu « news ». Toutes nos actions devront être placés entre les balises actions. Je donne le nom machine et humain du type de conteu, je précise que je veux activer les commentaires, ne pas activer l'upload, que les news soient publiées par défaut, et que ce type de contenu ne soit pas promu sur la page d'accueil.
<actions>

      <content>
        <name>News</name>
        <type>news</type>
        <description>Permet de poster des news sur le site</description>
        <status>1</status> <!--Publié par défaut-->
        <promote>0</promote><!--Promu en page d'accueil par défaut-->
        <title_label>Titre de la news</title_label>
        <body_label>Corps de la news</body_label>
        <has_body>1</has_body>
        <comment>2</comment> <!-- Pour que les commentaires soient activés-->
        <upload>0</upload>
      </content>

</actions>

Si on lance notre pattern, tout fonctionne à merveille et le type de contenu se crée à la perfection. Rédiger un type de contenu s'avère donc un jeu d'enfant. Comme patterns utilise l'API des formulaires de Drupal, on peut controler absolument n'importe quel paramètre du type de contenu : nombre de commentaires par page, type de commentaire,etc, etc.... Avec le module features, nous aurions eu besoin d'implémenter un hook dans le fichier .module pour pouvoir affiner les réglages des commentaires, de l'upload et du status de publication.
Rajouter un champ CCK

Nous sommes toujours au seins des balises actions . J'ajoute un champ filefield avec l'option « image » que me confère le module image_field, je décide que 5 images sont autorisées par article

      <field>
        <type>filefield</type> <!--Le type de champ, je souhaite un champ fichier-->
        <name>image</name> <!-- nom du champ, qui affichera plus tard field_image"-->
        <label>Images</label>
        <widget>imagefield_widget</widget>
        <weight>8</weight>
        <file_extensions>jpg jpeg png gif</file_extensions>
        <file_path>images</file_path> <!--Dossier où seront rangées les images-->
      </field>
Si on veut rajouter de la taxonomie, des presets d'image cache , des nodes, des blocks ?

La syntaxe pour tous ces objets sera tout aussi facile à rédiger, et la finesse de configuration toujours aussi pointue. Même si les premières fois il va falloir réfléchir et tatonner pour trouver les bon noms de paramètres pour le xml.
Comment créer une vue avec pattern?

A compléter : je n'ai pas eu le temps de comprendre comment créer une vue avec patterns. Une chose est sure, sur ce point, le module features a un énorme avantage car il permet d'exporter des vues et de les incorporer à notre feature en un seul clic: tandis que patterns, de par le fonctionnement du module, va vous demander de remplir de nombreuses informations pour reproduire une vue. Features à un très sérieux avantage pour l'instant de ce côté puisqu'il permet en un clic d'exporter une vue en profitant de l'API d'export de views.

Quelle sont les différences entre features et patterns ?

Ils ont un objectif commun : pouvoir réutiliser sur un nouveau site les configuration de modules patiemment créer sur un autre site. Mais pour cela ils utilisent une méthode très différente :
- Patterns s'appuie sur l'API des formulaire de Drupal. C'est à dire qu'à partir du xml que vous lui fournissez, il va soumettre programmatiquement les formulaires de configuration tout comme si vous le faisiez vous même. A part qu'il va beaucoup plus vite que vous :-). Vous obtenez donc le même résultat que si vous aviez fait tout ce travail à la main.

    Features agit d'une manière différente : il s'appuie sur l'API d'exportation des modules pour exporter leur configuration puis stocker cette configuration dans un fichier. Il extrait finalement les données présentes dans la base de données pour les mettre dans un module. Ce module devient ensuite un "donneur d'ordre" : il dit à image cache ou à CCK de créer telle ou telle chose, mais si on désactive la feature, tout disparait.

Exemple concret de cette différence : un type de contenu importé par patterns sera enregistré dans la base de données tout comme si vous l'aviez créer vous même à la main. Vous aurez un bouton delete vous permettant de l'effacer. Tandis que le type de contenu sauvegardée par feature sera contenu dans le fichier du module. Le type de contenu n'apparait que si vous activez la feature, vous n'aurez pas de bouton "delete" car ce type de contenu ne sera pas stocké dans la base de données. En revanche tous les élements créer par feature disposerons d'un bouton "revert" permettant de retourner à la configuration originelle donnée par votre feature.

Les avantages de patterns

    un large champ d'action et de possibilité. Un haut degré de précision. Pour en faire autant avec features, vous devrez installé le module strongarm et implémenté un hook_strongarm dans le fichier .module de la feature.

    possibilité de créer des vocabulaires, des termes, des nodes, des utilisateurs, des roles. Feature ne le fait pas de base. Patterns semble également très souple sur la gestion des blocs.

    L'idée de s'appuyer sur l'API des formualaire est ingénieuse : cela permet virtuellement de pouvoir s'adapter à n'importe quel module.

    La possibilité d'imbriquer des patterns dans des patterns. Cela permet sans doute de faire des features plus « configurable ». on peut imaginer un pattern qui créer le type de contenu news, le bloc, les tags, sans créer les images avec leurs presets. Ces images pourraient être un autre pattern que l'on peut selon nos besoin inclure ou pas dans notre pattern. On peut donc faire des patterns de patterns. :-)

    intégration avec pathauto

    Tout au même endroit :-) Tout se trouve exclusivement dans le fichier xml (ou autre format) sans une goutte de code php. Cette homogénéité est plaisante.

    j'en oublie surement, libre à vous d'éditer cette liste.

Les inconvénients de patterns

    Aucune interface utilisateur pour générer automatiquement votre xml. La page d'administration du module est actuellement incomplète, ne permettant pas de supprimer ( ou de désactiver un pattern ). (en tous je n'y suis pas arrivé)

    il est donc beaucoup plus long d'écrire un pattern en xml, et cela demande beaucoup plus de rigueur, que d'utiliser features qui permet parfois en quelques clics de faire quelque chose d'équivalent.

    Exporter une vue et ses blocs semble laborieux alors que features peut réaliser cela en un clic.

    Pas de bouton « revert » pour l'instant comme sur features, permettant de revenir à l'état antérieur du pattern

    Pas de possibilité de désactiver un pattern comme on désactive une feature.

Avis subjectif : Pourquoi je préfère features malgré sans champ d'action apparemment plus réduit

    Grande facilité pour importer des vues et leurs blocks

    Contrairement à patterns ou on doit rédiger de zero, features requiert simplement que vous créeiez comme à votre habitude vos types de contenus etc... puis vous n'avez qu'à exporter pour obtenir votre feature.

    Pouvoir utiliser le module context.

    Utilisation possible de features avec le module spaces, même si je n'ai pas encore exploré cette partie. Mais bon, cela donne open atrium :-)

    Chaque élément fourni par une features (views, preset d'image cache, champ CCK) dispose d'un bouton « revert ». Si vous n'etes pas satisfait des nouvelles évolutions apportées à votre features, le bouton revert permet en un clic de retrouver l'état orignel de votre vue, de votre champ CCK ou même de toute votre feature.

    facilité de mise à jour : il suffit d'uploader un fichier, et en cas de pépin il suffit de réuploader une version précédente du fichier, nous n'avons pas à nous préoccuper de la base de données. Patterns est plus « barbare » : il éxécute des requetes sql et il me paraît donc IMPERATIF de faire un back up and migrate avant tout import d'un nouveau pattern. Or, c'est justement pour éviter de devoir faire des backups constant au moindre changement de la base de données que je suis intéressé par features.

    En tant que développeur PHP, features me permet d'implémenter mes propres hooks en additions de la features, cela me donne donc une liberté totale, je ne suis dons pas frustré de certaines limites de features par rapport à patterns.

    une certaine confiance en Development Seed : j'aime leur travail de réflexion sur Drupal et les solutions qu'ils apportent. A priori features me parait promis à un plus bel avenir que patterns, mais je peux être dans l'erreur.


   
Aller plus loin avec le module strongarm et le fichier .module de votre feature
Dans les articles précédents j'ai expliqué comme combiner le module Features et le module Context pour pouvoir exporter la configuration de vos modules en un seul module que vous pouvez activer et désactiver à votre guise. Toutefois certaines limites apparaissent rapidement. Et si je veux que mon type de contenu « article_sport » ait par défaut ses commentaires désactivés ? Et comment faire pour exporter la configuration des modules non supportés par Features pour le moment ? Sommes-nous condamnés à fabriquer des features avec "seulement" CCK, views, context, image cache ? Que nenni.

Tirer parti du fichier .module de votre feature

En exportant votre feature, vous obtenez un module Drupal en bonne et due forme, si bien qu'il contient comme il se doit un fichier .module. Par défaut ce fichier contient cette unique ligne (dans mon cas, la feature se nomme « pack_reservation_taxi » ).
<?php
include_once('pack_reservation_taxi.features.inc');
?>

Cette ligne se charge d'aller cherches les autres fichiers de votre module contenant toute la configuration des modules composant votre features sous forme de tableaux php. Mais au-delà de cette ligne, vous êtes libre d'écrire absolument tout ce que voulez comme code php, comme si il s'agissait d'un module Drupal normal. Lors de votre prochain export, votre code fera partie du fichier .module de votre feature ! Voilà qui ouvre de nouveaux horizons.

C'est donc l'endroit idéal pour vous livrer aux hooks en tout genre qui peuvent vous permettre d'aller plus loin dans les ajustements de votre feature et améliorer son exportabilité. On peut imaginer utiliser le hook_enable (qui se déclenche uniquement au moment de l'activation de votre module, et donc de votre feature dans ce cas) pour lancer une requête sql permettant d'ajuster dans la table system le poids d'un autre module de façon automatisée par exemple.

Mais en utilisant le module Strongarm, qui est utilisé sur l'intranet drupal « open atrium » vous pouvez aussi prendre très facilement le contrôle d'une partie très importante de Drupal : les réglages de base des formulaires de configuration de n'importe quel module.

Un peu de théorie : La table « variable » de Drupal

En vous rendant dans la base de données de votre installation Drupal avec phpmyadmin ou autre, vous pourrez constater la présence d'une table variable. Cette table joue un rôle majeur dans la configuration de vos modules -et donc de votre site. En effet, chaque fois que vous vous rendez dans un formulaire de configuration d'un module, quand vous appuyez sur le bouton enregistrer, c'est dans cette table que sont stockés vos changements. Autrement dit, si nous pouvions exporter dans notre feature certaines variables de cette table, ça nous permettrait de maîtriser la configuration par défaut de n'importe quel module Drupal possédant une page d'administration lors de l'activation de notre feature.

Le module strongarm

C'est très justement ce que se propose de faire le module Strongarm. Ce module ne propose pas d'interface utilisateur, c'est au développeur d'implémenter un hook permettant de spécifier la configuration qu'il souhaite pour tel ou tel module Drupal. Une place toute trouvée pour implémenter ce hook c'est le fichier .module de votre feature :-)
Voici un exemple concret de ce hook que j'ai implémenté dans ma feature « pack_reservation_taxi », pour laquelle je souhaitais que soient désactivés par défaut les commentaires sur deux types de contenus spécifiques. Je souhaitais également que le module « automatic node title » soit automatiquement configuré pour cacher le titre de ces types de contenus et les remplacer par des tokens de mon choix. Plutôt que de refaire cela à la main lors de l'import de ma feature, j'ai implémenté le hook_strongarm, (disponible une fois activé le module Strongarm).

<?php
  function pack_reservation_taxi_strongarm() {
  $conf = array();

  // Désactiver les commentaires sur les types de contenus fiche trajet et vehicule
  $conf['comment_fiche_trajet'] = COMMENT_NODE_DISABLED;
  $conf['comment_vehicule']     = COMMENT_NODE_DISABLED;

  //autonodetitle
  $conf['ant_fiche_trajet'] = 1; //cacher automatiquement les titres
  $conf['ant_pattern_fiche_trajet'] = '[field_ville_depart-title] > [field_ville_arrivee-title]'; //tokens

  return $conf;
}
?>

Une fois ce hook implémenté, vous pourrez voir (après avoir vidé le cache de Drupal) sur les types de contenus choisis que les commentaires sont automatiquement forcés à « disabled ». De plus, le module Strongarm vous affiche un message vous indiquant que des champs de ce type de contenus sont « forcés » par Strongarm. Les boutons radios pour changer la configuration des commentaires apparaîtront dans un cadre de couleur et seront grisés : vous ne pouvez plus les changer. Toutefois en vous rendant dans la page de configuration du module Strongarm, vous pouvez décider qu'il reste possible d'overrider ces réglages, en dépit des ordres donnés par votre hook.

En utilisant à bon escient le fichier .module de notre feature et Strongarm, nous disposons donc d'un sérieux arsenal pour contrôler une grande partie de la configuration de vos modules avec peu d'efforts.