Quelles sont les lunettes de prescription non http://belgiquepharmacie.be/ Unie de liberté de santé oxford

Le système de theming de Drupal 7 est un gâchis. Jacine Luisi, co-auteure du livre The Definitive Guide to Drupal 7, résume dans son article Let’s Do Something About Drupal’s Theme System le fond de ma pensée. Au lieu de retranscrire son article ici même, je vais plutôt vous présenter de quoi il retourne.

Pourquoi le theming Drupal est-il si compliqué ?

Depuis que je travaille sur Drupal 7, il ne se passe pas une semaine sans que j’ai à pester contre son système de thème. Comme le souligne Jacine, les nombreux points d’entrées et la multiplicité de niveaux d’interactions font qu’il est souvent difficile de trouver où intervenir.

Quel preprocess appeler ? Celui-ci ?
Perdu. Testons dans un autre ou dans un hook_alter.
Toujours rien. Peut-être dans un hook_process ?
Finalement, il me faut surcharger un hook_theme parce que je ne peux agir sur ce pre-render

J’exagère un peu, quoique, pas tant que ça finalement.
Vous allez me dire qu’avec Drupal 6 nous étions habitué à cette gymnastique mentale, ce à quoi je réponds oui, mais. Mais, c’était moins anarchique. Exemple.

Un exemple tout bête

Pour un type de contenu spécifique, un client demande à pouvoir insérer librement du code JavaScript et des styles CSS depuis l’espace de contribution. Pas de problème, il me suffit de récupérer le contenu des champs et de les attacher à la page à l’aide des fonctions drupal_add_js et drupal_add_css en précisant un type inline et les scopes appropriés. Ni une ni deux, je m’exécute et fais le nécessaire dans une implémentation de hook_preprocess_node() et, sans surprise, cela fonctionne.

Note : les extraits de codes qui suivent sont simplifiés pour se focaliser sur le sujet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
/**
 * @file template.php
 */
/**
 * Implements hook_preprocess_node().
 */
function MYTHEME_preprocess_node(&$vars) {
  // Nous utilisons la propriété `value` au lieu de `safe_value` qui encode les quotes.
  if (!empty($vars['field_inline_css'][0]['value'])) {
    drupal_add_css($vars['field_inline_css'][0]['value'], array(
      'type'       => 'inline',
      'group'      => CSS_THEME,
      'every_page' => false,
      'media'      => 'all',
      'preprocess' => false, // ne pas aggréger avec les autres styles
    ));
  }
  // -- snip --
}

Malheureusement le markup HTML des champs est malgré tout généré dans le flux du contenu. Ok, il me suffit de les masquer (au sens Drupal 7 du terme). Je regarde pour appliquer un coup de hide() sur mes champs depuis mon implémentation du preprocess_node. Mince, ces derniers sont déjà marqués comme rendus, leurs contenu calculé, etc. Pas mieux depuis un hook_page_alter(), ni depuis le fichier de template dédié. Pourtant la documentation officielle ne cesse de montrer comme il est facile de gérer la visibilité des champs.

Que faire ? Dois-je perdre du temps pour rendre un à un tous les champs à afficher pour ce type de contenu, ou est-ce que je pousse un peu l’investigation ? J’opte pour la seconde option tellement cette situation me paraît ridicule.

Rapidement, je trouve que je peux masquer mes champs en implémentant le hook_node_view_alter(). Tout fonctionne.

1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * @file template.php
 */
/**
 * Implements hook_node_view_alter().
 */
function MYTHEME_node_view_alter(&$build) {
  hide($build['field_inline_css']);
  hide($build['field_inline_js']);
}

Cependant, gérer ces champs à deux endroits n’est pas des plus lisible. Je rapatrie donc le code ajouté dans l’implémentation du hook_preprocess_node() dans mon hook_node_view_alter.
Déconfiture : seule l’injection du JavaScript est prise en compte. Celle des styles CSS est tout bonnement ignorée ;!

WTF Drupal (╯°□°)╯︵ ┻━┻

Et c’est ainsi que je me suis résigné à scinder cette étape de theming en 2 emplacements distincts. Le tout agrémenté d’explications en commentaires pour ne pas m’y perdre dans quelques mois ou tout simplement pour aider mes collègues à s’y retrouver.

Comment en est-on arrivé là ?

La faute en incombe en partie à une structure de données non normalisée couplée à un système de render array alléchant mais qui ne tient pas ses promesses. Tout module gère ses données à transmettre à l’API render comme bon lui chante. De ce fait il existe presque autant de cas de figure qu’il y a de modules :-/ Au niveau des fichiers de template, nous avons le droit à une soupe de variables au type simple et de render array.

Également, les modules peuvent transformer la structure des render array et nous mettre des bâtons dans les roues pour le theming (les modules Field Group et Display Suite en sont de bons exemples).

Pour finir, bien des situations complexes pourraient être évités si le core de Drupal exploitait systématiquement les render array. Il arrive toujours un moment où, alors que nous cherchons à modifier le #prefix d’un élément, l’on tombe sur du pur HTML. Tout ça parce qu’une implémentation du hook_theme() ne retourne pas de render array, comme theme_links() par exemple…

L’avenir du theming avec Drupal 8

FIXME. C’est l’idée :D
Jacine propose une standardisation de composant qui aura le bénéfice de simplifier le templating en rationnalisant la construction d’une page et, surtout, chaque module pourra arrêter de nous noyer sous des kilomètres de classes CSS “au cas où…”.

publicité (chargement)

Ajouter un commentaire


Syndication

Réseaux sociaux