Revaluate the concept of 'extra fields'

Created on 27 March 2013, over 12 years ago
Updated 26 August 2025, 3 days ago

In light of the work being done on the unified Entity Field API, is Field API's concept of 'extra fields' still relevant?

I don't think I was around Drupal when this was introduced, but it seems to me that it only serves the purpose off adding 'stuff' to entity displays and forms that are *not* configurable fields. Given that we now have a new API for entity fields (formerly known as properties), and we want to move in a direction that allows existing field formatters and widget to be used by them, I think that a lot of special-casing code can be dropped and cleaned up.

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component

field system

Created by

πŸ‡·πŸ‡΄Romania amateescu

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    I totally agree "something" like extra fields, e.g. a field that returns a programmatically derived ("calculated") value, instead of a database value, makes a lot of sense in core and is definitely needed.

    Additionally I agree that the current very simple concept of extra fields should be expanded to OOP and using types (e.g. integer, decimal, text, ...) for representation and formatter, while the value is from code and the field itself should be defined in code.

    So to sum things up, we need something that at least solves the need for extra / pseudo fields, but there are lots of possibilities to expand and improve the concept.

  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    I totally agree "something" like extra fields, e.g. a field that returns a programmatically derived ("calculated") value, instead of a database value, makes a lot of sense in core and is definitely needed.

    Sounds like you are taking about computed fields.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @fago yes, kind of. I think the whole thing I described is around computed / extra / dynamic / pseudo fields. My proposal was a more complete out-of-the-box solution for such dynamically calculated / derived fields in core, without storage.
    Guess with computed fields you mean the contrib project β†’ , that also allows storing these values then. I think that part should be left to contrib indeed.

    TL;DR: I was talking about making such dynamic fields a first-class-citizen in core. hook_entity_extra_field_info() doesn't feel like that in contrast to other Plugin concepts. Maybe it could be summed up with sth. like: Improve Extra Fields in core and use Plugins.

    Is that a bit clearer?

  • πŸ‡©πŸ‡ͺGermany mxh Offenburg

    @anybody not sure whether you already know, but computed fields exist in core. Here is an excerpt from entity.api.php:

    function hook_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
      if ($entity_type->id() == 'node') {
        $fields = [];
        $fields['my_module_text'] = BaseFieldDefinition::create('string')
          ->setLabel(t('The text'))
          ->setDescription(t('A text property added by my_module.'))
          ->setComputed(TRUE)
          ->setClass('\Drupal\my_module\EntityComputedText');
    
        return $fields;
      }
    }
    
  • leymannx Berlin

    I like how "Improve Extra Fields in core and use Plugins" makes it a solvable task.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @mxh sorry my fault, indeed I now remember I saw that long ago, and think I also used it in a contrib project, but forgot about it. Instead, I used hook_entity_extra_field_info() a lot in such cases.

    Now I'm indeed unsure, if the Plugin idea still makes sense. Let's all think about that for a while. Thank you for the reminder and sorry I didn't remember that.

  • πŸ‡©πŸ‡ͺGermany mxh Offenburg

    Looking at some practical use cases, I don't think computed fields would be an equivalent replacement for extra fields.

    Extra fields, as elaborated already in previous comments long time ago, mostly serve UI-related things. That means in many cases you'd want to have something like a renderable array and/or Twig template involved when displaying the extra field's "value".

    On the other hand, computed fields are at the level of field definitions, which could be seen as the "data layer" maybe (it's one layer between database storage and frontend layer). I also think computed fields may be exposed automatically such as JSON API since they are "real" fields. So it may come with some surprising or even unwanted side effects when trying to use computed field instead of extra field.

    Looking at proper replacements, I currently think extra fields are some sort of relict from the past but at times still needed. They're almost impossible to be reused. But they may be still relevant if you still use classic "Manage display" without Layout Builder (or maybe in future Experience Builder) and "Manage form display". For example, I often have to define them when rendering further markup sections within an content entity form in-between other fields.

    When using Layout Builder, I'd prefer creating blocks instead of extra fields. They can already be implemented as full plugins and reused at other places if needed. Blocks are the most close equivalent that come to my mind right now. I had SDC in my mind as well but these are a bit lower level than block plugins (you could still write a block plugin on top of a SDC if you want though). Once Experience Builder is available, it might also come with yet another concept.

  • πŸ‡ΊπŸ‡ΈUnited States mortona2k Seattle

    I've been using UI Patterns, which lets you assign entity values to SDC props/slots. That could be used in multiple ways on a site, so having the value attached to an entity instead of calculated in a block would be helpful.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Adding a related issue.

    With manage display vs. layout builder vs. XB/canvas, there is already the issue that the 'Submitted by' information isn't controlled by managed display, and it's also not a single field that can have a formatter. So while it's not an 'extra field' (yet) it's an obvious case in core where we need something that's is a composite of two different fields rendered as one unit.

  • πŸ‡©πŸ‡ͺGermany mxh Offenburg

    After some more thoughts I guess the concept of an extra field itself is still valid, even when looking at all other concepts we have now. A plugin-based approach as suggested by @anybody, maybe covering methods for optional configuration and rendering could be straightforward.

    Splitting the concept up into "view" and "form" plugins might be worth it, this could make implementations get aligned to single responsibility and core may already prepare as much as it can for rendering at the place where it got placed into.

    Maybe something like this:

    #[ExtraViewField(id: 'my_extra_field', entity_type: 'node')]
    class MyExtraViewField implements ExtraViewFieldInterface {
    
      public function buildConfigurationForm(...);
    
      public function viewElement(array &$element, array &$build): void {
        // $element has #weight already set and is already attached to $build['my_extra_field']
       $element += ['#type' => 'details' ...];
      }
    
    }
    
    #[ExtraFormField(id: 'my_extra_field', entity_type: 'node')]
    class MyExtraFormField implements ExtraFormFieldInterface {
    
      public function buildConfigurationForm(...);
    
      public function formElement(array &$element, array &$form, FormStateInterface $form_state): void {
        // $element has #weight already set and is already attached to $build['my_extra_field']
       $element += ['#type' => 'details' ...];
      }
    
    }
    
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @mxh nice draft! Maybe we should put that into a separate issue then?

    Some additional thoughts on the draft:
    1. entity_type(s) parameter:
    #[ExtraViewField(id: 'my_extra_field', entity_type: 'node')]
    Would it make sense to allow more than one entity type:
    #[ExtraViewField(id: 'my_extra_field', entity_types: ['node', 'user'])]

    Or even leave out that parameter to have it on all existing entities automatically?
    #[ExtraViewField(id: 'my_extra_field')]

    2. Optional display parameter:
    #[ExtraViewField(id: 'my_extra_field', entity_type: 'node', displays: ['teaser'])]

    3. Configure field ui visibility:
    Hide the field entirely in the field ui sorting, only make it available programmatically
    #[ExtraViewField(id: 'my_extra_field', ..., visible: FALSE]

    4. Set "disabled" by default (maybe this should be assumed):
    #[ExtraViewField(id: 'my_extra_field', ..., disabled: true]
    πŸ› Show extra fields (hook_entity_extra_field_info) only in "Default" display mode by default Active
    or
    #[ExtraViewField(id: 'my_extra_field', ..., region: 'disabled']
    So that the field in region "disabled" by default.

    Just some ideas to discuss, which I had in the past regarding extra fields... Maybe some of them could alternatively better be methods of the interface?

    Another option would be to annotate functions, not classes, like OOP hooks do β†’ ...?! Or maybe better not...
    When using a class, the benefit might be to combine the form display, view display and eventually some kind of data handling in one class?!

  • πŸ‡¬πŸ‡§United Kingdom catch

    Yeah #53 is pretty encouraging and exporting in a new issue sounds good. Moving this one to a plan.

  • πŸ‡©πŸ‡ͺGermany mxh Offenburg

    Answering #54:

    Yes of course, the attribute constructor arguments may be defined in the ways we see to make most sense, including support of multiple entity types, default visibility settings etc.

    Another option would be to annotate functions, not classes, like OOP hooks do...?! Or maybe better not...

    OOP hooks make sense to be defined on methods since they address single invokable functions. Extra fields on the other hand may involve more things besides the main rendering / widget logic. One thing that may be often used is building the configuration form. Having all of that resided in one class that belongs to the extra field's functionality would be great. So using a class-level attribute seems suitable.

    When using a class, the benefit might be to combine the form display, view display and eventually some kind of data handling in one class?!

    This might still be possible if an extra field plugin could live or be discoverable within the same (parent?) directory. Then something like this may be possible:

    #[ExtraViewField(id: 'my_extra_field', entity_type: 'node')]
    #[ExtraFormField(id: 'my_extra_field', entity_type: 'node')]
    class MyExtraField implements PluginFormInterface, ExtraViewFieldInterface, ExtraFormFieldInterface {
    
      public function buildConfigurationForm(...);
    
      public function formElement(array &$element, array &$form, FormStateInterface $form_state): void {
        // $element has #weight already set and is already attached to $build['my_extra_field']
       $element += ['#type' => 'details' ...];
      }
    
      public function viewElement(array &$element, array &$build): void {
        // $element has #weight already set and is already attached to $build['my_extra_field']
        $element += ['#type' => 'details' ...];
      }
    
    }
    

    However such implementation would be using the same buildConfigurationForm(...) for both view and form, not sure whether that might be a bad thing.

    Anyway we may continue elaborating all this maybe in a separate issue as suggested by catch.

  • πŸ‡ͺπŸ‡ΈSpain pcambra Asturies

    Just chiming in to point to https://www.drupal.org/project/extra_field β†’ and https://www.drupal.org/project/extra_field_plus β†’ which might be useful in this context? happy to open a branch and give access if it's of any kind of use

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Thanks @pcambra, same here!

    With https://www.drupal.org/project/extra_field_plus β†’ you add another important point for using a class:
    Allow to add settings for extra fields (e.g. widget / display settings). Guess that should be handled by (inherited) methods.

    As @mxh wrote in #50 we should elaborate, where extra fields are placed and how they may interact with widgets and formatters. Maybe that also solves the settings partially. I agree extra fields might be a (yet missing) intermediate layer between the storage and the formatters / widgets.

Production build 0.71.5 2024