Skip to main content
ComputerMinds

Drupal 8: Creating a custom field - Part 1: Field type

I have been experimenting with the Alpha release of Drupal 8 and so I'm sharing some of my experiences so that you can avoid the pitfalls I have encountered.

Jo Fitzgerald · 2 min read

I have been experimenting with the Alpha release of Drupal 8 and so I'm sharing some of my experiences so that you can avoid the pitfalls I have encountered.

First I would like to give credit to the two articles I used during the exercise:

Hopefully this article will provide a third point-of-view to make your task easier.

a) Create the file

In D8 the location of files is very important. The field type must be located as follows:
/lib/Drupal//Plugin/field/field_type/.php
N.B. The field type name should be in CamelCase.

b) Add Contains, namespace and use

In the newly created field type file add a brief comment to explain what it consists of:
```php

/**

  • @file
  • Contains \Drupal<module_name>\Plugin\field\field_type<field_type_name>.
    */
<code>
N.B. The "Contains..." line should match the location and name of this file.

Then add the <code>namespace</code> as follows:

```php

namespace Drupal\<module_name>\Plugin\field\field_type;
</code>

N.B. It is vital that the namespace matches the location of the file otherwise it will not work.

Then add the following uses:

<code class="language-php">
use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
</code>

This provides the class that the field item will extend.

<code class="language-php">
use Drupal\field\FieldInterface;
</code>

This provides a variable type required within the field item class.

c) Add field details annotation

Annotations are an important part of Drupal 8 and must not be treated as simple comments! :o) The annotation should appear as follows:

<code class="language-php">
/**
 * Plugin implementation of the '<field_type_name>' field type.
 *
 * @FieldType(
 *   id = "<field_type_id>",
 *   label = @Translation("<field_type_label>"),
 *   description = @Translation("<field_type_description>"),
 *   default_widget = "<field_type_default_widget>",
 *   default_formatter = "<field_type_default_formatter>"
 * )
 */
</code>

N.B. All text represented by a <placeholder> should be appropriately replaced according to requirements. The default_widget and default_formatter must match the ids of a widget and a formatter (see Part 2 and Part 3 of this article).

d) Add field item class

Create the field item class as follows:

<code class="language-php">
class <field_type_name> extends ConfigFieldItemBase {

}
</code>

N.B. The <field_type_name> must match the name of this file (case-sensitive).

The class should contain the following:

i. schema()

The schema() function defines the sub-field(s) that make up the field item. Here is an example:

<code class="language-php">
  /**
   * {@inheritdoc}
   */
  public static function schema(FieldInterface $field) {
    return array(
      'columns' => array(
        'forename' => array(
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
        ),
        'surname' => array(
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
        ),
        'age' => array(
          'type' => 'int',
          'not null' => TRUE,
        ),
      ),
    );
  }
</code>

ii. isEmpty()

The isEmpty() function defines what constitutes an empty field item, e.g.

<code class="language-php">
  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->get('forename')->getValue();
    return $value === NULL || $value === '';
  }
</code>

iii. getPropertyDefinitions()

The getPropertyDefinitions() function defines the data types of the fields, e.g.

<code class="language-php">
  /**
   * {@inheritdoc}
   */
  static $propertyDefinitions;
  /**
   * {@inheritdoc}
   */
  public function getPropertyDefinitions() {
    if (!isset(static::$propertyDefinitions)) {
      static::$propertyDefinitions['forename'] = array(
        'type' => 'string',
        'label' => t('Forename'),
      );
      static::$propertyDefinitions['surname'] = array(
        'type' => 'string',
        'label' => t('Surname'),
      );
      static::$propertyDefinitions['age'] = array(
        'type' => 'integer',
        'label' => t('Age'),
      );
    }
    return static::$propertyDefinitions;
  }
</code>

Here is a simple example, similar to that described above.

Click Part 2: Field widget to continue creating a custom field.

File attachments

Written by

Jo Fitzgerald

Meet the team