I have a custom field type that I create with a custom module. It is a plain text field where the user type in a string. I want to retain two copies of this field:

  1. The exact string value as typed by the user.
  2. A safe value of the same string.

This is how I create the field:

class MyItem extends FieldItemBase {

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


I assume I should generate a safevalue of the string in hook_node_presave() and somehow get into the entity there (but corrections to these assumptions are welcome).

I have no problem getting the string value as typed by the user and to compute a safe value:

$value = $entity->field_myfield->getString();
$safevalue = makeSafe($value);

But I do not know how to get the $safevalue stored in the database.


I see that this has two nearly identical answers. Both work fine if the cardinality of the field is one, so I've upvoted both. Since I cannot accept both, I've accepted the one from apaderno for the extra detail about propertyDefinitions().

I am still not able to get this to work with a multivalue field, but I think that probably need to be a separate question.

2 Answers 2


If safeValue has been defined as field property in propertyDefinitions(), it can be accessed as $entity->field_myfield->safeValue, either to read it or write it.

In Drupal core, an example of field that stores a processed copy of the field value is the TextItem class, whose propertyDefinitions() method contains the following code.

$properties['value'] = DataDefinition::create('string')
$properties['format'] = DataDefinition::create('filter_format')->setLabel(t('Text format'));
$properties['processed'] = DataDefinition::create('string')
  ->setLabel(t('Processed text'))
  ->setDescription(t('The text with the text format applied.'))
  ->setSetting('text source', 'value')

That class defines the property as computed. That's why its schema() method doesn't include that property.


For saving:

$value = $entity->field_myfield->getString();
$entity->field_myfield->safevalue = makeSafe($value);

For loading:

$safe_value = $entity->field_myfield->safevalue;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.