Anzeigen von Knoten-IDs zusammen mit Titeln in der Autocomplete-Liste der Entitätsreferenz

8

Ich möchte diese Funktionalität zum Widget für die automatische Vervollständigung im Feld "Entityreference" hinzufügen, um die Knoten-ID neben den Titeln in der Dropdown-Liste anzuzeigen. Der Grund für die Idee besteht darin, zwischen mehreren Knoten mit demselben Titel zu unterscheiden.

Beispiel:

  • Dies ist ein Titel (3)
  • Dies ist ein Titel (2)
  • Dies ist ein Titel (1)

Ich weiß, dass die Knoten-ID angezeigt wird, sobald eine Auswahl getroffen wurde, aber ich möchte sie in der Dropdown-Liste anzeigen, um anhand der Knoten-ID schnell den richtigen Knoten auszuwählen.

neemu
quelle
Werfen
Sie
@ oksana-c überprüfen Sie meine Antwort mit einem anderen einfachen Weg
Adrian Cid Almaguer

Antworten:

20

Installieren Sie die Module Ansichten und Entitätsreferenz , erstellen Sie eine neue Ansicht und fügen Sie eine Entitätsreferenzanzeige hinzu:

Geben Sie hier die Bildbeschreibung ein

Fügen Sie dann in den Feldern den Inhaltstitel und die NID hinzu, klicken Sie in die NID und aktivieren Sie Ausschluss von der Anzeige, Speichern und klicken Sie in den Titel und gehen Sie, um die Ausgabe des Titels als neu zu schreiben [title] - ([nid])

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Bearbeiten Sie die Einstellungen des Formats und überprüfen Sie den Titel. Auf diese Weise können Sie nach Titel suchen.

Geben Sie hier die Bildbeschreibung ein

Speichern Sie die Ansicht.

Gehen Sie zum Bearbeiten Ihres Entitätsreferenzfelds und wählen Sie in den Modusansichten: .... (wie im folgenden Bild) und wählen Sie Ihre Ansicht aus (in diesem Fall lautet der Name: articles_with_id) und speichern Sie die Einstellungen:

Geben Sie hier die Bildbeschreibung ein

Dann gehen Sie, um das Ergebnis zu sehen:

Geben Sie hier die Bildbeschreibung ein

EDIT: Dies funktioniert jetzt in Drupal 8, zumindest in der Version 8.3.4.

Adrian Cid Almaguer
quelle
2
OMG, ich habe mich immer gefragt, wozu die Ansichtsoption dient. Das ist dreckig !!!
Kein Sssweat
1
@NoSssweat Ich lerne jetzt Englisch. Kannst du mir bitte ein Synonym für schmutzig geben? Ich kann den Satz "Das ist schmutzig" nicht verstehen
Adrian Cid Almaguer
3
Nein, es bedeutet, dass es eine wirklich gute / beeindruckende Lösung ist. Beispiel: Alexander Nylanders schmutziges Shootout-Ziel
No Sssweat
1
@AdrianCidAlmaguer Ich stimme zu, dass diese Lösung "krank" ist! (Redewendung)
John R
2
Das einzige Problem bei dieser Lösung besteht darin, dass das einmal ausgewählte Entitätsreferenzfeld die ID zweimal im Entitätsbearbeitungsformular anzeigt, da sie nach der Auswahl standardmäßig enthalten ist.
Yuri
5

Feld "Entitätsreferenz erstellen" mit der Standardkonfiguration

Geben Sie hier die Bildbeschreibung ein

Die Funktion entityreference_autocomplete_callback_get_matches bestimmt, wie die Ausgabe der automatischen Vervollständigung aussehen soll.

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);
}

Die letzte Zeile $matches[$prefix . $key] = '<div class="reference-autocomplete">'bestimmt die Ausgabe und $entity_ides steht die ID zur Verfügung. Sie können das tun, was ich in dieser Zeile getan habe (gezeigt durch **), schreiben Sie einfach:

 $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .' - ('. $entity_id . ')</div>';

Sie können $entity_idandere Felder und alles, was Sie wollen, abrufen.

Eine Sache noch!

Manchmal ist es keine gute Idee, die Funktion des Kernmoduls zu ändern (wenn es Ihnen nicht wichtig ist, reicht die obige Lösung aus).

Wenn Sie die Kernfunktion des entity_referenceModuls überschreiben müssen , erstellen Sie ein kleines Modul und benennen Sie eselabel

es ist 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

und es ist 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);
}

Ich habe diesen Code ausprobiert und er funktioniert einwandfrei. Wenn es andere Arten von Entitätsreferenzen gibt und Sie dies nicht tun müssen, fügen Sie einfach eine IFAnweisung hinzu und suchen Sie nach Bundle- oder Inhaltstypen.

M ama D.
quelle