Populate options field select values dynamically using a function

Drupal's core options module provides fields to create a select list (existing of integers, floats, or strings). From the user interface, these options seem to be static (i.e., are stored directly in configuration), but when looking at the exported configuration field.storage.<entity_type>.<field_name>.yml file there is an allowed_values_function setting. So, instead of writing an hook_form_alter(), you can add a function that will be invoked when the select list is created (hence allowing for dynamic values).

...
field_name: <field_name>
entity_type: node
type: list_string
settings:
  allowed_values: {  }
  allowed_values_function: example_allowed_values
module: options
...

The example code below illustrates how to create the options of the select list dynamically. Note that in the documentation of options_allowed_values(), the returned keys and values should be sanitized using the fieldFilterXss() function from the AllowedTagsXssTrait trait (of course only necessary when values are used that can be provided/changed by a user). Since, the options_allowed_values implementation often is placed in a .module file, we can invoke FieldFilteredMarkup::create() directly to create escaped keys and values.

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldFilteredMarkup;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Provides key-value options for a select list.
 *
 * @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 cache-able.
 *
 * @return array
 *   An array of possible key and value options.
 *
 * @see options_allowed_values()
 */
function example_allowed_values(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
  $options = [];

  // Usually, the options list is constructed using a loop.
  $options['example_key'] = FieldFilteredMarkup::create('Example description, e.g., retrieved from configuration');

  // Note: the key of the options list is stored in the database, not the value.
  return $options;
}

Don't forget to import the configuration after setting the allowed_values_function and rebuild Drupal's caches for the function to be found.

Category

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.