Modification du formulaire d'administration / de contenu

8

Après avoir ajouté un «modifié par» sur les nœuds, je dois maintenant afficher l'utilisateur qui a modifié chaque nœud sur le node_admin_contentformulaire (à admin/content) juste à côté de la colonne «Auteur».

J'ai réussi à résoudre ce problème facilement en modifiant node.admin.inc et en ajoutant seulement 2 lignes de code:

...
'changed_by' => t('Changed By'),
...

...
'changed_by' => theme('username', array('account' => user_load($node->changed_by))),
...

Bien sûr, ce n'est pas une bonne solution car cela modifie le noyau.

J'ai donc essayé de modifier le formulaire via:

function hook_form_node_admin_content_alter(&$form, &$form_state, $form_id) { 
  $form['admin']['nodes']['#header']['changed_by'] = t('Changed By');
  // ... ?
}

En utilisant dpmje peux voir que le formulaire a les nœuds dans les options. Le problème est que cela est le résultat du rendu des nœuds en tant qu'options de table. Je n'ai pas accès aux nœuds d'origine et je ne souhaite pas réexécuter la requête d'extraction de nœud afin d'obtenir les informations "modifiées par". Je suppose que faire cela dans le crochet de formulaire ne le résoudrait pas dans la bonne couche. Ou est-ce?

Alors, quel est un bon moyen de modifier le node_admin_contentformulaire pour ajouter plus de données qui existent sur les nœuds?

cherouvim
la source

Réponses:

18

La mauvaise nouvelle, c'est qu'après avoir inspecté le code, la couche alter form est le seul endroit pour vraiment faire cela; votre approche est à peu près parfaite.

La bonne nouvelle est que Drupal implémente toutes sortes de cache statique tout au long du chargement de la page, ce qui minimise la nécessité de revenir dans la base de données. Ainsi, bien que la modification de la table de contenu puisse sembler fastidieuse, vous ne prenez pas réellement un coup de performance notable.

Le code suivant (ou similaire) devrait fonctionner; voir les commentaires pour plus d'informations sur le problème de mise en cache:

function MYMODULE_form_node_admin_content_alter(&$form, &$form_state, $form_id) {
  // Load the nodes. This incurrs very little overhead as 
  // "$nodes = node_load_multiple($nids);" has already been run on these
  // nids in node_admin_nodes(). The static cache will be used instead of
  // another db query being invoked
  $nodes = node_load_multiple(array_keys($form['admin']['nodes']['#options']));

  // Grab a list of all user ids that have been responsible for changing the node
  $uids = array();
  foreach ($nodes as $node) {
    $uids[] = $node->changed_by;
  }

  // Filter out duplicates (one user may have been the last to change more than one node)
  $uids = array_unique($uids);

  // Load a list of all involved users in one go. This is about as performant
  // as this is going to get, as you're going to need the user objects one
  // way or the other for the call to theme_username
  $users = user_load_multiple($uids);

  // Add another column to the table header
  $form['admin']['nodes']['#header']['changed_by'] = array('data' => t('Changed by'));

  // Loop through the rows in the table and add the changed by column
  foreach ($form['admin']['nodes']['#options'] as $nid => $row) {
    // Grab the user related to this node.
    $this_user = $users[$nodes[$nid]->changed_by];

    // Add data for the new column
    $form['admin']['nodes']['#options'][$nid]['changed_by'] = theme('username', array('account' => $this_user));
  }
}

Le code ci-dessus produit une belle nouvelle colonne brillante comme celle-ci sur la page d'administration de contenu:

entrez la description de l'image ici

Clive
la source
4
Superbe! Merci beaucoup d'avoir fourni une documentation de qualité avec votre réponse.
cherouvim
@cherouvim Pas de soucis :)
Clive
Merci aussi pour son travail, mais je souhaite modifier les colonnes existantes comme si je voulais afficher le nom d'utilisateur ou le vrai nom de l'auteur au lieu du courrier électronique de l'auteur dans la colonne auteur.
Pranav Gandhi
3

Remplacez simplement admin / content par une vue, puis ajoutez les champs que vous souhaitez. Les vues d'administration le feront même pour vous.

Bojan Zivanovic
la source
C'était aussi ma première pensée, mais Views serait-il automatiquement informé de la nouvelle colonne qui a été ajoutée à la table des nœuds? Obtient-il des informations sur les propriétés d'entité de hook_schema()/ hook_schema_alter()implémentations?
Clive
Je suppose que vous venez d'ajouter un champ CCK. Je vois maintenant que vous êtes allé avec hook_schema_alter (), ce qui est très beurk. Pourtant, vous pouvez implémenter hook_views_data_alter () pour exposer la nouvelle colonne.
Bojan Zivanovic
Ouais, ça ne me semblait pas «bien» de faire ça, mais je ne peux pas dire pourquoi. Pouvez-vous imaginer un scénario dans lequel l'ajout de la colonne de cette manière entraînerait réellement un problème?
Clive
Cela ne pose aucun problème, vous donne juste un peu de travail supplémentaire (comme avoir besoin de hook_views_data_alter () pour les vues, de même pour les propriétés si vous êtes sur D7) tout en étant "idéologiquement" faux, c'est une façon de penser très Drupal 5 . Eh bien, ce n'est pas grave.
Bojan Zivanovic
Merci c'est bon à savoir. Personnellement, j'utilisais toujours des champs pour ce genre de choses, mais c'était intéressant de découvrir que cela pouvait se faire sans gros effets secondaires. Votre réponse en dit long cependant. si vous le faites de la manière appropriée / recommandée (c'est-à-dire avec des champs), vous vous épargnerez beaucoup de travail plus tard
Clive
0

Un peu hors sujet, mais cette réponse montre comment vous pouvez le faire par programme (par exemple en l'ajoutant en tant que mise à jour de module dans le fichier MY_MODULE.install.)

Vous aurez besoin d'un peu plus de travail si vous souhaitez ajouter votre nouveau champ avant le dernier champ existant. Fusionnez-le avant la fin du tableau $ view-> display ['default'] -> display_options ['fields'].

    function MY_MODULE_update_7101(){
        // update the admin/content view, need to do it manually because it's
        // set by admin_views module
        $view_name = 'admin_views_node';
        $view = views_get_view($view_name, TRUE);

        //  add the relationship
        $view->display['default']->display_options['relationships']['uid_1']['id'] = 'uid_1';
        $view->display['default']->display_options['relationships']['uid_1']['table'] = 'node_revision';
        $view->display['default']->display_options['relationships']['uid_1']['field'] = 'uid';
        $view->display['default']->display_options['relationships']['uid_1']['label'] = 'Revision User';
        // new column settings
        $new_column = array(
            'name_1' => array(
                'id' => 'name_1',
                'table' => 'users',
                'field' => 'name',
                'relationship' => 'uid_1',
                'label' => 'Updated By',
            )
        );
        // need to use this because array_splice by itself resets 'name_1' key to '0'
        // see http://php.net/manual/en/function.array-splice.php#56794
        $temp_array = array_splice( $view->display['default']->display_options['fields'] , 0, 7);
        $view->display['default']->display_options['fields'] = array_merge($temp_array , $new_column, $view->display['default']->display_options['fields']);

        views_save_view($view);
    }
reedbert
la source