我想将此功能添加到“实体引用”字段的“自动完成”小部件中,以在下拉列表的标题旁边显示节点ID。这个想法背后的原因是要区分具有相同标题的多个节点。
例:
- 这是一个标题(3)
- 这是一个标题(2)
- 这是一个标题(1)
我知道一旦选择就显示了节点ID,但我想在下拉列表中显示它,以便根据节点ID快速选择正确的节点。
我想将此功能添加到“实体引用”字段的“自动完成”小部件中,以在下拉列表的标题旁边显示节点ID。这个想法背后的原因是要区分具有相同标题的多个节点。
例:
我知道一旦选择就显示了节点ID,但我想在下拉列表中显示它,以便根据节点ID快速选择正确的节点。
Answers:
安装视图和实体引用模块,创建一个新的视图并添加一个实体引用显示:
然后在字段中添加内容标题和目录,单击目录,然后选中从显示中排除,保存并单击标题,然后将标题输出重写为 [title] - ([nid])
转到编辑格式设置并检查标题,这将允许您按标题搜索。
保存视图。
转到编辑您的“实体引用”字段,然后在“模式视图”中选择:....(如下图所示),然后选择您的视图(在本例中,名称为:articles_with_id)并保存设置:
然后去看看结果:
编辑:这现在在Drupal 8,至少在版本8.3.4中工作。
使用默认配置创建实体引用字段
函数entityreference_autocomplete_callback_get_matches确定自动完成的输出是什么。
function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
$matches = array();
$entity = NULL;
if ($entity_id !== 'NULL') {
$entity = entity_load_single($entity_type, $entity_id);
$has_view_access = (entity_access('view', $entity_type, $entity) !== FALSE);
$has_update_access = (entity_access('update', $entity_type, $entity) !== FALSE);
if (!$entity || !($has_view_access || $has_update_access)) {
return MENU_ACCESS_DENIED;
}
}
$handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);
if ($type == 'tags') {
// The user enters a comma-separated list of tags. We only autocomplete the last tag.
$tags_typed = drupal_explode_tags($string);
$tag_last = drupal_strtolower(array_pop($tags_typed));
if (!empty($tag_last)) {
$prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
}
}
else {
// The user enters a single tag.
$prefix = '';
$tag_last = $string;
}
if (isset($tag_last)) {
// Get an array of matching entities.
$entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);
// Loop through the products and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
$key = "$label ($entity_id)";
// Strip things like starting/trailing white spaces, line breaks and tags.
$key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
// Names containing commas or quotes must be wrapped in quotes.
if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
$key = '"' . str_replace('"', '""', $key) . '"';
}
/* *** */$matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .' - ('. $entity_id . ')</div>';//****
}
}
}
drupal_json_output($matches);
}
最后一行$matches[$prefix . $key] = '<div class="reference-autocomplete">'
确定输出,并且$entity_id
ID可用。您可以执行我在该行中所做的(由所示**
),只需编写:
$matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .' - ('. $entity_id . ')</div>';
您可以$entity_id
用来获取其他字段以及所需的任何内容。
有时,更改核心模块的功能不是一个好主意(如果对您来说不重要,上述解决方案就足够了)。
如果您需要覆盖entity_reference
模块的核心功能,请构建一个小模块并命名elabel
它是 elabel.info
;$Id;
name = My Entity Reference Label
description = This module creates special Entity Reference Label
package = My Modules
core = 7.x
php = 5.1
files[] = elabel.module
它是 elabel.module
<?php function elabel_menu_alter(&$items){
unset($items['entityreference/autocomplete/single/%/%/%']);
unset($items['entityreference/autocomplete/tags/%/%/%']);
$items['entityreference/autocomplete/single/%/%/%'] = array(
'title' => 'Entity Reference Autocomplete',
'page callback' => 'elabel_autocomplete_callback',
'page arguments' => array(2, 3, 4, 5),
'access callback' => 'entityreference_autocomplete_access_callback',
'access arguments' => array(2, 3, 4, 5),
'type' => MENU_CALLBACK,
);
$items['entityreference/autocomplete/tags/%/%/%'] = array(
'title' => 'Entity Reference Autocomplete',
'page callback' => 'elabel_autocomplete_callback',
'page arguments' => array(2, 3, 4, 5),
'access callback' => 'entityreference_autocomplete_access_callback',
'access arguments' => array(2, 3, 4, 5),
'type' => MENU_CALLBACK,
);
return $items;
}
function elabel_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '', $string = '') {
// If the request has a '/' in the search text, then the menu system will have
// split it into multiple arguments and $string will only be a partial. We want
// to make sure we recover the intended $string.
$args = func_get_args();
// Shift off the $type, $field_name, $entity_type, $bundle_name, and $entity_id args.
array_shift($args);
array_shift($args);
array_shift($args);
array_shift($args);
array_shift($args);
$string = implode('/', $args);
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
return elabel_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id, $string);
}
function elabel_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
$matches = array();
$entity = NULL;
if ($entity_id !== 'NULL') {
$entity = entity_load_single($entity_type, $entity_id);
$has_view_access = (entity_access('view', $entity_type, $entity) !== FALSE);
$has_update_access = (entity_access('update', $entity_type, $entity) !== FALSE);
if (!$entity || !($has_view_access || $has_update_access)) {
return MENU_ACCESS_DENIED;
}
}
$handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);
if ($type == 'tags') {
// The user enters a comma-separated list of tags. We only autocomplete the last tag.
$tags_typed = drupal_explode_tags($string);
$tag_last = drupal_strtolower(array_pop($tags_typed));
if (!empty($tag_last)) {
$prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
}
}
else {
// The user enters a single tag.
$prefix = '';
$tag_last = $string;
}
if (isset($tag_last)) {
// Get an array of matching entities.
$entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);
// Loop through the products and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
$key = "$label ($entity_id)";
// Strip things like starting/trailing white spaces, line breaks and tags.
$key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
// Names containing commas or quotes must be wrapped in quotes.
if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
$key = '"' . str_replace('"', '""', $key) . '"';
}
/* *** */ $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .'('.$entity_id.')' .'</div>';
}
}
}
drupal_json_output($matches);
}
我尝试了这段代码,它可以完美地工作如果还有其他类型的实体引用,而您不需要为它们执行此操作,只需添加一条IF
语句并检查bundle或内容类型。