La surcharge des thèmes

Date du document original en anglais : 24 Août 2009 – 11h33 - http://drupal.org/node/173880

Ce qui suit n'est utile 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 Drupal conserve les données en cache vie le registre de thèmes (theme registry), il doit être vidé lors de la mise en place des « surcharges ».

1. Localiser la source des données

La source des données peut être difficile à déterminer puisque les fonctions de thèmes peuvent être appelées dans n'importe quel module de Drupal.

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 ... (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.

(J'utiliserai souvent les termes « points d'entrée » pour désigner ces fonctions de hook. NDT)

Le module Devel permet désormais de tracer l'origine de toute partie du code. Il contient un outil « thèmes » pour visualiser l'origine d'un affichage, son type et de nombreuses autres données du thème. Reportez-vous au screencast pour une démonstration. Pour des raisons techniques, cet outil n'est pas disponible pour les version de Drupal antérieures à la 6.

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. Ne bricolez jamais les fichiers hors de votre thème.

Si votre thème nécessite des contrôles ne pouvant être effectués dans le cadre des surcharges, le registre de thèmes peut être manipulé à cette fin (theme registry can be manipulated).

Remarque : bien que cela soit encore possible, le moteur PHPTemplate de Drupal 6 ne surcharge plus les fonctions de thème. In 5, that is what allowed templates to be used for a handful of the theming hooks. It is no longer necessary.

3. Les fonctions comparées aux gabarits

Il y a deux façons d'implémenter un point d'entrée (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 points d'entrée implémentés par les fonctions sont plus rapides. Environ cinq fois plus rapides que les points d'entrée des gabarits, mais ils sont plus difficiles à appréhender pour les concepteurs qui sont davantage habitués à travailler directement en xHTML. La rapidité dépendra de la nature du point d'entrée 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é.

For example, using templates for the theming hook "links" could cause a noticeable performance hit for complex and busy sites due to its repeated use.

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 point d'entrée est menu_local_tasks. Pour le surcharger, le préfixe « theme » du nom de la fonction peut être remplacé par le nom de votre thème ou par le nom du moteur de thème qui le fait tourner. Il est recommandé d'utiliser le nom du thème, pour éviter des conflits de noms avec les sous-thèmes.

Cet exemple montre Garland utilisant le nom du moteur de thème pour la surcharge. Si vous créez un sous-thème dérivé de Garland, l'utilisation du nom de votre thème est impérative.

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 points d'entrée des thèmes qui ne sont pas encore disponibles en gabarits.

La reconnaissance d'un point d'entrée 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 point d'entrée est user_signature. La création d'un fichier nommé user-signature.tpl.php dira à Drupal, lorsque le registre aura été vidé, que le point d'entrée 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 devrait pas se trouver dans le fichier tpl.php mais dans les fonctions de pré-traitement. Le code restera propre et sa gestion facilitée.
  • Il y a aussi 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 malfaisant. 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é.
  • 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 points d'entrée 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 points d'entrée 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 les points d'entrées de thème pour vous.

<>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 point d'entrée 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 prises en compte. D'autres moteurs doivent 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.