Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
13/04/2025, by Ivan

Field types define the properties and behavior of fields. Field types are defined as plugins, so it is recommended to review the Plugin API before creating a new field type.

To create a field type in Drupal 8, you need a class with a @FieldType annotation.

Location of the field type class should be placed in MODULE_NAME/src/Plugin/Field/FieldType
Example: /modules/foo/src/Plugin/Field/FieldType/BazItem.php

Namespace of this class should be Drupal\MODULE_NAME\Plugin\Field\FieldType

<?php

namespace Drupal\MODULE_NAME\Plugin\Field\FieldType;

The annotation above the class should include a unique ID, label, and the default formatter and widget. The default formatter should match the ID used in the formatter class annotation.

/**
 * Provides a field type of baz.
 * 
 * @FieldType(
 *   id = "baz",
 *   label = @Translation("Baz field"),
 *   default_formatter = "baz_formatter",
 *   default_widget = "baz_widget",
 * )
 */

The class must implement the FieldItemInterface. It should extend FieldItemBase for a common implementation.

class BazItem extends FieldItemBase {

}

FieldItemInterface::schema() must be overridden to define how the field values are stored:

/**
 * {@inheritdoc}
 */
public static function schema(FieldStorageDefinitionInterface $field_definition) {
  return array(
    'columns' => array(
      'value' => array(
        'type' => 'text',
        'size' => 'tiny',
        'not null' => FALSE,
      ),
    ),
  );
}

This method returns an array of Schema API column specifications.

FieldItemInterface::propertyDefinitions() gives more detailed information about the field's properties:

/**
 * {@inheritdoc}
 */
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
  $properties = [];
  $properties['value'] = DataDefinition::create('string');

  return $properties;
}

The Map::isEmpty method (inherited from FieldItemBase) should be overridden to define when the field is considered empty:

/**
 * {@inheritdoc}
 */
public function isEmpty() {
  $value = $this->get('value')->getValue();
  return $value === NULL || $value === '';
}

Field Settings

Field settings allow users to customize the field. If the field includes any settings, follow these three steps:

  1. Override FieldItemBase::defaultFieldSettings() to define default values
  2. Create a configuration schema for those settings
  3. Create a form to allow users to change the settings

Step 1: Override defaultFieldSettings()

/**
 * {@inheritdoc}
 */
public static function defaultFieldSettings() {
  return [
    'size' => 'large',
  ] + parent::defaultFieldSettings();
}

Step 2: Create a configuration schema

Schema file path:

[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml

Schema for the size setting:

field.field_settings.[FIELD ID]:
  type: mapping
  label: 'FIELDNAME settings'
  mapping:
    size:
      type: string
      label: 'Size'

Step 3: Create the settings form

/**
 * {@inheritdoc}
 */
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
  $element = [];

  $element['size'] = [
    '#title' => $this->t('Size'),
    '#type' => 'select',
    '#options' => [
      'small' => $this->t('Small'),
      'medium' => $this->t('Medium'),
      'large' => $this->t('Large'),
    ],
    '#default_value' => $this->getSetting('size'),
  ];

  return $element;
}

Real Example

RgbItem from the field_example module in the Examples project:

namespace Drupal\field_example\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Plugin implementation of the 'field_example_rgb' field type.
 *
 * @FieldType(
 *   id = "field_example_rgb",
 *   label = @Translation("Example Color RGB"),
 *   module = "field_example",
 *   description = @Translation("Demonstrates a field composed of an RGB color."),
 *   default_widget = "field_example_text",
 *   default_formatter = "field_example_simple_text"
 * )
 */
class RgbItem extends FieldItemBase {

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return array(
      'columns' => array(
        'value' => array(
          'type' => 'text',
          'size' => 'tiny',
          'not null' => FALSE,
        ),
      ),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->get('value')->getValue();
    return $value === NULL || $value === '';
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')
      ->setLabel(t('Hex value'));

    return $properties;
  }

}

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.