使用 cck 节点引用的自动完成字段始终将节点 ID 显示为隐蔽的括号扩展:
Page Title [nid:23]
我知道这可以确保在节点具有相同标题的情况下选择是唯一的,但显然这对用户来说是一件令人讨厌的事情。
有没有人成功删除这些括号或添加不同的唯一标识符?
最终,您需要更改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>';
我相信此时标识符纯粹是装饰性的,这意味着您也可以随意更改文本。如果它不是纯粹的装饰,那么我还没有测试过在错误的条件下会发生什么。
我一直想确定如何做到这一点。谢谢你用你的问题激励我。
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个缺点:
所以在走这条路之前,你必须考虑一下。特别是,如果发生这种情况,您很可能无法找到选择错误节点的问题。另一件需要注意的事情是,nid 的出现,也给用户带来了一些有价值的信息,一种快速查找节点的方法,如果他们怀疑它是否是他们想要的,如果几个节点有相似的标题.
我得到了 Grayside 的工作答案,但我不得不使用 MENU alter,而不是他发布的 FORM alter。没什么大不了的!
function custommodule_menu_alter(&$items) {
$items['nodereference/autocomplete']['page callback'] = 'fp_tweaks_nodereference_autocomplete';
}
我发现另一种解决方案是将您的小部件类型更改为选择列表,然后使用所选模块将您的列表转换为自动完成字段。
这处理具有相同标题的节点,实际上我认为 UI 比自动完成小部件提供的更好。
对于通过谷歌搜索遇到这个(相当老的)主题的任何人 - 对于 Drupal 7,请尽可能考虑使用实体引用模块和“实体引用”字段类型。
您可以使用“实体参考”字段在配置中实现更多目标。方括号中的nid没有这个问题。
这是 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);
}