Change explanation
Formerly the settings for a @FieldType, @FieldFormatter or @FieldWidget plugin were part of its definition expressed through annotations. As annotations these values were alterable like the rest of the definition. Given the alterability a third party module could add new settings that would get saved and loaded along with the field, widget or formatter configuration. In D8 content_translation.module leveraged this pattern to add its 'translation_sync' field setting, applicable to all field types.
The problem was there is no way to provide config schema for these altered-in settings. For a detailed discussion see Config schema mechanisms cannot reflect alterable config trees.
A configuration schema is used to validate the form associated with changing those settings. Settings altered-in by 3rd party modules cannot be accounted for in this case.
For background see Use config schema in saving and validating configuration form to ensure data is consistent and correct.
The change announced by this notice moves plugin settings from annotations to newly-introduced methods in base classes.
Code examples
Before: Settings defined in annotation
<?php
/**
* Plugin implementation of the 'file' field type.
*
* @FieldType(
* id = "file",
* label = @Translation("File"),
* description = @Translation("This field stores the ID of a file as an integer value."),
* settings = {
* "target_type" = "file",
* "display_field" = "0",
* "display_default" = "0",
* "uri_scheme" = ""
* },
* instance_settings = {
* "file_extensions" = "txt",
* "file_directory" = "",
* "max_filesize" = "",
* "description_field" = "0"
* },
* default_widget = "file_generic",
* default_formatter = "file_default",
* list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList"
* )
*/
class FileItem extends EntityReferenceItem {
...
}
Now: Settings defined through method
<?php
/**
* Plugin implementation of the 'file' field type.
*
* @FieldType(
* id = "file",
* label = @Translation("File"),
* description = @Translation("This field stores the ID of a file as an integer value."),
* default_widget = "file_generic",
* default_formatter = "file_default",
* list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList"
* )
*/
class FileItem extends EntityReferenceItem {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return array(
'target_type' => 'file',
'display_field' => 0,
'display_default' => 0,
'uri_scheme' => file_default_scheme(),
) + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public static function defaultInstanceSettings() {
return array(
'file_extensions' => 'txt',
'file_directory' => '',
'description_field' => 0,
'uri_scheme' => file_default_scheme(),
) + parent::defaultInstanceSettings();
}
...
}
We see how these settings and instance settings correspond to the config schema for file plugins:
field.file.settings:
type: mapping
label: 'File settings'
mapping:
display_field:
type: boolean
label: 'Enable Display field'
display_default:
type: boolean
label: 'Files displayed by default'
uri_scheme:
type: string
label: 'Upload destination'
field.file.instance_settings:
type: mapping
label: 'File settings'
mapping:
file_directory:
type: string
label: 'File directory'
file_extensions:
type: string
label: 'Allowed file extensions'
max_filesize:
type: string
label: 'Maximum upload size'
description_field:
type: boolean
label: 'Enable Description field'
API changes
Added
public static /Drupal/Core/Field/FieldItemInterface::defaultSettings()
public static /Drupal/Core/Field/FieldItemInterface::defaultInstanceSettings()
public static /Drupal/Core/Field/PluginSettingsInterface::defaultSettings() (applies to widget and formatter plugins)
Removed
The settings and instance_settings properties of /Drupal/Core/Field/Annotation/FieldType
The settings property of /Drupal/Core/Field/Annotation/FieldFormatter
The settings property of /Drupal/Core/Field/Annotation/FieldWidget