Entity baseFieldDefinitions fields examples in Drupal 8
Let's take a look at a method baseFieldDefinitions and its abilities today.
Base fields are non-configurable fields that always exist on a given entity type, like the node title or created and changed dates. By definition, base fields are fields that exist for every bundle.
Entity types define their base fields in a static method baseFieldDefinitions on the entity class. The definitions returned by this function can be overridden for all bundles by hook_entity_base_field_info_alter() or overridden on a per-bundle basis via base_field_override configuration entities.
For a demonstration of baseFieldDefinitions capabilities, we need to create a new module with a custom entity. For this, I will use the Drupal console.
Create a module:
drupal generate:module
// Welcome to the Drupal module generator
Enter the new module name:
> Demo Entity
Enter the module machine name [demo_entity]:
> demo_entity
Enter the module Path [/modules/custom]:
> /modules/custom
Enter module description [My Awesome Module]:
> Module for baseFieldDefinitions examples
Enter package name [Custom]:
> Custom
Enter Drupal Core version [8.x]:
> 8.x
Do you want to generate a .module file (yes/no) [yes]:
> no
Define module as feature (yes/no) [no]:
> no
Do you want to add a composer.json file to your module (yes/no) [yes]:
> no
Would you like to add module dependencies (yes/no) [no]:
> no
Do you want to generate a unit test class (yes/no) [yes]:
> no
Do you want to generate a themeable template (yes/no) [yes]:
> no
Do you confirm generation? (yes/no) [yes]:
> yes
Generated or updated files
1 - /var/www/drupalvm/drupal/web/modules/custom/demo_entity/demo_entity.info.yml
Create a content entity in the new module:
drupal generate:entity:content
// Welcome to the Drupal Content Entity generator
Enter the module name [admin_toolbar]:
> demo_entity
Enter the class of your new content entity [DefaultEntity]:
> DemoEntity
Enter the machine name of your new content entity [demo_entity]:
> demo_entity
Enter the label of your new content entity [Demo entity]:
> Demo entity
Enter the base-path for the content entity routes [/admin/structure]:
> /admin/structure
Do you want this (content) entity to have bundles (yes/no) [no]:
> no
Is your entity translatable (yes/no) [yes]:
> no
Is your entity revisionable (yes/no) [yes]:
> no
Generated or updated files
1 - modules/custom/demo_entity/demo_entity.permissions.yml
2 - modules/custom/demo_entity/demo_entity.links.menu.yml
3 - modules/custom/demo_entity/demo_entity.links.task.yml
4 - modules/custom/demo_entity/demo_entity.links.action.yml
5 - modules/custom/demo_entity/src/DemoEntityAccessControlHandler.php
6 - modules/custom/demo_entity/src/Entity/DemoEntityInterface.php
7 - modules/custom/demo_entity/src/Entity/DemoEntity.php
8 - modules/custom/demo_entity/src/DemoEntityHtmlRouteProvider.php
9 - modules/custom/demo_entity/src/Entity/DemoEntityViewsData.php
10 - modules/custom/demo_entity/src/DemoEntityListBuilder.php
11 - modules/custom/demo_entity/src/Form/DemoEntitySettingsForm.php
12 - modules/custom/demo_entity/src/Form/DemoEntityForm.php
13 - modules/custom/demo_entity/src/Form/DemoEntityDeleteForm.php
14 - modules/custom/demo_entity/demo_entity.page.inc
15 - modules/custom/demo_entity/templates/demo_entity.html.twig
Check in the demo_entity/src/Entity/DemoEntity.php – public static function baseFieldDefinitions, Drupal console have created user_id, name, status, created and changed fields. All these fields will be inside demo_entity table in DB.
Also, parent::baseFieldDefinitions($entity_type); provides id and uuid fields.
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields['user_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The user ID of author of the Demo entity entity.'))
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
],
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of the Demo entity entity.'))
->setSettings([
'max_length' => 50,
'text_processing' => 0,
])
->setDefaultValue('')
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'string',
'weight' => -4,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -4,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Demo entity is published.'))
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the entity was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the entity was last edited.'));
return $fields;
}
Drupal core has the following field types:
- boolean
- changed
- created
- decimal
- entity_reference
- float
- integer
- language
- map
- password
- string
- string_long
- timestamp
- uri
- uuid
- comment
- datetime
- file
- image
- link
- list_float
- list_integer
- list_string
- path
- telephone
- text
- text_long
- text_with_summary
Below you can find examples with most of these types of fields.
entity_reference field
$fields['user_id'] is an example of entity_reference field.
The default widget – entity_reference_autocomplete, the default formatter – entity_reference_label. In settings, you can set the entity type for auto-complete. Also, you can set a handler (the examples of creating custom handlers you can find here).
With setDisplayOptions config, we can set options for the field widget (display context – form) and the field formatter (display context – view).
For better understanding, see another example with a node entity:
$fields['article'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Article'))
->setDescription(t('Article related to demo entity.'))
->setSetting('target_type', 'node')
->setSetting('handler', 'default:node')
->setSetting('handler_settings', [
'target_bundles' => ['article' => 'article'],
'auto_create' => FALSE,
])
->setRequired(TRUE)
->setTranslatable(FALSE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'string',
'weight' => 2,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 2,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => 'Enter here article title...',
],
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
Note that we can set target_bundles in handler_settings.
String field
$fields['name'] – is an example of a string field.
This field contains a plain string value. The default widget is string_textfield, and the default formatter – string.
string_long field
Also, we can create a string_long field that can contain a long string value. The default widget is string_textarea, the default formatter – basic_string.
$fields['notes'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Notes'))
->setDescription(t('Example of string_long field.'))
->setDefaultValue('')
->setRequired(FALSE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'basic_string',
'weight' => 5,
])
->setDisplayOptions('form', [
'type' => 'string_textarea',
'weight' => 5,
'settings' => ['rows' => 4],
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
boolean field
If an entity field contains a boolean value, the default widget is boolean_checkbox, the default formatter – boolean.
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Demo entity is published.'))
->setDefaultValue(TRUE)
->setSettings(['on_label' => 'Published', 'off_label' => 'Unpublished'])
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'boolean',
'weight' => 2,
])
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => 2,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
list_integer, list_float, list_string fields
These fields come from the options module and basically similar, so it is enough to demonstrate the use of one of them.
All these fields have options_select as the default widget and list_default as the default formatter.
$fields['http_status'] = BaseFieldDefinition::create('list_integer')
->setLabel(t('HTTP status code'))
->setDescription(t('Hypertext Transfer Protocol (HTTP) response status codes.'))
->setDefaultValue(200)
->setSettings([
'allowed_values' => [
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Moved Temporarily',
403 => 'Forbidden',
404 => 'Not Found',
],
])
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'list_default',
'weight' => 6,
])
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => 6,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
text, text_long, text_with_summary fields
These fields store a text with a text format.
As the default formatted, all of them uses text_default, for the widget – text_textfield, text_textarea and text_textarea_with_summary.
$fields['text_long'] = BaseFieldDefinition::create('text_long')
->setLabel(t('Text (formatted, long)'))
->setDescription(t('Test formatted text.'))
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'text_default',
'weight' => 6,
])
->setDisplayOptions('form', [
'type' => 'text_textarea',
'weight' => 6,
'rows' => 6,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
datetime field
$fields['start_date'] = BaseFieldDefinition::create('datetime')
->setLabel(t('Only Date'))
->setDescription(t('Date field example.'))
->setRevisionable(TRUE)
->setSettings([
'datetime_type' => 'date',
])
->setDefaultValue('')
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'datetime_default',
'settings' => [
'format_type' => 'medium',
],
'weight' => -9,
])
->setDisplayOptions('form', [
'type' => 'datetime_default',
'weight' => -9,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
The rest of the fields are pretty simple.
If you need information about the widget, formatted, or settings of these fields, try to find it in this directory – core/lib/Drupal/Core/Field/Plugin/Field/FieldType, or search in core directory files by @FieldType( keyword.
Please note, if you work with an already created entity type, you need to run a command for updating this entity. Also, this update will fail if you have any generated data in this entity.
With drush just run:
drush entity-updates -y
In hook_update_N you can apply changes with this code:
\Drupal::service('entity.definition_update_manager')->applyUpdates();
Please be aware that for Drupal 8.7.0, the support for automatic entity updates has been removed. Read more details here.
Check the important links now:
LET'S CONNECT
Get a stunning website, integrate with your tools,
measure, optimize and focus on success!