Al diseñar nuestros tipos de contenido, uno de los campos a tener en cuenta para la selección única o múltiple de valores dinámicos no relacionados con ninguna entidad es la lista de cadenas, o List (String).
Por defecto, este campo está definido para que declares los valores permitidos en un área de texto añadiendo pares "clave"|"valor". Pero ¿Y si queremos trabajar con una lista dinámica de valores permitidos? Ya sean datos del propio Drupal o datos que nos traemos de otro sistema vía consulta a una API.
Para resolver esto haremos uso de la función callback_allowed_values_function que nos proporciona Drupal.
Vamos a ver un ejemplo en el que para un tipo de contenido Post tenemos un campo Tags en el que los elementos los cargamos mediante una petición GET a una API.
Nos creamos un módulo para la ocasión, por ejemplo el módulo blog_fixes. En el archivo blog_fixes.module tenemos que hacer uso del hook_form_alter para habilitar la propiedad allowed_values_function en nuestro campo, como podéis ver en el siguiente fragmento de código:
function blog_fixes_form_alter(&$form, &$form_state, $form_id){ if($form_id == 'node_post_form' || $form_id == 'node_post_edit_form'){ $field = FieldStorageConfig::loadByName('node','field_post_tags'); $field->setSetting('allowed_values_function', 'blog_fixes_allowed_values_function'); $field->save(); } }
Una vez tenemos "activada" la opción de carga de valores mediante una función, tenemos que definirla y cargar los valores:
function blog_fixes_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable){ if($definition->get('id') == 'node.field_post_tags'){ try { $client = \Drupal::service('http_client'); $tags = $client->get('https://sistema.biz/api/v1/tags')->result; $options = []; foreach($tags for $key->$value){ $options[$key]=$value; } return $options; } catch (\Throwable $th) { \Drupal::logger('blog_fixes')->error($th->getMessage()); } } }
Con esto ya tendremos nuestro selector de Tags proporcionadas por un sistema externo a Drupal.