5 * Field API documentation.
14 * @defgroup field_types Field Types API
16 * Defines field, widget, display formatter, and storage types.
18 * In the Field API, each field has a type, which determines what kind of data
19 * (integer, string, date, etc.) the field can hold, which settings it provides,
20 * and so on. The data type(s) accepted by a field are defined in
21 * hook_field_schema().
23 * Field types are plugins annotated with class
24 * \Drupal\Core\Field\Annotation\FieldType, and implement plugin interface
25 * \Drupal\Core\Field\FieldItemInterface. Field Type plugins are managed by the
26 * \Drupal\Core\Field\FieldTypePluginManager class. Field type classes usually
27 * extend base class \Drupal\Core\Field\FieldItemBase. Field-type plugins need
28 * to be in the namespace \Drupal\{your_module}\Plugin\Field\FieldType. See the
29 * @link plugin_api Plugin API topic @endlink for more information on how to
32 * The Field Types API also defines two kinds of pluggable handlers: widgets
33 * and formatters. @link field_widget Widgets @endlink specify how the field
34 * appears in edit forms, while @link field_formatter formatters @endlink
35 * specify how the field appears in displayed entities.
37 * See @link field Field API @endlink for information about the other parts of
42 * @see field_formatter
47 * Perform alterations on Field API field types.
50 * Array of information on field types as collected by the "field type" plugin
53 function hook_field_info_alter(&$info) {
54 // Change the default widget for fields of type 'foo'.
55 if (isset($info['foo'])) {
56 $info['foo']['default widget'] = 'mymodule_widget';
61 * Perform alterations on preconfigured field options.
63 * @param array $options
64 * Array of options as returned from
65 * \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions().
66 * @param string $field_type
67 * The field type plugin ID.
69 * @see \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions()
71 function hook_field_ui_preconfigured_options_alter(array &$options, $field_type) {
72 // If the field is not an "entity_reference"-based field, bail out.
73 /** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
74 $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
75 $class = $field_type_manager->getPluginClass($field_type);
76 if (!is_a($class, 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', TRUE)) {
80 // Set the default formatter for media in entity reference fields to be the
81 // "Rendered entity" formatter.
82 if (!empty($options['media'])) {
83 $options['media']['entity_view_display']['type'] = 'entity_reference_entity_view';
88 * Forbid a field storage update from occurring.
90 * Any module may forbid any update for any reason. For example, the
91 * field's storage module might forbid an update if it would change
92 * the storage schema while data for the field exists. A field type
93 * module might forbid an update if it would change existing data's
94 * semantics, or if there are external dependencies on field settings
95 * that cannot be updated.
97 * To forbid the update from occurring, throw a
98 * \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException.
100 * @param \Drupal\field\FieldStorageConfigInterface $field_storage
101 * The field storage as it will be post-update.
102 * @param \Drupal\field\FieldStorageConfigInterface $prior_field_storage
103 * The field storage as it is pre-update.
107 function hook_field_storage_config_update_forbid(\Drupal\field\FieldStorageConfigInterface $field_storage, \Drupal\field\FieldStorageConfigInterface $prior_field_storage) {
108 if ($field_storage->module == 'options' && $field_storage->hasData()) {
109 // Forbid any update that removes allowed values with actual data.
110 $allowed_values = $field_storage->getSetting('allowed_values');
111 $prior_allowed_values = $prior_field_storage->getSetting('allowed_values');
112 $lost_keys = array_keys(array_diff_key($prior_allowed_values, $allowed_values));
113 if (_options_values_in_use($field_storage->getTargetEntityTypeId(), $field_storage->getName(), $lost_keys)) {
114 throw new \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', ['@field_name' => $field_storage->getName()]));
120 * @} End of "defgroup field_types".
124 * @defgroup field_widget Field Widget API
126 * Define Field API widget types.
128 * Field API widgets specify how fields are displayed in edit forms. Fields of a
129 * given @link field_types field type @endlink may be edited using more than one
130 * widget. In this case, the Field UI module allows the site builder to choose
131 * which widget to use.
133 * Widgets are Plugins managed by the
134 * \Drupal\Core\Field\WidgetPluginManager class. A widget is a plugin annotated
135 * with class \Drupal\Core\Field\Annotation\FieldWidget that implements
136 * \Drupal\Core\Field\WidgetInterface (in most cases, by
137 * subclassing \Drupal\Core\Field\WidgetBase). Widget plugins need to be in the
138 * namespace \Drupal\{your_module}\Plugin\Field\FieldWidget.
140 * Widgets are @link form_api Form API @endlink elements with additional
141 * processing capabilities. The methods of the WidgetInterface object are
142 * typically called by respective methods in the
143 * \Drupal\Core\Entity\Entity\EntityFormDisplay class.
147 * @see field_formatter
152 * Perform alterations on Field API widget types.
155 * An array of information on existing widget types, as collected by the
156 * annotation discovery mechanism.
158 function hook_field_widget_info_alter(array &$info) {
159 // Let a new field type re-use an existing widget.
160 $info['options_select']['field_types'][] = 'my_field_type';
164 * Alter forms for field widgets provided by other modules.
166 * This hook can only modify individual elements within a field widget and
167 * cannot alter the top level (parent element) for multi-value fields. In most
168 * cases, you should use hook_field_widget_multivalue_form_alter() instead and
169 * loop over the elements.
172 * The field widget form element as constructed by
173 * \Drupal\Core\Field\WidgetBaseInterface::form().
175 * The current state of the form.
177 * An associative array containing the following key-value pairs:
178 * - form: The form structure to which widgets are being attached. This may be
179 * a full form structure, or a sub-element of a larger form.
180 * - widget: The widget plugin instance.
181 * - items: The field values, as a
182 * \Drupal\Core\Field\FieldItemListInterface object.
183 * - delta: The order of this item in the array of subelements (0, 1, 2, etc).
184 * - default: A boolean indicating whether the form is being shown as a dummy
185 * form to set default values.
187 * @see \Drupal\Core\Field\WidgetBaseInterface::form()
188 * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
189 * @see hook_field_widget_WIDGET_TYPE_form_alter()
190 * @see hook_field_widget_multivalue_form_alter()
192 function hook_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
193 // Add a css class to widget form elements for all fields of type mytype.
194 $field_definition = $context['items']->getFieldDefinition();
195 if ($field_definition->getType() == 'mytype') {
196 // Be sure not to overwrite existing attributes.
197 $element['#attributes']['class'][] = 'myclass';
202 * Alter widget forms for a specific widget provided by another module.
204 * Modules can implement hook_field_widget_WIDGET_TYPE_form_alter() to modify a
205 * specific widget form, rather than using hook_field_widget_form_alter() and
206 * checking the widget type.
208 * This hook can only modify individual elements within a field widget and
209 * cannot alter the top level (parent element) for multi-value fields. In most
210 * cases, you should use hook_field_widget_multivalue_WIDGET_TYPE_form_alter()
211 * instead and loop over the elements.
214 * The field widget form element as constructed by
215 * \Drupal\Core\Field\WidgetBaseInterface::form().
217 * The current state of the form.
219 * An associative array. See hook_field_widget_form_alter() for the structure
220 * and content of the array.
222 * @see \Drupal\Core\Field\WidgetBaseInterface::form()
223 * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
224 * @see hook_field_widget_form_alter()
225 * @see hook_field_widget_multivalue_WIDGET_TYPE_form_alter()
227 function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
228 // Code here will only act on widgets of type WIDGET_TYPE. For example,
229 // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
230 // widgets of type 'mymodule_autocomplete'.
231 $element['#autocomplete_route_name'] = 'mymodule.autocomplete_route';
235 * Alter forms for multi-value field widgets provided by other modules.
237 * To alter the individual elements within the widget, loop over
238 * \Drupal\Core\Render\Element::children($elements).
240 * @param array $elements
241 * The field widget form elements as constructed by
242 * \Drupal\Core\Field\WidgetBase::formMultipleElements().
243 * @param \Drupal\Core\Form\FormStateInterface $form_state
244 * The current state of the form.
245 * @param array $context
246 * An associative array containing the following key-value pairs:
247 * - form: The form structure to which widgets are being attached. This may be
248 * a full form structure, or a sub-element of a larger form.
249 * - widget: The widget plugin instance.
250 * - items: The field values, as a
251 * \Drupal\Core\Field\FieldItemListInterface object.
252 * - default: A boolean indicating whether the form is being shown as a dummy
253 * form to set default values.
255 * @see \Drupal\Core\Field\WidgetBaseInterface::form()
256 * @see \Drupal\Core\Field\WidgetBase::formMultipleElements()
257 * @see hook_field_widget_multivalue_WIDGET_TYPE_form_alter()
259 function hook_field_widget_multivalue_form_alter(array &$elements, \Drupal\Core\Form\FormStateInterface $form_state, array $context) {
260 // Add a css class to widget form elements for all fields of type mytype.
261 $field_definition = $context['items']->getFieldDefinition();
262 if ($field_definition->getType() == 'mytype') {
263 // Be sure not to overwrite existing attributes.
264 $elements['#attributes']['class'][] = 'myclass';
269 * Alter multi-value widget forms for a widget provided by another module.
271 * Modules can implement hook_field_widget_multivalue_WIDGET_TYPE_form_alter() to
272 * modify a specific widget form, rather than using
273 * hook_field_widget_form_alter() and checking the widget type.
275 * To alter the individual elements within the widget, loop over
276 * \Drupal\Core\Render\Element::children($elements).
278 * @param array $elements
279 * The field widget form elements as constructed by
280 * \Drupal\Core\Field\WidgetBase::formMultipleElements().
281 * @param \Drupal\Core\Form\FormStateInterface $form_state
282 * The current state of the form.
283 * @param array $context
284 * An associative array. See hook_field_widget_multivalue_form_alter() for
285 * the structure and content of the array.
287 * @see \Drupal\Core\Field\WidgetBaseInterface::form()
288 * @see \Drupal\Core\Field\WidgetBase::formMultipleElements()
289 * @see hook_field_widget_multivalue_form_alter()
291 function hook_field_widget_multivalue_WIDGET_TYPE_form_alter(array &$elements, \Drupal\Core\Form\FormStateInterface $form_state, array $context) {
292 // Code here will only act on widgets of type WIDGET_TYPE. For example,
293 // hook_field_widget_multivalue_mymodule_autocomplete_form_alter() will only
294 // act on widgets of type 'mymodule_autocomplete'.
295 // Change the autocomplete route for each autocomplete element within the
296 // multivalue widget.
297 foreach (Element::children($elements) as $delta => $element) {
298 $elements[$delta]['#autocomplete_route_name'] = 'mymodule.autocomplete_route';
303 * @} End of "defgroup field_widget".
308 * @defgroup field_formatter Field Formatter API
310 * Define Field API formatter types.
312 * Field API formatters specify how fields are displayed when the entity to
313 * which the field is attached is displayed. Fields of a given
314 * @link field_types field type @endlink may be displayed using more than one
315 * formatter. In this case, the Field UI module allows the site builder to
316 * choose which formatter to use.
318 * Formatters are Plugins managed by the
319 * \Drupal\Core\Field\FormatterPluginManager class. A formatter is a plugin
320 * annotated with class \Drupal\Core\Field\Annotation\FieldFormatter that
321 * implements \Drupal\Core\Field\FormatterInterface (in most cases, by
322 * subclassing \Drupal\Core\Field\FormatterBase). Formatter plugins need to be
323 * in the namespace \Drupal\{your_module}\Plugin\Field\FieldFormatter.
332 * Perform alterations on Field API formatter types.
335 * An array of information on existing formatter types, as collected by the
336 * annotation discovery mechanism.
338 function hook_field_formatter_info_alter(array &$info) {
339 // Let a new field type re-use an existing formatter.
340 $info['text_default']['field_types'][] = 'my_field_type';
344 * @} End of "defgroup field_formatter".
348 * Returns the maximum weight for the entity components handled by the module.
350 * Field API takes care of fields and 'extra_fields'. This hook is intended for
351 * third-party modules adding other entity components (e.g. field_group).
353 * @param string $entity_type
354 * The type of entity; e.g. 'node' or 'user'.
355 * @param string $bundle
357 * @param string $context
358 * The context for which the maximum weight is requested. Either 'form' or
360 * @param string $context_mode
361 * The view or form mode name.
364 * The maximum weight of the entity's components, or NULL if no components
367 * @ingroup field_info
369 function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mode) {
372 foreach (my_module_entity_additions($entity_type, $bundle, $context, $context_mode) as $addition) {
373 $weights[] = $addition['weight'];
376 return $weights ? max($weights) : NULL;
380 * @addtogroup field_purge
385 * Acts when a field storage definition is being purged.
387 * In field_purge_field_storage(), after the storage definition has been removed
388 * from the system, the entity storage has purged stored field data, and the
389 * field definitions cache has been cleared, this hook is invoked on all modules
390 * to allow them to respond to the field storage being purged.
392 * @param $field_storage \Drupal\field\Entity\FieldStorageConfig
393 * The field storage being purged.
395 function hook_field_purge_field_storage(\Drupal\field\Entity\FieldStorageConfig $field_storage) {
396 db_delete('my_module_field_storage_info')
397 ->condition('uuid', $field_storage->uuid())
402 * Acts when a field is being purged.
404 * In field_purge_field(), after the field definition has been removed
405 * from the system, the entity storage has purged stored field data, and the
406 * field info cache has been cleared, this hook is invoked on all modules to
407 * allow them to respond to the field being purged.
410 * The field being purged.
412 function hook_field_purge_field(\Drupal\field\Entity\FieldConfig $field) {
413 db_delete('my_module_field_info')
414 ->condition('id', $field->id())
419 * @} End of "addtogroup field_purge".
423 * @} End of "addtogroup hooks".