Alterando o formulário de administração / conteúdo

8

Depois de adicionar um "alterado por" nos nós , agora preciso exibir o usuário que modificou cada nó no node_admin_contentformulário (at admin/content) ao lado da coluna "Autor".

Eu consegui resolver isso facilmente alterando node.admin.inc e adicionando apenas 2 linhas de código:

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

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

Obviamente, essa não é uma solução adequada, pois altera o núcleo.

Então, tentei alterar o formulário via:

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

Usando dpmposso ver que o formulário tem os nós nas opções. O problema é que esse é o resultado da renderização dos nós como opções da tabela. Não tenho acesso aos nós originais, nem quero re-executar a consulta de busca do nó para obter as informações "alteradas por". Eu acho que fazer isso no gancho de forma não seria resolvê-lo na camada correta. Ou é?

Então, qual é uma boa maneira de alterar o node_admin_contentformulário para adicionar mais dados que existem nos nós?

cherouvim
fonte

Respostas:

18

A má notícia é que, depois de inspecionar o código, a forma alter layer é o único local para realmente fazer isso; sua abordagem é bastante clara.

A boa notícia é que o Drupal implementa todos os tipos de cache estático em todo o carregamento da página, o que minimiza a necessidade de voltar ao banco de dados. Portanto, embora a alteração da tabela de conteúdo possa parecer complicada, você não está sofrendo um impacto perceptível no desempenho.

O código a seguir (ou similar) deve funcionar; veja os comentários para obter mais informações sobre o problema de armazenamento em 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));
  }
}

O código acima produz uma nova coluna agradável e brilhante como esta na página de administração de conteúdo:

insira a descrição da imagem aqui

Clive
fonte
4
Soberbo! Muito obrigado por fornecer documentação de qualidade com sua resposta.
29412 Cherouvim
@cherouvim Não se preocupe :)
Clive
Obrigado por trabalhar também para mim, mas quero alterar as colunas existentes, como desejo exibir o nome de usuário ou o nome real do autor, em vez do email do autor na coluna do autor.
Pranav Gandhi
3

Apenas substitua admin / content por uma View e adicione os campos que desejar. As Visualizações de administrador farão isso por você.

Bojan Zivanovic
fonte
Esse foi o meu primeiro pensamento também, mas o Views saberia automaticamente sobre a nova coluna que foi adicionada à tabela de nós? Ele obtém informações sobre propriedades da entidade de hook_schema()/ hook_schema_alter()implementações?
Clive
Supus que você acabou de adicionar um campo CCK. Vejo agora que você foi com hook_schema_alter (), que é muito eca. Ainda assim, você pode implementar hook_views_data_alter () para expor a nova coluna.
Bojan Zivanovic
Sim, não parecia "certo" fazer isso, mas não sei por que. Você consegue pensar em um cenário em que adicionar a coluna dessa maneira realmente causaria um problema?
Clive
Isso não causa problemas, apenas fornece um pouco de trabalho extra (como precisar de hook_views_data_alter () para Views, o mesmo para propriedades se você estiver no D7) enquanto estiver "ideologicamente" errado, é uma maneira de pensar muito Drupal 5 . Oh bem, não é grande coisa.
Bojan Zivanovic
Obrigado, é bom saber. Pessoalmente, eu sempre usava campos para esse tipo de coisa, mas era interessante descobrir que isso poderia ser feito sem grandes efeitos colaterais. Sua resposta fala muito sobre isso; se você fizer da maneira apropriada / recomendada (ou seja, com campos), poupará muito trabalho mais tarde
Clive
0

Um pouco fora do assunto, mas esta resposta mostra como você pode fazer isso programaticamente (por exemplo, adicionando-o como uma atualização de módulo no arquivo MY_MODULE.install.)

Você precisará de um pouco mais de trabalho se desejar adicionar seu novo campo antes do último campo existente. Faça a mesclagem antes do final da matriz $ 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
fonte