Automatically provide options to a list field type with Drupal 8

punches

Drupal 8 has a multitude of field types to cover a large number of use cases and situations when it comes to structuring and modeling content. Among these, we have a List field type which, as its name suggests, allows us to configure an input field based on a list of predefined options. This list of options must be set manually in the field's storage options at the time of creation.

But we can also use this field based on a list of options that can be provided dynamically. Let's look at how we need to proceed to have a field that allows us to choose from a list of dynamic options.

For the example, we will create a list field that will provide us with a list of all content types available on a Drupal 8 project. The creation of such a field will take place in 4 steps.

  1. Creating the field with an empty list of options
  2. Export of the field configuration
  3. Modification of the field configuration by associating a function to it to provide the list of options
  4. Importing the new field configuration

Creating the List field

Creating such a field is quite simple. Let's add a field called Content type (machine name field_content_type) on a paragraph type for example.

add field list type

Et laissons les options de champs vide.

Field list settings empty

Exporting the field configuration

We can export the configuration of the new field, with the drush cex command, or with the Features module, or using the configuration export interface available natively with Drupal Core.

We get this configuration for our new field

langcode: fr
status: true
dependencies:
  module:
    - options
    - paragraphs
id: paragraph.field_content_type
field_name: field_content_type
entity_type: paragraph
type: list_string
settings:
  allowed_values: {  }
  allowed_values_function: ''
module: options
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

Changing the field configuration

We then edit this field configuration to associate a function on the allowed_values_function parameter. This function will be in charge of providing a dynamic list of possible options, namely the different types of content present on the project.

Our configuration then becomes

langcode: fr
status: true
dependencies:
  module:
    - options
    - paragraphs
id: paragraph.field_content_type
field_name: field_content_type
entity_type: paragraph
type: list_string
settings:
  allowed_values: {  }
  allowed_values_function: my_module_allowed_values_bundle
module: options
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

 

Of course, we must now create this function in the my_module module.

/**
 * Set dynamic allowed values for the bundle field.
 *
 * @param \Drupal\field\Entity\FieldStorageConfig $definition
 *   The field definition.
 * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity
 *   The entity being created if applicable.
 * @param bool $cacheable
 *   Boolean indicating if the results are cacheable.
 *
 * @return array
 *   An array of possible key and value options.
 *
 * @see options_allowed_values()
 */
function my_module_allowed_values_bundle(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
  $entity_type_id = 'node';
  $options = [];
  /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entityBundleInfo */
  $entityTypeBundleInfo = \Drupal::service('entity_type.bundle.info');
  $entity_type_bundles = $entityTypeBundleInfo->getBundleInfo($entity_type_id);

  foreach ($entity_type_bundles as $key => $entity_type_bundle) {
    $options[$key] = $entity_type_bundle['label'];
  }
  return $options;
}

Importing the new field configuration

We can then import this new configuration using the drush cim command, or using the Features module or from the configuration import interface, depending on your project, whether it is a simple site or a Drupal 8 web factory.

And the trick is done. Now the configuration of the field indicates that the list of options is provided dynamically.

Liste des types de contenu

And you can now offer a selection from the different content types on the site. This type of implementation is particularly effective when it comes to making components, whatever they are, which can then be used on any type of project, from a simple site, to a complex site or a Drupal 8 web factory.

 

Commentaires

But this is not the same behavior. Field type list provide options that aren't content but config. And this is a behavior that the options couldn't be deleted. You can need this. Especially if you need a select list of all the content type available on the project, as in the example above. Or any list of options that shouldn't be updated / deleted. A fixed list of options and a taxonomy list options are complementary.

Soumis par DigitalCoder (non vérifié) le 08/12/2020 à 16:35 - Permalien

Hi !
Imagine the entity_type_bundle for "Actualité" is no removed and You add 2 new ?

when you launch 'drush cim' will you have these message ? or will it work ?
" The import failed due to the following reasons:
Unexpected error during operation with operation update for field.storage.node.field_xxx: A list field 'field_xxx' with existing data cannot have
its keys changed.

Thx
(from France)

Ajouter un commentaire