在实体参考自动完成列表中显示节点ID和标题


8

我想将此功能添加到“实体引用”字段的“自动完成”小部件中,以在下拉列表的标题旁边显示节点ID。这个想法背后的原因是要区分具有相同标题的多个节点。

例:

  • 这是一个标题(3)
  • 这是一个标题(2)
  • 这是一个标题(1)

我知道一旦选择就显示了节点ID,但我想在下拉列表中显示它,以便根据节点ID快速选择正确的节点。



@ oksana-c用另一种简单的方法检查我的答案
Adrian Cid Almaguer

Answers:


20

安装视图实体引用模块,创建一个新的视图并添加一个实体引用显示:

在此处输入图片说明

然后在字段中添加内容标题和目录,单击目录,然后选中从显示中排除,保存并单击标题,然后将标题输出重写为 [title] - ([nid])

在此处输入图片说明 在此处输入图片说明

转到编辑格式设置并检查标题,这将允许您按标题搜索。

在此处输入图片说明

保存视图。

转到编辑您的“实体引用”字段,然后在“模式视图”中选择:....(如下图所示),然后选择您的视图(在本例中,名称为:articles_with_id)并保存设置:

在此处输入图片说明

然后去看看结果:

在此处输入图片说明

编辑:这现在在Drupal 8,至少在版本8.3.4中工作。


2
天哪,我一直想知道视图选项的用途是什么。这是肮脏的!
No Sssweat

1
@NoSssweat我正在学习英语,能给我一个肮脏的同义词吗?我听不懂“这是肮脏的”一词
Adrian Cid Almaguer

3
不,这意味着它是一个非常好的/令人印象深刻的解决方案。例如:亚历山大莫名其妙的肮脏的点球大战进球
没有Sssweat

1
@AdrianCidAlmaguer我同意这个解决方案是“病”!(成语)
约翰·R

2
该解决方案的唯一问题是,一旦选中了实体引用字段,该实体编辑表单就会在实体编辑表单中显示两次ID,因为默认情况下,一旦选中该ID,它就会被包括在内。
尤里(Yuri)

5

使用默认配置创建实体引用字段

在此处输入图片说明

函数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_idID可用。您可以执行我在该行中所做的(由所示**),只需编写:

 $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或内容类型。

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.