La gestion des thèmes Drupal

La gestion des thèmes de Drupal est une vraie merveille en permettant tant aux développeurs et qu'aux thèmeurs de bosser chacun avec son domaine de compétence, toute en assurant une parfaite indépendance entre les données et la présentation.

Cette gestion repose essentiellement sur une fonction, theme(), dont le rôle est de découpler la donnée de la présentation. De l'appel à theme() découle tout un processus relativement complexe qu'il est important de bien maîtriser pour savoir où et comment modifier l'apparence globale de Drupal.

Thème de site et hook de thème

Tout d'abord il faut distinguer deux notions. D'un côté le thème du site, qui est l'ensemble des modèles et des ressources (images, css, etc.) utilisé pour créer une apparence globale, un "look & feel". De l'autre côté le hook de thème défini par un module, qui est un outil capable de transformer une donnée (ex. un "lien") en un fragment de code XHTML. Une autre manière de comprendre la différence est de se dire que le thème du site est utilisé par les hooks de thème des modules, ou plus exactement que le thème du site correspond à l'exploitation de la possibilité personnalisation des hooks de thème des modules.

Et ces hooks de thème fournis par les modules sont invoqués par une seule et même fonction Drupal, theme().

La fonction theme()

La fonction theme() prend en premier paramètre un hook, correspondant au type de transformation que l'on cherche à opérer sur les données à formater (les paramètres qui suivent). Par exemple :

  • theme('link', $lien) va transformer l'objet PHP $lien en un fragment XHTML.
  • theme('page', $contenu), car transformer les données textuelles de $contenu en une page XHTML.

Dans le premier cas le nom du hook est link et est page dans le second.

Fonctions de thème et modèles de thème

A ce stade, il est sans doute plus simple de suivre avec un schéma. Celui que vous trouvez sur la gauche reprend l'ensemble du processus de la fonction theme().

Pour effectuer son travail, la fonction theme() va commencer par rechercher des informations sur le hook dans le registre des thèmes.

Ce registre a été créé par Drupal par la fonction drupal_rebuild_theme_registry() en explorant les modules actifs pour déterminer la liste des hooks présents. Et pour chaque hook, il va explorer tous les thèmes de sites et modules actifs pour déterminer qui est éligible à la prise en charge de ce hook. Pour information drupal_rebuild_theme_registry() est appelé systématiquement à chaque fois que l'on va sur la page d'administration des thèmes.

Chaque module peut ainsi déclarer de nouveaux hooks en choisissant entre deux méthodes possibles.

  • Soit le hook fait appel à une fonction PHP, c'est le cas de theme('link', ...) qui fait appel à theme_link(..)
  • Soit il fait appel à un modèle, c'est le cas de theme('page', ...) qui fait appel à page.tpl.php.

Une fois la méthode fixée, les modules définissent un "comportement par défaut" pour les hooks qu'ils déclarent (une fonction par défaut ou un modèle par défaut). Bien évidemment, ceci n'empêche aucunement ce comportement de pouvoir être modifié par le thèmeur. Ainsi si le hook est défini par une fonction (ex. theme_link), le thèmeur pourra alors déclarer dans le fichier mon_theme/template.php de son thème de site une fonction mon_theme_link qui viendra remplacer celle du développeur.

De la même manière, si un hook de thème est défini par rapport à un modèle (ex. page.tpl.php), il pourra être "remplacé" par un modèle équivalent dans le dossier du thème du site (ex. mon_theme/page.tpl.php).

Les modèles éligibles

Ça c'est la première approche, de manière plus affinée, pour un même modèle, Drupal défini un ensemble de "suggestions" de noms de modèle que le thèmeur pourra utiliser dans son dossier mon_theme.

Par exemple s'il veut définir un modèle de page spécifique au chemin http://mon_site.com/rubrique, il va alors créer un modèle mon_theme/page-rubrique.tpl.php qui ne sera utilisé par theme('page', ..) que pour les URL qui commencent par rubrique. Une liste exhaustive des suggestions possible pour les modules du core de Drupal est disponible ici.

Enrichissement des variables du modèle

L'autre finesse correspond aux variables qui sont fournies au modèle. En effet, avant d'y faire appel, Drupal va appeler toute une série de fonction *_preprocess et *_preprocess_hook dans un ordre déterminé qui chacune vont aller enrichir le tableau de variables à passer au modèle et qui leur est donné en paramètre (&$vars).

Le thèmeur peut donc, toujours dans mon_theme/template.php créer des fonctions de la forme mon_theme_preprocess qui seront appelées pour chaque modèles, ou encore de la forme mon_theme_preprocess_hook qui elles ne seront appelées qu'avant l'appel d'un modèle défini par hook. Par exemple, la fonction mon_theme_preprocess_page permettra d'ajouter de nouvelles variables pour le hook page qui seront donc disponible tant pour le modèle page.tpl.php que pour tous les modèles de suggestion (ex. page-rubrique.tpl.php).

En réalité, Drupal ne s'amuse pas à chercher à chaque appel à theme() quelles fonctions sont utilisables. C'est en effet au moment de la construction du registre de thème que les fonctions éligibles sont classées par ordre d'exclusion et/ou de priorité. La fonction thème sait donc toujours instantanément quel fonction ou quel modèle appeler dans n'importe quelle situation.

A la recherche du thème perdu

Du côté thèmeur, il n'est pas forcement aisé de savoir :

  • Quel module est responsable de la présentation de tel ou tel élément d'une page. Drupal est en effet un outil purement systémique et chaque module peut potentiellement déclarer des hooks.
  • Si le hook défini comme une fonction ou comme un modèle.

Pour résoudre ce problème, vous pouvez déjà vous référer au manuel des thèmes (en anglais) qui fourni déjà pas mal d'informations, au moins pour les module du coeur de Drupal.

Une autre option sans doute plus directe, est d'exploiter le module devel qui fourni de manière très simple (il suffit de cliquer sur l'élément à explorer) la liste des modèles éligibles et des fonctions.

Et les autres moteurs ?

Ici j'ai tout de même passé sous silence l'aspect multi-moteur de Drupal en partant du principe que seul PHPTemplate existait. C'est effectivement le cas dans 80% des cas. Sachez seulement qu'une couche de traitement supplémentaire faisant appel au moteur de rendu serait dans le cas contraire à ajouter au processus, et que toutes les fonctions préfixées par phptemplate le serait par le nom du moteur que vous aurez utilisé.

Conclusion

J'espère avoir un peu débroussaillé le vaste sujet de la gestion des thèmes de Drupal. Et aussi montré à quel point il avait été pensé autant par les développeurs que par les thèmeurs, ce qui est assez rare pour être souligné.

Vus : 451
Publié par arNuméral : 54