logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll
20/06/2025, by Ivan

Menu

Los widgets de campo se utilizan para visualizar un campo dentro de formularios. Los widgets de campo se definen como plugins, por lo que se recomienda revisar la API de plugins antes de comenzar a crear un nuevo tipo de widget para campo.

Para crear un widget de campo en Drupal 8, necesitas una clase con la anotación FieldWidget.

La ubicación de la clase del widget debe ser /[NOMBRE_DEL_MÓDULO]/src/Plugin/Field/FieldWidget. Por ejemplo, /foo/src/Plugin/Field/FieldWidget/BarWidget.php.

El namespace de esta clase debe ser [NOMBRE_DEL_MÓDULO]\Plugin\Field\FieldWidget. Por ejemplo, \Drupal\foo\Plugin\Field\FieldWidget.

La anotación sobre la clase debe incluir un ID único, etiqueta y un arreglo de IDs de tipos de campo que el widget pueda manejar.

/**
 * Un widget bar.
 *
 * @FieldWidget(
 *   id = "bar",
 *   label = @Translation("Widget Bar"),
 *   field_types = {
 *     "baz",
 *     "string"
 *   }
 * )
 */

La clase debe implementar la interfaz WidgetInterface. Puede extender WidgetBase para la implementación común de la interfaz. El único método obligatorio a implementar es ::formElement(), que debe devolver los elementos reales del formulario que representan tu widget.

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

//...
class BarWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = [];
    // Construye el array render de elemento.
    return $element;
  }

}

Configuraciones del widget

Si tu widget necesita configuraciones adicionales, debes hacer tres pasos:

  • Sobre-escribir PluginSettingsBase::defaultSettings() para definir valores por defecto
  • Crear un esquema de configuración para esas opciones
  • Crear un formulario para permitir que usuarios modifiquen esas configuraciones

Paso 1: Sobre-escribe PluginSettingsBase::defaultSettings() para definir valores por defecto

/**
 * {@inheritdoc}
 */
 public static function defaultSettings() {
  return [
    // Crea la configuración personalizada 'size' con valor por defecto 60
    'size' => 60,
  ] + parent::defaultSettings();
}

Paso 2: Crear esquema de configuración para las opciones

El esquema se coloca en:

/[NOMBRE_DEL_MÓDULO]/config/schema/[NOMBRE_DEL_MÓDULO].schema.yml

En este archivo defines los tipos de datos de las opciones creadas en defaultSettings():

Por ejemplo, la opción 'size' es un entero, el esquema se verá así:

field.widget.settings.[ID_DEL_WIDGET]:
  type: mapping
  label: 'Configuraciones del widget WIDGET NAME'
  mapping:
    size:
      type: integer
      label: 'Tamaño'

Paso 3: Crear formulario para permitir editar configuraciones

Este formulario se crea sobre-escribiendo WidgetBase::settingsForm().

/**
 * {@inheritdoc}
 */
public function settingsForm(array $form, FormStateInterface $form_state) {
  $element['size'] = [
    '#type' => 'number',
    '#title' => $this->t('Tamaño del campo de texto'),
    '#default_value' => $this->getSetting('size'),
    '#required' => TRUE,
    '#min' => 1,
  ];

  return $element;
}

También puedes mostrar un resumen de las configuraciones elegidas para el widget así:

/**
 * {@inheritdoc}
 */
public function settingsSummary() {
  $summary = [];

  $summary[] = $this->t('Tamaño del campo de texto: @size', ['@size' => $this->getSetting('size')]);

  return $summary;
}

Puedes usar el método getSetting() para obtener la configuración en el widget:

class BarWidget extends WidgetBase implements WidgetInterface {

class BarWidget extends WidgetBase implements WidgetInterface {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element['value'] = $element + [
      '#type' => 'textfield',
      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
      '#size' => $this->getSetting('size'),
    ];

    return $element;
  }

}

Ejemplo de widget

TextWidget del módulo field_example del módulo Examples:

namespace Drupal\field_example\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implementación del plugin widget 'field_example_text'.
 *
 * @FieldWidget(
 *   id = "field_example_text",
 *   module = "field_example",
 *   label = @Translation("Valor RGB como #ffffff"),
 *   field_types = {
 *     "field_example_rgb"
 *   }
 * )
 */
class TextWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $value = isset($items[$delta]->value) ? $items[$delta]->value : '';
    $element += [
      '#type' => 'textfield',
      '#default_value' => $value,
      '#size' => 7,
      '#maxlength' => 7,
      '#element_validate' => [
        [static::class, 'validate'],
      ],
    ];
    return ['value' => $element];
  }

  /**
   * Valida el campo de texto para color.
   */
  public static function validate($element, FormStateInterface $form_state) {
    $value = $element['#value'];
    if (strlen($value) == 0) {
      $form_state->setValueForElement($element, '');
      return;
    }
    if (!preg_match('/^#([a-f0-9]{6})$/iD', strtolower($value))) {
      $form_state->setError($element, t("El color debe ser un valor hexadecimal de 6 dígitos, válido para CSS."));
    }
  }

}

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.