Mostrar ID de nodo junto con títulos en la lista de autocompletado de referencia de entidad

8

Me gustaría agregar esta funcionalidad al widget de autocompletar en el campo de referencia de entidad para mostrar la ID del nodo junto a los títulos en la lista desplegable. La razón detrás de la idea es diferenciar entre múltiples nodos con el mismo título.

Ejemplo:

  • Este es un título (3)
  • Este es un título (2)
  • Este es un título (1)

Sé que la ID del nodo se muestra una vez que se realiza una selección, pero me gusta mostrarla en la lista desplegable para elegir el nodo correcto rápidamente en función de la ID del nodo.

neemu
fuente
eche un vistazo a este drupal.stackexchange.com/questions/82165/…
oksana-c
@ oksana-c comprueba mi respuesta de otra manera fácil
Adrian Cid Almaguer el

Respuestas:

20

Instale las vistas y los módulos de referencia de entidad , cree una nueva vista y agregue una pantalla de referencia de entidad:

ingrese la descripción de la imagen aquí

Luego agregue en los campos el título del contenido y el nid, haga clic en el nid y marque Excluir de la pantalla, Guardar y haga clic en el título y vaya a reescribir la salida del título como [title] - ([nid])

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Vaya a editar la configuración del formato y verifique el título, esto le permitirá buscar por título.

ingrese la descripción de la imagen aquí

Guarda la vista.

Vaya a editar su campo de Referencia de entidad y seleccione en las Vistas de modo: .... (como la siguiente imagen) y seleccione su Vista (en este caso el nombre es: articles_with_id) y guarde la configuración:

ingrese la descripción de la imagen aquí

Luego ve a ver el resultado:

ingrese la descripción de la imagen aquí

EDITAR: Esto ahora funciona en Drupal 8, al menos en la versión 8.3.4.

Adrian Cid Almaguer
fuente
2
Dios mío, siempre me pregunté para qué era la opción de vistas. Esto es asqueroso!
No Sssweat
1
@NoSssweat Estoy aprendiendo inglés ahora, ¿me puede dar un sinónimo de asqueroso por favor? No puedo entender la frase "Esto es sucio"
Adrian Cid Almaguer
3
No, significa que es una solución realmente buena / impresionante. Ej .: Golpe sucio de Alexander Nylander
No Sssweat
1
@AdrianCidAlmaguer ¡Estoy de acuerdo con que esta solución está "enferma"! (modismo)
John R
2
El único problema con esta solución es que el campo de referencia de la entidad, una vez seleccionado, muestra la ID dos veces en el formulario de edición de la entidad, porque se incluye de manera predeterminada una vez que se selecciona.
Yuri
5

Crear campo de referencia de entidad con la configuración predeterminada

ingrese la descripción de la imagen aquí

La función entityreference_autocomplete_callback_get_matches determina cuál debería ser la salida del autocompletado.

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

la última línea $matches[$prefix . $key] = '<div class="reference-autocomplete">'determina la salida y $entity_idestá disponible cuál es la ID. Puedes hacer lo que hice en esa línea (mostrada por **), simplemente escribe:

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

puede usar $entity_idpara buscar otros campos y cualquier cosa que desee.

¡Una cosa más!

Algunas veces no es una buena idea cambiar la función del módulo central (si no es importante para usted, la solución anterior es suficiente).

Si necesita anular la función principal del entity_referencemódulo, cree un módulo pequeño y asígnele un nombreelabel

es 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

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

Probé este código y funciona perfectamente. Si hay otro tipo de referencias de entidad y no necesita hacer esto por ellas, simplemente agregue una IFdeclaración y verifique el paquete o el tipo de contenido.

M ama D
fuente