Afficher les ID de noeud ainsi que les titres dans la liste de saisie semi-automatique de référence d'entité

8

Je souhaite ajouter cette fonctionnalité au widget de saisie semi-automatique dans le champ Entityreference pour afficher l'ID du nœud à côté des titres dans la liste déroulante. La raison derrière l'idée est de différencier plusieurs nœuds avec le même titre.

Exemple:

  • Ceci est un titre (3)
  • Ceci est un titre (2)
  • Ceci est un titre (1)

Je sais que l'ID de nœud est affiché une fois la sélection effectuée, mais j'aime l'afficher dans la liste déroulante afin de choisir rapidement le bon nœud en fonction de l'ID de nœud.

neemu
la source
jetez un oeil à ce drupal.stackexchange.com/questions/82165/…
oksana-c
@ oksana-c vérifier ma réponse avec un autre moyen facile
Adrian Cid Almaguer

Réponses:

20

Installez les modules Vues et Référence d'entité , créez une nouvelle vue et ajoutez un affichage de référence d'entité:

entrez la description de l'image ici

Ensuite, ajoutez dans les champs le titre du contenu et le nid, cliquez dans le nid et cochez Exclure de l'affichage, enregistrez et cliquez dans le titre et allez réécrire la sortie du titre comme [title] - ([nid])

entrez la description de l'image ici entrez la description de l'image ici

Allez modifier les paramètres du format et vérifiez le titre, cela vous permettra de rechercher par titre.

entrez la description de l'image ici

Enregistrez la vue.

Allez à modifier votre champ de référence d'entité et sélectionnez dans les vues de mode: .... (comme l'image suivante) et sélectionnez votre vue (dans ce cas, le nom est: articles_with_id) et enregistrez les paramètres:

entrez la description de l'image ici

Allez ensuite voir le résultat:

entrez la description de l'image ici

EDIT: Cela fonctionne maintenant dans Drupal 8, au moins dans la version 8.3.4.

Adrian Cid Almaguer
la source
2
OMG, je me suis toujours demandé à quoi servait l'option vues. C'est sale !!!
Pas de Sssweat le
1
@NoSssweat J'apprends l'anglais maintenant, pouvez-vous me fournir un synonyme de sale s'il vous plaît? Je ne peux pas comprendre la phrase "c'est sale"
Adrian Cid Almaguer
3
Non, cela signifie que c'est une solution vraiment bonne / impressionnante. Ex: le but de Filthy Shootout d'Alexander Nylander
No Sssweat
1
@AdrianCidAlmaguer Je suis d'accord que cette solution est "malade"! (idiome)
John R
2
Le seul problème avec cette solution est que le champ de référence d'entité, une fois sélectionné, affiche l'ID deux fois dans le formulaire de modification d'entité, car il est inclus par défaut une fois qu'il est sélectionné.
Yuri
5

Champ Créer une référence d'entité avec la configuration par défaut

entrez la description de l'image ici

La fonction entityreference_autocomplete_callback_get_matches détermine quelle devrait être la sortie de la saisie semi-automatique.

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 dernière ligne $matches[$prefix . $key] = '<div class="reference-autocomplete">'détermine la sortie et $entity_idest disponible qui est l'ID. Vous pouvez faire ce que j'ai fait dans cette ligne (montré par **), écrivez simplement:

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

vous pouvez utiliser $entity_idpour récupérer d'autres champs et tout ce que vous voulez.

Encore une chose!

Parfois, ce n'est pas une bonne idée de changer la fonction du module de base (si cela n'est pas important pour vous, la solution ci-dessus est suffisante).

Si vous devez remplacer la fonction principale du entity_referencemodule, créez un petit module et nommez-leelabel

c'est 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

et c'est 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);
}

J'ai essayé ce code et il fonctionne parfaitement S'il existe d'autres types de références d'entité et que vous n'avez pas besoin de le faire pour elles, ajoutez simplement une IFdéclaration et vérifiez le type de bundle ou de contenu.

M ama D
la source