Skip to main content

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

An article from ComputerMinds - Building with Drupal in the UK since 2005
28th Jan 2014

Jo Fitzgerald

Developer
Jo Fitzgerald
Hey, you seem to look at this article a lot! Why not Bookmark this article so you can find it easily in the future?

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>.
    */

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;

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

Then add the following uses:


use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;

This provides the class that the field item will extend.


use Drupal\field\FieldInterface;

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:


/**
 * 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>"
 * )
 */

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:


class <field_type_name> extends ConfigFieldItemBase {

}

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:


  /**
   * {@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,
        ),
      ),
    );
  }

ii. isEmpty()

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


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

iii. getPropertyDefinitions()

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


  /**
   * {@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;
  }

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

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

Hi, thanks for reading

ComputerMinds are the UK’s Drupal specialists with offices in Bristol and Coventry. We offer a range of Drupal services including Consultancy, Development, Training and Support. Whatever your Drupal problem, we can help.