Imaginez que vous avez deux champs : "Prénom" et "Nom", et que vous souhaitez calculer le nom complet à partir des valeurs de ces champs.
Comment y parvenir sans créer un nouveau champ et utiliser hook_update_N pour le remplir dans les anciens contenus ?
La solution : créer un champ calculé Comme son nom l’indique, un champ calculé est un champ dont la valeur est générée à partir des données d’autres champs, mais n'est pas stockée dans la base de données.
Pour créer un champ calculé, suivez ces étapes :
- Créez une classe pour le champ calculé. Cette classe doit être située dans [MODULE_NAME]/src/Plugin/Field/FieldType/FullNameComputedField.php
<?php
namespace Drupal\[MODULE_NAME]\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
/**
* Full name computed field class.
*/
class FullNameComputedField extends FieldItemList {
use ComputedItemListTrait;
/**
* Computes the values for an item list.
*/
protected function computeValue() {
$fullName = '';
$entity = $this->getEntity();
if (
$entity->hasField('field_first_name')
&& !$entity->get('field_first_name')->isEmpty()
) {
$fullName .= $entity->get('field_first_name')?->value;
}
if (
$entity->hasField('field_last_name')
&& !$entity->get('field_last_name')->isEmpty()
) {
$fullName .= $entity->get('field_last_name')?->value . ' ';
}
// Computed full name.
/** @var \Drupal\Core\Field\FieldItemInterface $item */
$item = $this->createItem(0, $fullName);
$this->list[0] = $item;
}
}
Maintenant que nous avons créé notre classe, l’étape suivante consiste à ajouter notre nouveau champ à notre contenu Person Pour ce faire, nous devons implémenter le hook_entity_bundle_field_info.
dans votre fichier [MODULE_NAME].module ajouter le code suivant :
<?php
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\[MODULE_NAME]\Plugin\Field\FieldType\FullNameComputedField;
/**
* Implements hook_entity_bundle_field_info().
*/
function hello_world_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
if ($entity_type->id() == 'node' && $bundle == 'person') {
$fields = [];
// Add a property only to nodes of the 'person' bundle.
$fields['full_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Full name'))
->setDescription(t('Full name field'))
// Mark this field as computed.
->setComputed(TRUE)
// Mark your field as read only since it's computed we will never populate it.
->setReadOnly(TRUE)
// Set our class as field class.
->setClass(FullNameComputedField::class)
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE)
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'string',
'weight' => 0,
]);
return $fields;
}
}[MODULE_NAME] avec le nom réel de votre module. Ce code vérifie si le type d'entité est "node" et si le bundle est "person" avant de définir et de créer le champ calculé pour le nom complet.
C'est tout ! Il vous suffit de vider le cache, d’accéder à la gestion des champs de votre type de contenu, et vous verrez votre nouveau champ. Vous pouvez le personnaliser, le masquer ou l’utiliser comme n’importe quel autre champ.