Drupal - How to easily alter an entity's base field definition per bundle

Bundle specific labels for base fields are stored in label of a BaseFieldOverride config entity:

Defines the base field override entity.

Allows base fields to be overridden on the bundle level.

Plugin annotation

@ConfigEntityType(
  id = "base_field_override",
  label = @Translation("Base field override"),
  handlers = {
    "storage" = "Drupal\Core\Field\BaseFieldOverrideStorage",
    "access" = "Drupal\Core\Field\BaseFieldOverrideAccessControlHandler",
  },
  config_prefix = "base_field_override",
  entity_keys = {
    "id" = "id",
    "label" = "label"
  },
  config_export = {
    "id",
    "field_name",
    "entity_type",
    "bundle",
    "label",
    "description",
    "required",
    "translatable",
    "default_value",
    "default_value_callback",
    "settings",
    "field_type",
  }
)

When you get a base field from EntityFieldManager::getFieldDefinitions($entity_type_id, $bundle), set a new label for the field and save the field definition, then this label is not stored in the entity type (which would not be possible, because this is in code and the same for all bundles), but in the mentioned base field override.


The answer of @4k4 got us on the right track. For our solution, we primarily tried altering the labels for some programmatically provided base group types.

In order to help others with a similar use case, here is how we did it:

We implemented hook_entity_bundle_field_info() within the module that provided our group entity bundle and then used BaseFieldOverride to creating the field overrides:

use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\Entity\BaseFieldOverride;

/**
 * Implements hook_entity_bundle_field_info().
 */
function ourgroupmodule_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];

  // Whether the hook implementation was called for our group type.
  if ($entity_type->id() == 'group' && $bundle == 'ourgroup' && !empty($base_field_definitions['label'])) {
    // Create a base field override with custom title.
    $field = BaseFieldOverride::createFromBaseFieldDefinition($base_field_definitions['label'], $bundle);
    $field->setLabel(t('Our group label title'));
    $fields['label'] = $field;
  }

  return $fields;
}

As further stated by @4k4, the override could be done within other places as well. E.g. in form submit handlers to override title labels of groups that are created within the admin UI.

Tags:

Entities

8