How to define a custom field as a BaseFieldDefinition

Created on 2 August 2025, 22 days ago

Problem/Motivation

I would like to add a custom field as a BaseFieldDefinition for a custom content entity type. How can I define a custom field as a BaseField on an entity? I can see the type should be 'custom', but I'm unsure how to add the sub-fields of the custom field.

πŸ’¬ Support request
Status

Active

Version

3.1

Component

Code

Created by

πŸ‡¨πŸ‡¦Canada jaypan Victoria, BC

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @jaypan
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    I'm not 100% sure as I havn't tried it myself but would assume you would use the setSettings() method to define the columns/field_settings as it would be in configs? https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Field%21B...

    I would probably create a regular field first and look at the field configs to see if you can make it work from that as an example. If you figure it out, feel free to create a documentation page. Also, be aware that I'm working on a 4.x version that is going to completely refactor the form settings into more of the "drupal" way of handling so the config structure is inevitable going to change.

  • πŸ‡¨πŸ‡¦Canada jaypan Victoria, BC

    I believe I have it working as follows, for a custom field with two elements:
    * String field
    * Serialized - Text (plain)

        $fields['target_types'] = BaseFieldDefinition::create('custom')
          ->setLabel(new TranslatableMarkup('Vehicle Types'))
          ->setDescription(new TranslatableMarkup('Vehicle Types'))
          ->setSetting('field_settings', [
            'brand' => [
              'type' => 'text',
              'weight' => 0,
              'check_empty' => FALSE,
              'widget_settings' => [
                'label' => 'Brand',
                'translatable' => FALSE,
                'settings' => [
                  'description' => '',
                  'description_display' => 'after',
                  'size' => 60,
                  'placeholder' => '',
                  'maxlength' => 255,
                  'prefix' => '',
                  'suffix' => '',
                  'required' => FALSE,
                ],
              ],
            ],
            'models' => [
              'type' => 'map_text',
              'weight' => 0,
              'check_empty' => FALSE,
              'widget_settings' => [
                'label' => 'Model(s)',
                'translatable' => FALSE,
                'settings' => [
                  'description' => '',
                  'description_display' => 'after',
                  'table_empty' => '',
                  'required' => FALSE,
                ],
              ],
            ],
          ])
          ->setSetting('columns', [
            'brand' => [
              'name' => 'brand',
              'type' => 'string',
              'length' => 255,
            ],
            'models' => [
              'name' => 'models',
              'type' => 'map_string',
            ],
          ])
          ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
          ->setDisplayConfigurable('view', TRUE)
          ->setDisplayConfigurable('form', TRUE)
          ->setDisplayOptions('form', [
            'type' => 'custom_flexbox',
            'region' => 'content',
            'settings' => [
              'label' => TRUE,
              'wrapper' => 'div',
              'open' => TRUE,
            ],
          ])
          ->setDisplayOptions('view', [
            'type' => 'custom_formatter',
            'label' => 'above',
            'settings' => [
              'fields' => [],
            ],
            'third_party_settings' => [],
            'region' => 'content',
          ]);
    
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Oh good! I figured that was all that was needed. It will get simpler in 4.x as the array of settings will be flattened out and easier to work with. Just be aware of that when that version rolls out.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    It would be great if you could create a documentation page with a full example.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Perfect. Thank you!

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
Production build 0.71.5 2024