Voilà, voilà... Fin de l'aventure...

 

Fermeture de kolossaldrupal.org dans...


Bonjour tout le monde,

Drupal évolue, les versions changent et Kolossaldrupal.org était essentiellement consacré à la version 6 de Drupal.

Autant dire que les infos présentées ici commencent à dater...

Faute de temps, je ne peux plus garder le site Kolossaldrupal à jour...

Je vous aurais bien proposé de reprendre le flambeau mais... c'est tellement simple de nos jours de se faire son propre site à soi...Pourquoi s'embêter alors ? :-)

Ce site restera donc en l'état, tel qu'il était en 2011...

Ah la la ! Cela ne nous rajeunit pas !

Manuel Vila - Avril 2016

Utiliser la couche de thème (theme layer)

Référence en anglais sur drupal.org : 11 Mai 2010 - 04h47
http://drupal.org/node/165706


Voir aussi le Guide des thèmes Drupal 6.x.

Les modules Drupal offrent la possibilité d'avoir leur mise en page surchargée. Cette possibilité s'appelle theming (habillage ? ). Pour pouvoir l'utiliser, le module doit être écrit en conséquence. Pour cela, le contenu doit être séparé autant que possible de sa présentation.

Pour cela, le module s'oocupe du traitement des données puis les passe à la couche de mise en page sans autre intervention. Les modules fournissent alors des implémentations par défaut qui définissent une mise en forme minimale et servent de point de départ aux thèmes qui veulent fournir une présentation différente. Cela se fait via la fonction theme(). Chaque partie à afficher qui est habillé via la fonction theme() est appelé theme hook.

Il y a deux façons de fournir une implémentation par défaut. La plus simple, mais la moins recommandée, est de fournir une fonction, et la façon de faire la plus recommandée est de fournir un gabarit (template) et la fonction de pré-traitement correspondante. Voyons cela un peu plus en détail.

Idéalement, votre module ne devrait pas produire la moindre ligne de code HTML en dehors d'un thème. En réalité, les pages d'administration et quelques petits éléments n'ont pas vraiment besoin d'être mis en page de façon personnalisée, mais on reconnait des modules bien écrits au fait qu'ils permettent cette personnalisation.

Enregistrement des hooks de thèmes

Pour utiliser un hook de thème, votre module doit d'abord indiquer son existence. C'est une nouveauté depuis Drupal 6; l'enregistrement des hook de thème est nécessaire parce que l'auto-découverte des mises en pages alternatives prenait trop de temps; en enregistrant les hooks, cette découverte n'est faite que lorsqu'il y en a besoin, et devient définitivement disponible. Au final, la couche de thème est vraiment un peu plus rapide, bien qu'elle fasse plus de travail.

Le hook_theme de votre module retournera une liste de tous les hooks de thème qu'il exécute. Une implémentation hook_theme simple ressemblera à ce qui suit :

<?php
function forum_theme() {
  return array(
    
'forums' => array(
      
'template' => 'forums',
      
'arguments' => array('forums' => NULL'topics' => NULL'parents' => NULL'tid' => NULL'sortby' => NULL'forum_per_page' => NULL),
    ),
  );
}
?>

L'enregistrement nous dit qu'un hook de thème nommé forums est implémenté. L'implémentation par défaut est un gabarit (template). Puisqu'il y a différents moteurs de templates, cet enregistrement ne mentionne pas l'extension utilisée par le moteur de template, bien que, pour les modules, le core de Drupal ne supporte que les gabarits PHPTemplate. Ces fichiers gabarits ont l'extension .tpl.php.

Il nous dit également que la fonction de thème forums (template_preprocess_forums) prend 6 arguments et qu'ils sont tous à NULL par défaut (tous les arguments doivent être donnés par défaut car nous ne pouvons être sûrs qu'un appel à theme() fournira les bonnes infos. Dans le doute, indiquez NULL comme valeur par défaut).

Ces arguments sont déplacés à l'intérieur des variables nommées pour le gabarit. En appelant ce hook de theme, un auteur peut écrire :

  $output = theme('forums', $forums, $topics, $parents, 17, 'ASC', 25);

Si le gabarit a été abandonné, on supposera que l'implémentation par défaut des hooks de thème sera une fonction appelée theme_forums.

Beaucoup d'options peuvent être paramétrées ici, mais ces deux-là sont de loin les plus importantes. pour plus d'information, voir la documentation de hook_theme.

Implémenter les gabarits par défaut

Le fichier .tpl.php est requis pour l'implémentation de gabarits. Il doit se trouver dans le même dossier que le fichier .module (bien que la directive path puisse être utilisée pour placer ces gabarits dans un autre dossier ou dans un sous-dossier).

Les gabarits ne doivent comporter, autant que possible, que du code HTML pur, mais un petit nombre de fonctions peuvent y être placées.

La première d'entre elles est la fonction t(). Les modules devraient toujours pouvoir être traduits facilement, il en va de même pour les thèmes et leurs gabarits. Les concepteurs de thèmes n'ont pas à travailler sur les contenus, les textes affichés, et tous les textes fournis par les traducteurs doivent être passées via t(). Il est ainsi fortement conseillé d'utiliser cette fonction dans les gabarits.

Une autre fonction dont l'usage est recommandé dans les gabarits est la fonction format_date(). Comme il s'agit surtout d'une fonction de mise en forme, la couche de présentation est l'endroit adéquat pour son utilisation. Cependant, son utilisation peut se révéler ésotérique et quelque peu difficiles pour les personnes qui ne sont pas familiarisées avec le PHP. Elle doit néanmoins être utilisée dans les gabarits.

Pour les autres fonctions, à vous de déterminer si elles doivent être utilisées dans la couche de présentation ou pas. Si non, elles peuvent l'être dans la couche de pré-traitement. Tous les gabarits peuvent avoir des fonctions de pré-traitement, nommées template_preprocess_HOOK. Par exemple, pour notre hook de thème forums, la fonction de pré-traitement se nommera template_preprocess_forums (allez voir dans l'API, elle existe).

Le but d'une fonction de pré-traitement est de s'occuper des traitements qui rendent les données présentables, et d'assainir ces données pour un affichage sûr. Il est d'une importance vitale que vos sorties soient sûres et ne contiennent pas de failles XSS (Cross Site Scripting). Et comme les données affichées proviennent la plupart du temps des utilisateurs, elles doivent être assainies avant d'être affichées.

Dès lors que nous supposons que les concepteurs de thèmes ne sont pas forcément des développeurs, nous devons supposer qu'ils ne seront pas à même d'effectuer ces opérations correctement; mais ce n'est pas grave puisque nous pouvons assainir les données dans les fonctions de pré-traitement en les passant à check_plain , check_markup , filter_xss_admin ou à d'autres fonctions d'assainissement.

Voici un exemple simple :

<?php
function template_preprocess_poll_bar(&$variables) {
  if (
$variables['block']) {
    
$variables['template_files'][] = 'poll-bar-block';
  }
  
$variables['title'] = check_plain($variables['title']);
  
$variables['percentage'] = round($variables['votes'] * 100 max($variables['total_votes'], 1));

?>

Tout d'abord, vous remarquerez que la fonction de pré-traitement prend la référence d'un tableau de variables. Ce tableau sera alimenté par les arguments qui ont été envoyés via la fonction theme() et nommés dans la section arguments de l'enregistrement du hook. Puisqu'il s'agit d'un passage par référence, la simple modification du tableau est suffisante pour répercuter cette modification au gabarit qui l'accompagne.

Cet exemple illustre trois concepts importants :

  1. Le champ title n'est pas sûr car il provient de l'utilisateur. Il est filtré via check_plain pour que le gabarit puisse l'afficher sans risques.
  2. Le hook du thème reçoit le nombre total de votes et le nombre de votes pour cet élément seulement, mais le gabarit veut afficher un pourcentage. Ce calcul ne doit pas être fait dans le gabarit mais dans la fonction de pré-traitement. Les variables existent toujours; un concepteur de thème surchargeant cela pourra choisir d'afficher autre chose qu'un pourcentage.
  3. La variable spéciale template_files peut être utilisée pour indiquer un gabarit alternatif à utiliser. Cette variable est un tableau de fichiers gabarits, de type LIFO : le dernier élément ajouté au tableau sera le premier utilisé. Cette méthode est assez pratique pour utiliser un tableau de différents gabarits, mais faites attention au fait qu'elle est juste utilisable avec des gabarits.

Le module Theme Developper, qui fait partie du projet Devel, contient une fonctionnalité template log qui affiche en haut de la page touts les fichiers gabarits mis en œuvre pour mettre en forme cette page. Cela peut s'avérer pratique lorsque vous développez votre module, mais aussi lorsque vous personnalisez l'habillage d'un site. Donc, utilisez ces infos !

Petite remarque : les fichiers gabarits devraient être nommées avec des traits d'union au lieu de signes soulignés. Si le hook du thème est forum_list, le fichier gabarit devra s'appeler forum-list.tpl.php.

Implémenter des fonctions de thème

Drupal vous permet d'utiliser des fonctions pour vos implémentations de thème par défaut. C'est beaucoup plus rapide et il n'y a pas de vérification de thèmes alternatifs.

Le revers de la médaille c'est qu'il n'y a pas non plus de fonctions de pré-traitement. Ce qui rend difficile leur surcharge pour les concepteurs de thèmes, vu que ce ne sont pas des programmeurs. C'est d'autant plus vrai si votre fonction de thème touche aux données plutôt qu'à leur présentation. Habituellement, l'utilisation de gabarits réduit ce risque.

Les fonctions de thème sont nommées en préfixant le nom du hook par theme_. Les arguments de theme('hook') seront passés directement, sans modification. Les valeurs par défaut indiquées dans l'enregistrement du hook ne seront pas fournies ici; elles doivent l'être en tant qu'arguments PHP classiques.

<?php
function theme_forums($topics NULL$parents NULL$tid NULL$sortby NULL$forum_per_page NULL) {
  ...
  return 
$output;
}
?>

 

Mise en forme dynamique

En plus de pouvoir spécifier des gabarits alternatifs dans une fonction de pré-traitement, vous pouvez aussi créer des implémentations dynamiques de thèmes en utilisant des caractères jokers. Cela se fait en deux temps.

D'abord, dans hook_theme, vous pouvez indiquer un motif (pattern). Les motifs sont des expressions rationnelles. ^ (début de ligne) est implicite, mais $ ne l'est pas. Pour indiquer une partie de motif dynamique, un double signe souligné est la convention habituelle; ce n'est pas obligatoire mais c'est fortement recommandé.

Ensuite, lors de l'appel de la fonction theme(), au lieu de passer une chaîne comme premier argument, vous pouvez passer un tableau. Ce tableau ressemble beaucoup au templates_files vu plus haut, mais celui-là est de type FIFO, le premier entrée sera le premier utilisé.

Voici une exemple concret : le module Views permet que chaque vue soit personnalisable par le nom. Dès l'enregistrement, le hook views_view pourra s'enregistrer avec le motif views_view__ . Lorsqu'on personnalise cette vue, Views pourra appeler :

  $output = theme(array("views_view__$view->name", 'views_view'), $view);

Views implémentera une vue par défaut pour views_view; si le thème enregistre views_view__foo et que Views personnalise (themes en anglais) une vue nommée foo, la surcharge spécifique sera alors activée et utilisée. Contrairement à la variable template_files dans la fonction de pré-traitement, ceci fonctionne pour les fonctions de thèmes comme pour les gabarits.

Davantage d'infos sur http://www.kolossaldrupal.org/docs/initialisation-variables-pour-leur-utilisation-dans-gabarit-fonctions-de-pre-traitement

theme('table') et theme('item_list')

Drupal fournit une aide pour l'élaboration de code HTML complexe. Ce sont des fonctionnalités très utiles et s'en servir facilite la création de tableaux et de listes d'apparence homogène. L'inconvénient c'est qu'elles ne sont pas très accessibles aux concepteurs de thèmes. Elles mettent du code dans la partie programme au lieu de le mettre dans la partie présentation, et seuls des concepteurs de thèmes expérimentés peuvent s'y retrouver.

Lorsque vous créez des sorties susceptibles d'être modifiées, il vaut mieux éviter ces méthodes et créer les tableaux et les listes en vrai code HTML. Les thèmes de forums sont des très bons exemples de création de code HTML homogène.

Si vous implémentez des fonctions de thèmes personnalisées au lieu d'implémenter des gabarits par défaut, vous devrez redémarrer votre module (le désactiver et l'activer) après chaque modifications dans la fonction theme_custom().