Ändern des Administrations- / Inhaltsformulars

8

Nachdem ich auf Knoten ein "Geändert von" hinzugefügt habe , muss ich nun den Benutzer, der jeden Knoten geändert hat, im node_admin_contentFormular (at admin/content) direkt neben der Spalte "Autor" anzeigen .

Ich habe es geschafft, dies einfach zu lösen, indem ich node.admin.inc geändert und nur 2 Codezeilen hinzugefügt habe:

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

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

Dies ist natürlich keine richtige Lösung, da es den Kern verändert.

Also habe ich dann versucht, das Formular zu ändern über:

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

Mit dpmkann ich sehen, dass das Formular die Knoten in Optionen hat. Das Problem ist, dass dies das Ergebnis des Renderns der Knoten als Tabellenoptionen ist. Ich habe keinen Zugriff auf die ursprünglichen Knoten und möchte die Knotenabrufabfrage nicht erneut ausführen, um die Informationen "Geändert von" zu erhalten. Ich denke, dies im Formular-Hook zu tun, würde es nicht in der richtigen Ebene lösen. Oder ist es?

Was ist also eine gute Möglichkeit, das node_admin_contentFormular zu ändern , um weitere Daten hinzuzufügen, die auf Knoten vorhanden sind?

Cherouvim
quelle

Antworten:

18

Die schlechte Nachricht ist, dass nach dem Überprüfen des Codes die Formularänderungsebene der einzige Ort ist, an dem dies wirklich möglich ist. Ihr Ansatz ist ziemlich genau richtig.

Die gute Nachricht ist, dass Drupal während des gesamten Seitenladens alle Arten von statischem Caching implementiert, wodurch die Notwendigkeit minimiert wird, wieder in die Datenbank zurückzukehren. Während das Ändern der Inhaltstabelle umständlich erscheint, erzielen Sie keinen spürbaren Leistungseinbruch.

Der folgende Code (oder ähnliches) sollte funktionieren. Weitere Informationen zum Caching-Problem finden Sie in den Kommentaren:

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));
  }
}

Der obige Code erzeugt eine schöne, glänzende neue Spalte wie diese auf der Inhaltsadministrationsseite:

Geben Sie hier die Bildbeschreibung ein

Clive
quelle
4
Hervorragend! Vielen Dank für die Bereitstellung einer qualitativ hochwertigen Dokumentation mit Ihrer Antwort.
Cherouvim
@cherouvim Keine Sorge :)
Clive
Vielen Dank, dass es auch für mich funktioniert, aber ich möchte vorhandene Spalten so ändern, dass ich den Benutzernamen des Autors oder den echten Namen anstelle der E-Mail des Autors in der Autorenspalte anzeigen möchte.
Pranav Gandhi
3

Ersetzen Sie einfach admin / content durch eine Ansicht und fügen Sie dann die gewünschten Felder hinzu. Admin Views erledigt das sogar für Sie.

Bojan Zivanovic
quelle
Das war auch mein erster Gedanke, aber würde Views automatisch über die neue Spalte Bescheid wissen, die der Knotentabelle hinzugefügt wurde? Erhält es Informationen zu Entitätseigenschaften von hook_schema()/ hook_schema_alter()Implementierungen?
Clive
Ich nahm an, Sie haben gerade ein CCK-Feld hinzugefügt. Ich sehe jetzt, dass du mit hook_schema_alter () gegangen bist, was sehr igitt ist. Sie können dennoch hook_views_data_alter () implementieren, um die neue Spalte verfügbar zu machen.
Bojan Zivanovic
Ja, es fühlte sich nicht 'richtig' an, das zu tun, aber ich kann nicht sagen warum. Können Sie sich ein Szenario vorstellen, in dem das Hinzufügen der Spalte auf diese Weise tatsächlich ein Problem verursachen würde?
Clive
Es verursacht keine Probleme, gibt Ihnen nur ein bisschen zusätzliche Arbeit (wie das Erfordernis von hook_views_data_alter () für Ansichten, das gleiche für Eigenschaften, wenn Sie auf D7 sind), während es "ideologisch" falsch ist, es ist eine sehr Drupal 5-Denkweise . Na ja, keine große Sache.
Bojan Zivanovic
Danke, das ist gut zu wissen. Persönlich würde ich immer Felder für solche Dinge verwenden, aber es war interessant herauszufinden, dass dies ohne große Nebenwirkungen möglich ist. Ihre Antwort spricht jedoch Bände darüber; Wenn Sie es richtig / empfohlen machen (dh mit Feldern), sparen Sie sich später viel Arbeit
Clive
0

Ein wenig abseits des Themas, aber diese Antwort zeigt, wie Sie dies programmgesteuert tun können (z. B. indem Sie es als Modulaktualisierung in die Datei MY_MODULE.install einfügen).

Sie benötigen etwas mehr Arbeit, wenn Sie Ihr neues Feld vor dem letzten vorhandenen Feld hinzufügen möchten. Führen Sie es vor dem Ende des Arrays $ view-> display ['default'] -> display_options ['fields'] ein.

    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
quelle