Modifier la liste déroulante d’un champ nodereference dans drupal 6

Nodereference (inclus dans CCK) est un module très pratique. Il permet simplement d’effectuer des relations entre différents nodes. Je ne reviens pas sur l’utilisation de ce module, Marie-Hélène s’en est chargée avec brio.

Un des widgets possible d’un champ nodereference est la liste déroulante (select list, ou combo-box), qui permet de choisir un node parmi plusieurs dans une liste. Cette liste déroulante nous affiche les titres des nodes référençables, mais cela manque parfois de détail et on aimerait pouvoir l’altérer afin d’y ajouter d’autres informations.
Notre exemple, volontairement très simple, consiste à ajouter le nid du node à coté de son titre.

Comme pour toute altération de formulaire, on utilise le hook_form_alter(). Le champ nodereference (ici ‘field_noderef’) est fourni par cck, et si on le regarde au moment du form_alter ($form['field_noderef']), on ne verra pas l’état final du champ. En effet, CCK s’occupe de ses champs après la construction du formulaire (le ‘build’). Pour les modifier, il faut passer après (‘after_build’)

function monmodule_form_alter(&$form, &$form_state, $form_id) {
  // assurons nous d'être dans le formulaire correspondant à notre type de contenu
  if ($form_id == 'mycontenttype_node_form') {

    // ajoutons une fonction d' #after_build à notre champ nodereference
    $form['field_noderef']['#after_build'][] = 'customnoderef_select';
  }
}

Il nous reste à écrire notre fonction:

function customnoderef_select($form_element, &$form_state) {

  // #columns contient le type de clé du champ nodereference: nid (node), ou uid (user)
  $column = $form_element['#columns'][0];

  // Récupération des options par defaut
  $default_options = $form_element[$column][$column]['#options'];

  /** Alteration
   * La clé du tableau ($k) représente le nid
   * La valeur ($v) représente le titre
   */
  foreach($default_options as $k => $v) {
    $default_options[$k] = '[' . $k . '] '. $v;
  }

  // Ecriture des options altérées
  $form_element[$column][$column]['#options'] = $default_options;

  // renvoi de l'élément du formulaire
  return $form_element;
}

Et voila, il a suffit de ces 2 hooks pour altérer le widget d’un champ nodereference. La stratégie est la même pour modifier les autres types de champs CCK (En anglais, l’altération d’un champ filefield)

Notre altération reste très simple, le but de l’article étant de montrer le principe de base. En réalité, on cherchera généralement à afficher d’autres informations sur le node, comme son type, sa date de création… Dans ces cas, il faut passer par une étape de récupération d’information (Requête sur la base de données).

Sources:
http://drupal.org/node/935088
http://ossolutions.org/article/alter-cck-filefield-elements

Comme d’habitude, je suis preneur d’autres techniques, d’alternatives, de critiques constructives, de correction de typo…

19 fév 2011 catégorie : | Mots-clés : , ,

3 Commentaires

  • 23 fév 2011 Marie-Hélène

    Merci pour ces indications ; pour les non techniciens, il y a quelques modules qui répondent au besoin de faciliter la recherche d’un noeud (nrembrowser, node relationships, node reference fields…). Je ne les connais pas bien personnellement.

  • 23 fév 2011 opi

    Pour ceux qui souhaitent dépasser la limite de 10 elements dans la liste déroulante, un patch a nodereference.module est proposé ici: http://drupal.org/node/505272#comment-3605658
    (via @asplamagnifique )

    ( Dans la fonction de callback du #after_build, c’est également possible de faire une requete perso, et de charger plus que 10 elements. L’exemple est volontairement très simple.

  • 28 nov 2011 Castelnau

    Merci pour l’astuce concernant le nombre de nodes listés dans une réponse de nodereference, je teste asap…

    …en ayant en parallèle le besoin de thémer en CSS la liste nodereference de façon plus large que 100% du champ dans le formulaire de création. En effet je mets 5 champs CCK sur une seule ligne de formulaire, et la liste nodereference hérite de la taille initiale du champ.

    Pour ceux qui souhaitent faire du lien facile vers un node directement dans un body ou un champ CCK, un peu comme un nodereference lors d’une saisie de texte, je signale l’excellent module CKE Link lié à l’éditeur CKEditor, très pratique pour le seo par ailleurs.

Poster un commentaire