La surcharge des thèmes

Traduction de la page http://drupal.org/node/173880
publiée / actualisée le 11 Décembre 2010 sur drupal.org


Ce qui suit ne s'applique que si vous avez besoin de modifier le balisage par défaut. Vous pouvez sauter ces explications si votre présentation ne s'effectue que par le biais de feuilles de style.

Il y a trois étapes pour surcharger un thème. La première consiste à localiser la source des données, la seconde consiste à surcharger et la troisième consiste à comprendre son type.

Notez que les données du thème sont conservées en cache par Drupal, via le registre de thèmes (theme registry), ce registre doit être vidé lors de la mise en place des « surcharges ».

1. Localiser la source des données

La source des données affichées peut être difficile à déterminer étant donné la hiérarchie des appels de thèmes, qui peuvent provenir de n'importe où dans le système.

http://drupal.org/files/theme_tree_1.pdf

La plupart des éléments de la page sont généralement appelés avec theme('page') et placés dans le gabarit page.tpl.php après mise en forme des éléments... (traduction incomplète, voir le texte an anglais ci-dessous)

Most of the page elements are typically pulled with theme('page') and placed inside the page.tpl.php template after rendering navigation bits, the bits within the navigation bits, block regions, the blocks within the block regions, etc. Each chunk of themed data is often referred to as a theming "hook".

Remarque : les fonctions de thèmes et de gabarit seront désormais dénommées « theming hook ». Le système comprend de nombreux hooks qui n'ont rien à voir avec les thèmes. Les hooks dont nous parlerons ici ne concerneront que les thèmes.

Obtenir l'origine de toute partie de code mis en forme peut se faire grâce au module Theme developer. Il dispose d'un outil de développement de thème qui permet d'afficher facilement l'origine de tout affichage, son type et de nombreuses autres données du thème. Reportez-vous au screencast pour une démonstration. Cet outil n'est pas disponible dans les versions Drupal antérieures à la 6, en raison de limitations techniques.

2. Le système de surcharges

Le système de surcharges possède un ordre de cascades spécifique, comportant peu de dérogations. Le core Drupal et les modules fournissent un balisage par défaut géré par les hooks du thème. Si ce balisage ne convient pas aux exigences de votre thème, vous pouvez le remplacer par un autre, ce qui empêchera alors le chargement des valeurs par défaut. Les valeurs par défaut seront ainsi ignorées et toutes les modifications spécifiques au thème seront localisées dans le thème lui-même. C'est pourquoi vous ne devez jamais bricoler les fichiers en dehors de votre thème.

Si votre thème nécessite des contrôles qui ne peuvent être effectués dans le cadre des surcharges, vous pouvez alors intervenir sur le registre de thèmes ).

Remarque : bien que cela soit encore possible, le moteur PHPTemplate de Drupal 6 ne surcharge plus les fonctions de thème. Dans Drupal 5, c'est ce qui permettait l'utilisation de quelques theming hooks dans les gabarits de mise en page. Ce n'est plus nécessaire.

3. Les fonctions comparées aux gabarits

Il y a deux façons d'implémenter un theming hook : par le biais de fonctions ou par par le biais de gabarits. La méthode que vous utiliserez dépendra du but à atteindre ou de la nature de l'élément à personnaliser. Le core et les modules peuvent construire leurs sorties des deux façons, et les thèmes peuvent employer la même façon, ou la changer.

http://drupal.org/files/theme_flow_6_1.pdf.
Diagramme de la version 5, pour comparaison : Flow map for 5

Les fonctions sont légèrement plus rapides que les gabarits, mais elles sont plus difficiles à appréhender par les concepteurs de thèmes habitués à travailler directement en xHTML. La rapidité dépendra de la nature du hook multiplié par le nombre de fois où il est appelé dans une page. Par exemple, l'utilisation de gabarits pour les theming hook "links" peut grandement impacter les performances pour des sites complexes et sollicités étant donné leur usage répété.

Voici deux exemples de surcharge à l'aide de Devel themer.

Surcharger des fonctions

La fonction theme_menu_local_tasks affiche les onglets primaires et secondaires. Son theming hook est menu_local_tasks. Pour le surcharger, le préfixe « theme » du nom de la fonction doit être remplacé par le nom de votre thème. (Dans Drupal 6, vous pouviez aussi utiliser le nom du moteur de thème qui exécutait le thème, mais ce n'était pas une pratique conseillée. Cette possibilité a été supprimé dans Drupal 7).

Cet exemple, tiré de Drupal 6, montre Garland utilisant le nom du moteur de thème pour la surcharge. Une fois encore, dans Drupal 6 il est conseillé d'utiliser le nom du thème et dans Drupal 7, il est obligatoire d'utiliser le nom du thème.

Placer le code suivant dans le fichier template.php du thème surchargera les valeurs par défaut après avoir vidé le registre des thèmes.

Remplacez « drop » par le nom de votre thème.

<?php
function mytheme_menu_local_tasks() {
  
$output '';

  if (
$primary menu_primary_local_tasks()) {
    
$output .= "<ol class=\"tabs primary\">\n"$primary ."</ol>\n";
  }
  if (
$secondary menu_secondary_local_tasks()) {
    
$output .= "<ol class=\"tabs secondary\">\n"$secondary ."</ol>\n";
  }

  return 
$output;
}
?>

La seule modification ici est le remplacement du balisage liste non ordonnée (<ul>) par liste ordonnée (<ol>).

Un listing de toutes les fonctions de thème (theme functions) est disponible dans api.drupal.org.

Surcharger les gabarits

Si c'est un gabarit qui implémente les valeurs par défaut, copier son fichier source dans votre thème le surchargera automatiquement, une fois que vous aurez vidé le registre de thème.

Voici un exemple pour search-theme-form.tpl.php. Notez que, dans ce cas, le point d'entrée est search_theme_form avec le gabarit utilisant des traits d'union au lieu de signes souligné.

C'est tout ce que vous avez besoin de faire. Ouvrez le gabarit copié dans un éditeur de texte pour faire vos modifications. Tous les fichiers tpl.php du core sont documentés. Cela vous donnera de bonnes informations sur ce qui peut être fait avec les sorties.

Remarque : les gabarits peuvent être placés dans n'importe quel dossier du thème. Cela permet une meilleure gestion et évite le désordre dans le dossier racine du thème.

Pages liées :

  • Pour personnaliser les variables à l'intérieur des gabarits, reportez-vous à la page Preprocess functions.

Convertir des fonctions en gabarit

Convertir une fonction en gabarit demande un certain travail initial mais une fois réalisé, il est plus facile de travailler avec. Si vous travaillez avec un designer, la conversion lui permettra de se concentrer sur la seule conception et pas sur le codage.

Plusieurs gabarits sont déjà disponibles dans le core et beaucoup d'autres seront convertis dans les futures versions. Les modules additionnels qui respectent les bonnes pratiques devraient aussi avoir des gabarits disponibles. Ces instructions sont fournies pour les hooks des thèmes qui ne sont pas encore disponibles en gabarits.

La reconnaissance d'un hook comme gabarit est automatisée dans Drupal. Voici les seules règles pour déclencher cette modification : 

  • Le nom du gabarit doit correspondre au point d'entrée.
  • Les signes soulignés du point d'entrée doivent être remplacés par des traits d'union.
  • Le gabarit doit avoir tpl.php comme extension (cette extension peut varier en fonction du moteur du thème utilisé)

Prenons la fonction theme_user_signature. Ici, le hook est user_signature. La création d'un fichier nommé user-signature.tpl.php dira à Drupal, lorsque le registre aura été vidé, que le hook est maintenant ce gabarit.

Tout contenu dans ce fichier remplacera la fonction. La tâche qui demande le plus de travail est le paramétrage des variables à utiliser dans ce fichier et cela se fait par le biais des fonctions de pré-traitement (pre-process functions).

Quelques remarques :

  • Bien qu'il soit possible de coder directement dans le gabarit, ce n'est pas une bonne pratique. Toute la logique de programmation ne doit pas se trouver dans le fichier tpl.php mais dans les fonctions de pré-traitement. Le code restera propre et sa gestion facilitée.
  • C'est également une question de sécurité. La séparation du code minimise les risques d'attaques par cross-site scripting pouvant provenir d'un contenu utilisateur malveillant. Quand vous remettez les fichiers gabarits à votre designer, toutes les sorties seront « propres » et il n'aura pas à s'occuper des questions de sécurité.
  • Si votre thème implémente une fonction de thème et un gabarit pour un hook donné, la fonction de thème sera toujours utilisée.
  • La détection automatique des surcharges de thème est réalisée par le moteur PHPTemplate, en conséquence, assurez-vous que le moteur soit paramétré dans le fichier .info.
  • Comparez les fonctions de thèmes de Drupal 5 (theming functions in 5) aux conversions de gabarits de Drupal 6 pour les forums (template conversions in 6). Vous pouvez les utiliser comme exemple de conversion d'un type à l'autre.

Le registre de thème :

Le registre de thème de Drupal conserve en cache les données des hooks du thème et la façon de les manipuler.

Pour beaucoup de développeurs, le registre ne doit pas être traité directement. Rappelez-vous simplement de le vider quand vous ajoutez ou modifiez des gabarits ou des fonctions de thème. La modification de fonctions ou de gabarits existants ne demande pas de reconstruire le registre.

Pour vider le registre de thèmes, faites l'une des opérations suivantes :

  1. Dans la page Administrer » Configuration du site » Performance, cliquez sur le bouton Supprimer les données du cache.
  2. Avec le bloc Devel activé (livré avec le module Devel), cliquez sur le lien Vider le cache.
  3. La fonction API drupal_rebuild_theme_registry.

Le registre de thèmes contient des données mises en cache indiquant à Drupal les hooks disponibles du thème et la façon de les manipuler selon leurs types. Dans les précédentes versions tous les appels de thème étaient exécutés à la volée. Comme beaucoup de travail est désormais effectué « sous le capot » par l'application, la mise en cache des instructions accélère les traitements, surtout en ce qui concerne les gabarits. Le moteur de thème qui exécute votre thème doit en principe automatiquement enregistrer pour vous les hooks de thème.

Il y a des situations particulières pour lesquelles vous aurez besoin de travailler directement avec le registre. Quand votre thème aura besoin d'enregistrer un nouveau hook qui n'était pas précédemment implémenté dans les couches inférieures du thème (celles du core, des modules, du moteur). Cela concerne des formulaires dont la présentation n'était pas explicitement réalisée par le core ou les modules mais était rattachée à la présentation défaut.

  • Plus de détails disponibles dans la page The theme registry for special cases.
  • Ne confondez pas le registre de thème avec le fichier .info du thème qui est lui aussi mis en cache. Les points 1 et 2 indiqués pour vider le cache videront les deux caches.
  • Votre thème doit utiliser le moteur PHPtemplate pour que ses gabarits et fonctions soit pris en compte. D'autres moteurs devraient avoir le même comportement. Pour les thèmes qui n'utilisent pas de moteur, la prise en compte doit se faire manuellement.

    Reportez-vous à phptemplate_theme pour voir comment faire.