更改管理员/内容形式


8

节点上添加了“由...更改”后,我现在需要在“作者”列旁边的node_admin_content表单上(在admin/content)上显示修改了每个节点的用户。

我设法通过更改node.admin.inc并仅添加两行代码来轻松解决此问题:

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

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

当然,这不是适当的解决方案,因为它会更改内核。

因此,我然后尝试通过以下方式更改表格:

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

使用,dpm我可以看到表单在选项中有节点。问题在于这是将节点渲染为表选项的结果。我无权访问原始节点,也不想重新执行节点获取查询以获取“更改者”信息。我想在表单挂钩中执行此操作不会在正确的层中解决它。还是?

那么,改变node_admin_content表单以添加更多存在于节点上的数据的好方法是什么?

Answers:


18

坏消息是,在检查了代码之后,表单更改层才是真正执行此操作的唯一位置。您的方法几乎是正确的。

好消息是,Drupal在整个页面加载期间实现了各种静态缓存,从而最大程度地减少了返回数据库的需求。因此,尽管更改内容表可能看起来很麻烦,但实际上并没有带来明显的性能损失。

以下代码(或类似代码)应该有效;请参阅注释以获取有关缓存问题的更多信息:

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

上面的代码在内容管理页面上产生了一个漂亮的闪亮新列,如下所示:

在此处输入图片说明


4
高超!非常感谢您提供高质量的文档以及您的答案。
cherouvim 2012年

@cherouvim不用担心:)
Clive

也感谢它为我所做的工作,但是我想更改现有的列,例如我想在作者列中显示作者用户名或真实姓名,而不是作者电子邮件。
普拉纳夫·甘地

3

只需将View替换为admin / content,然后添加所需的任何字段即可。 管理员视图甚至可以为您完成此任务。


那也是我的第一个想法,但是Views是否会自动知道添加到节点表中的新列?它是否从hook_schema()/ hook_schema_alter()实现获取有关实体属性的信息?
克莱夫(Clive)

我以为您刚刚添加了CCK字段。我现在看到您选择了hook_schema_alter(),这真是太糟糕了。不过,您可以实现hook_views_data_alter()以公开新列。
Bojan Zivanovic

是的,这样做并没有感觉“正确”,但是我不能指责为什么。您能想到以这种方式添加列实际上会导致问题的情况吗?
克莱夫(Clive)

它不会造成任何问题,只是为您提供了一些额外的工作(例如,对于Views需要hook_views_data_alter(),对于D7而言,属性也是如此),而在“意识形态”上是错误的,这是Drupal的5种思维方式。哦,没什么大不了的。
Bojan Zivanovic

谢谢,很高兴知道。就我个人而言,我总是将字段用于此类事情,但有趣的是发现它可以在没有较大副作用的情况下完成。您的答案虽然说明了这一点;如果您以正确/推荐的方式(即使用字段)执行此操作,则以后可以节省很多工作
克莱夫(Clive)

0

主题稍有偏离,但是此答案显示了如何以编程方式执行此操作(例如,通过将其作为模块更新添加到MY_MODULE.install文件中)。

如果要在最后一个现有字段之前添加新字段,则需要做更多的工作。将其合并到$ 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);
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.