删除nodereference自动完成中的[nid:n]

时间:2009-10-04 05:56:51

标签: drupal drupal-6 cck

使用cck nodereference的自动填充字段始终将节点ID显示为隐藏的加密扩展名:

Page Title [nid:23]

我理解这可以确保选择在节点具有相同标题的情况下是唯一的,但显然这对于​​向用户公开是件令人讨厌的事情。

是否有人在删除这些括号或添加其他唯一标识符方面取得了成功?

6 个答案:

答案 0 :(得分:17)

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

要正确执行此操作,您需要自定义模块干净地覆盖该功能。

此功能被定义为菜单回调,因此,

/**
 * 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>';

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

我一直想确定如何做到这一点。感谢您激励我提出问题。

答案 1 :(得分: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。

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

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

  1. 表现(小)
  2. 选择正确节点的不确定性。
  3. 所以在走这条路之前你必须考虑一下。特别是,因为你很可能无法找到选择错误节点的问题,所以它应该发生。需要注意的另一件事是,nid出现,也为用户带来了一些有价值的信息,一种查找节点的快捷方式,如果它们是他们想要的那个,如果有几个节点有相似的标题,他们是否会有疑问

答案 2 :(得分:0)

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

function custommodule_menu_alter(&$items) {
  $items['nodereference/autocomplete']['page callback'] = 'fp_tweaks_nodereference_autocomplete';
}

答案 3 :(得分:0)

我发现另一种解决方案是更改窗口小部件类型以选择列表,然后使用chosen module将列表转换为自动填充字段。

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

答案 4 :(得分:0)

对于通过谷歌搜索遇到此(相当古老)主题的任何人 - 对于Drupal 7,请考虑使用entityreference模块和&#34;实体参考&#34;字段类型,如果可能的话。

使用&#34;实体参考&#34;您可以在配置中实现更多功能。领域。方括号中的nid没有这个问题。

答案 5 :(得分: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);
}