Mengubah bentuk admin / konten

8

Setelah menambahkan "diubah oleh" pada node saya sekarang perlu menampilkan pengguna yang memodifikasi setiap node pada node_admin_contentformulir (at admin/content) tepat di sebelah kolom "Author".

Saya telah berhasil memecahkan ini dengan mengubah node.admin.inc dan menambahkan hanya 2 baris kode:

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

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

Ini, tentu saja, bukan solusi yang tepat karena mengubah inti.

Jadi saya kemudian mencoba mengubah formulir melalui:

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

Dengan menggunakan dpmsaya dapat melihat bahwa formulir memiliki node dalam opsi. Masalahnya adalah bahwa ini adalah hasil dari rendering node sebagai opsi tabel. Saya tidak memiliki akses ke node asli, saya juga tidak ingin menjalankan kembali node fetch query untuk mendapatkan informasi "diubah oleh". Saya kira melakukan ini dalam bentuk kait tidak akan menyelesaikannya di lapisan yang benar. Atau itu?

Jadi, apa cara yang baik untuk mengubah node_admin_contentformulir untuk menambahkan lebih banyak data yang ada pada node?

cherouvim
sumber

Jawaban:

18

Berita buruknya adalah bahwa setelah memeriksa kode, form alter layer adalah satu-satunya tempat untuk benar-benar melakukan ini; pendekatan Anda cukup tepat.

Berita baiknya adalah, Drupal mengimplementasikan semua jenis caching statis di seluruh halaman, yang meminimalkan kebutuhan untuk kembali ke database. Jadi, sementara mengubah tabel konten mungkin tampak rumit, Anda tidak benar-benar melakukan hit kinerja yang nyata.

Kode berikut (atau yang serupa) harus berfungsi; lihat komentar untuk info lebih lanjut tentang masalah caching:

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

Kode di atas menghasilkan kolom baru mengkilap yang bagus seperti ini di halaman admin konten:

masukkan deskripsi gambar di sini

Clive
sumber
4
Hebat! Terima kasih banyak telah menyediakan dokumentasi berkualitas dengan jawaban Anda.
cherouvim
@cherouvim Jangan khawatir :)
Clive
Terima kasih ini berfungsi untuk saya juga, tetapi saya ingin mengubah kolom yang ada seperti saya ingin menampilkan nama pengguna Penulis atau nama asli, bukan email Penulis di kolom penulis.
Pranav Gandhi
3

Ganti saja admin / konten dengan Tampilan, lalu tambahkan bidang mana saja yang Anda inginkan. Tampilan Admin bahkan akan melakukannya untuk Anda.

Bojan Zivanovic
sumber
Itu adalah pemikiran pertama saya juga, tetapi akankah Views secara otomatis tahu tentang kolom baru yang ditambahkan ke tabel simpul? Apakah ia mendapat info tentang properti entitas dari hook_schema()/ hook_schema_alter()implementasi?
Clive
Saya berasumsi Anda baru saja menambahkan bidang CCK. Saya melihat sekarang bahwa Anda pergi dengan hook_schema_alter (), yang sangat yuck. Namun, Anda dapat menerapkan hook_views_data_alter () untuk mengekspos kolom baru.
Bojan Zivanovic
Ya itu tidak terasa 'benar' untuk melakukan itu, tetapi saya tidak tahu mengapa. Bisakah Anda memikirkan skenario di mana menambahkan kolom dengan cara itu sebenarnya akan menyebabkan masalah?
Clive
Itu tidak menimbulkan masalah, hanya memberi Anda sedikit pekerjaan ekstra (seperti membutuhkan hook_views_data_alter () untuk Views, sama untuk properti jika Anda menggunakan D7) ketika sedang "secara ideologis" salah, itu adalah cara berpikir yang sangat Drupal 5 . Oh well, bukan masalah besar.
Bojan Zivanovic
Terima kasih itu bagus untuk diketahui. Secara pribadi saya selalu menggunakan bidang untuk hal semacam ini tetapi menarik untuk mengetahui bahwa hal itu dapat dilakukan tanpa efek samping yang besar. Jawaban Anda berbicara banyak tentang itu; jika Anda melakukannya dengan cara yang tepat / direkomendasikan (yaitu dengan bidang) Anda menghemat banyak pekerjaan nanti
Clive
0

Sedikit masalah, tetapi jawaban ini menunjukkan bagaimana Anda dapat melakukan ini secara terprogram (misalnya dengan menambahkannya sebagai pembaruan modul di file MY_MODULE.install.)

Anda perlu sedikit lebih banyak pekerjaan jika Anda ingin menambahkan bidang baru Anda sebelum bidang terakhir yang ada. Gabungkan sebelum akhir $ view-> display ['default'] -> display_options ['fields'] array.

    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
sumber