4

In Drupal 8 there are two types of fields: "base fields" like node.uid, and user-defined fields like 'node.body'.

All of the field names for one entity type can be found with EntityFieldManagerInterface->getFieldMap(). However this only contains the field type (as string) and a list of bundles.

For the base fields like 'uid', there is EntityFieldManagerInterface->getbaseFieldDefinitions($entity_type_id). But this omits the user-defined fields.

For user-defined fields, there is EntityTypeManagerInterface->getStorage('field_storage_config')->load($entity_type_id . $field_name);. But this does not include base fields like 'node.uid'.

There is also EntityFieldManagerInterface->getFieldDefinitions($entity_type_id, $bundle_name). But this has to be called per bundle.

There is more in FieldTypePluginmanager, EntityAdapter, and EntityDataDefinition. The more I look, the more confusing and complex this entire architecture looks to me..

Background

I would like to show a select element where a user can choose a field. Entity type is given, but bundle is not. Options are filtered by various criteria. E.g. maybe I want to show all fields where the item type extends EntityReferenceItem, and the reference target type is 'node'. For this I need to inspect the definition of each field.

All of this is for D8 version of https://drupal.org/project/renderkit.

4

The more I look, the more confusing and complex this entire architecture looks to me.

The architecture is actually very similar to 7.x, just renamed. 7.x had fields and field instances, 8.x has field storages (= 7.x fields) and fields. Base fields are exposed as both by default, while configurable fields have a separate entity type for each.

Field storages exist per entity type and fields per entity_type/bundle. (in 7.x, fields were global, otherwise it is the same).

To get all field storages of an entity type, you can use \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions(). Note that a field storage has no label, only the field (and the label can be different per bundle), so you will need to consider all bundles anyway if you don't want to just show a machine name. token and views have helper functions for that, e.g. _token_field_label().

Another useful reference is how the entity selection plugin build the list of fields to sort by: \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection::buildConfigurationForm()

  • My plan is to build a combined label from different bundles. – donquixote Aug 14 '17 at 15:17
  • Interesting, I just found that BaseFieldDefinition has no reference to FieldStorageDefinition, instead all the values are copied on BaseFieldDefinition::createFromFieldStorageDefinition(). This somehow dilutes the architectural separation. – donquixote Aug 14 '17 at 15:30
  • 2
    BaseFieldDefinition implements FieldStorageDefinitionInterface – Eyal Aug 14 '17 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.