13

使用 cck 节点引用的自动完成字段始终将节点 ID 显示为隐蔽的括号扩展:

Page Title [nid:23]

我知道这可以确保在节点具有相同标题的情况下选择是唯一的,但显然这对用户来说是一件令人讨厌的事情。

有没有人成功删除这些括号或添加不同的唯一标识符?

4

6 回答 6

17

最终,您需要更改nodereference_autocomplete()nodereference.module 中的输出。

要正确执行此操作,您需要一个自定义模块来干净地覆盖该函数。

这个函数被定义为一个菜单回调,因此,

/**
 * Implementation of hook_menu_alter().
 */
function custom_module_menu_alter(&$items) {
  $items['nodereference/autocomplete']['page callback'] = 'custom_module_new_nodereference_autocomplete';
}

然后,将 nodereference_autocomplete 函数复制到您的自定义模块中,更改其名称以匹配您的回调。然后改变这一行:

$matches[$row['title'] ." [nid:$id]"] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';

删除nid 参考。

$matches[$row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';

我相信此时标识符纯粹是装饰性的,这意味着您也可以随意更改文本。如果它不是纯粹的装饰,那么我还没有测试过在错误的条件下会发生什么。

我一直想确定如何做到这一点。谢谢你用你的问题激励我。

于 2009-10-04T07:05:25.147 回答
6

Grayside 发布的内容将起作用……只要您没有两个具有相同标题的节点。换句话说,如果你想按照 Grayside 的建议去做,你需要知道 nid 并不是完全不重要的。nodereference_autocomplete_validate ()函数做了两件事。它检查是否有匹配的节点,如果是,则将 nid 传递给$form_state数组。如果找不到节点,则会设置错误。如果 nid 存在,它将用于获取节点,这也更快,代码在这里:

preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $value, $matches);
    if (!empty($matches)) {
        // Explicit [nid:n].
        list(, $title, $nid) = $matches;
        if (!empty($title) && ($n = node_load($nid)) && $title != $n->title) {
            form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array('%name' => t($field['widget']['label']))));
        }
    }

这只是检查是否有 nid 并检查该节点是否与标题匹配,如果是,则传递 nid。

第二个选项有点慢,但在这里可能会发生错误。如果你跟着执行,你会看到,if 将尝试仅根据标题查找节点,并将获取第一个匹配的节点。这样做的结果是,如果您有两个具有相同标题的节点,则将始终使用其中一个。这对您来说可能不是问题,但问题是,您永远不会发现这种情况是否发生。一切都会正常工作,用户会认为他选择了他想要的节点。可能是这种情况,但他也可能选择了错误的节点。

所以简而言之,你可以摆脱自动完成回调中的nid,但它有2个缺点:

  1. 表现(少许)
  2. 选择正确节点的不确定性。

所以在走这条路之前,你必须考虑一下。特别是,如果发生这种情况,您很可能无法找到选择错误节点的问题。另一件需要注意的事情是,nid 的出现,也给用户带来了一些有价值的信息,一种快速查找节点的方法,如果他们怀疑它是否是他们想要的,如果几个节点有相似的标题.

于 2009-10-04T21:41:24.563 回答
0

我得到了 Grayside 的工作答案,但我不得不使用 MENU alter,而不是他发布的 FORM alter。没什么大不了的!

function custommodule_menu_alter(&$items) {
  $items['nodereference/autocomplete']['page callback'] = 'fp_tweaks_nodereference_autocomplete';
}
于 2010-05-28T21:08:39.603 回答
0

我发现另一种解决方案是将您的小部件类型更改为选择列表,然后使用所选模块将您的列表转换为自动完成字段。

这处理具有相同标题的节点,实际上我认为 UI 比自动完成小部件提供的更好。

于 2014-03-07T15:36:33.433 回答
0

对于通过谷歌搜索遇到这个(相当老的)主题的任何人 - 对于 Drupal 7,请尽可能考虑使用实体引用模块和“实体引用”字段类型。

您可以使用“实体参考”字段在配置中实现更多目标。方括号中的nid没有这个问题。

于 2015-07-31T10:20:41.490 回答
0

这是 Grayside 答案的完整 Drupal 7 版本(参考 7.x-2.1)。这在您的自定义模块中:

/**
 * Implementation of hook_menu_alter().
 */
function custom_menu_alter(&$items) {
  $items['node_reference/autocomplete/%/%/%']['page callback'] = 'custom_new_node_reference_autocomplete';
}

/**
 * Implementation of Menu callback for the autocomplete results.
 */
function custom_new_node_reference_autocomplete($entity_type, $bundle, $field_name, $string = '') {
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle);

  $options = array(
    'string' => $string,
    'match' => $instance['widget']['settings']['autocomplete_match'],
    'limit' => 10,
  );
  $references = node_reference_potential_references($field, $options);

  $matches = array();
  foreach ($references as $id => $row) {
    // Markup is fine in autocompletion results (might happen when rendered
    // through Views) but we want to remove hyperlinks.
    $suggestion = preg_replace('/<a href="([^<]*)">([^<]*)<\/a>/', '$2', $row['rendered']);
    // Add a class wrapper for a few required CSS overrides.
    $matches[$row['title']] = '<div class="reference-autocomplete">' . $suggestion . '</div>'; // this is the line that was modified to remove the "[nid:XX]" disambiguator
  }

  drupal_json_output($matches);
}
于 2016-06-23T17:44:49.640 回答