Field Formatter only shows latest revision

Created on 9 March 2024, 7 months ago
Updated 18 June 2024, 3 months ago

Problem/Motivation

We need to create a view of revisions, it's not with the base of "node_revision", but similar. In this case the field formatter is a paragraphs field, and the parent entity is a node.

I need the view to show a node revision, and then the paragraph revision that is associated with that node revision. The field formatter display only displays the latest revision, regardless of the parent entity.

Steps to reproduce

Proposed resolution

This looks to be caused by the prepareView method. The class Drupal\field_formatter\Plugin\Field\FieldFormatter\FieldFormatterBase extends class Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase. The prepareView function in that class reloads the entities completely for static caching.

The method in Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsFormatterBase::prepareView, for example, overrides this explicitly to not reload anything.

I suppose there are two ways to address this, one would be to extend the EntityReferenceRevisionsFormatterBase class instead of FieldReferenceFormatterBase directly. Since there are two formatters in this module though, that would involve creating a FieldFormatterBase and then a FieldFormatterBase (for revisions), and then creating two different formatters for both of the two types of fields.

I added a patch that instead just checks for the current field type, and either calls the parent class to reload entities and cache, or, do what the EntityReferenceRevisionsFormatterBase::prepareView does. (the code is just copied over)

Remaining tasks

QA & Tests

🐛 Bug report
Status

Needs work

Version

3.0

Component

Code

Created by

🇺🇸United States asherry

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

  • Issue created by @asherry
  • 🇺🇸United States asherry
  • 🇺🇸United States asherry
  • Status changed to Needs review 7 months ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 8
    last update 7 months ago
    10 pass
  • 🇺🇸United States asherry
  • 🇮🇳India Vivek Panicker Kolkata

    Seems like a CORE issue.
    Trying to fix in https://www.drupal.org/project/drupal/issues/3442267 🐛 Entity Reference Revision not loaded in EntityReferenceFormatterBase Active .

  • 🇺🇸United States asherry

    I'm not sure I agree that it's a core issue, particularly regarding EntityReferenceFormatterBase. This class is very generic. It's meant as a basis for all entity references including entities that are not revisionable as well is config entities. In order to "load a revision" you would have to actually check if the entity is revisionable, which is well outside the scope of that class and would add complication for extending classes.

  • 🇮🇳India Vivek Panicker Kolkata

    I have done all that you've mentioned.

    > It's meant as a basis for all entity references including entities that are not revisionable as well is config entities.
    This point I can understand.
    Anyways I have raised an MR.
    Let's see what the core maintainers have to say about this.

  • Status changed to Needs work 4 months ago
  • 🇩🇪Germany Anybody Porta Westfalica

    @asherry could you please provide this as MR and add tests to ensure it works as expected, with and without revisioning enabled?

    The current implementation also means that a parent prepareView() is never called, if not one of these two if clauses match!

    So instead of:

    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function prepareView(array $entities_items) {
    +    $field_type = $this->fieldDefinition->getType();
    +    if ($field_type === 'entity_reference') {
    +      parent::prepareView($entities_items);
    +    }
    +    if ($field_type === 'entity_reference_revisions') {
    +      // See \Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsFormatterBase::prepareView()
    +      foreach ($entities_items as $items) {
    +        foreach ($items as $item) {
    +          if ($item->entity) {
    +            $item->_loaded = TRUE;
    +          }
    +        }
    +      }
    +    }
    +  }
    

    shouldn't it be something like this:

    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function prepareView(array $entities_items) {
    +    $field_type = $this->fieldDefinition->getType();
    +    if ($field_type === 'entity_reference_revisions') {
    +      // See \Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsFormatterBase::prepareView()
    +      foreach ($entities_items as $items) {
    +        foreach ($items as $item) {
    +          if ($item->entity) {
    +            $item->_loaded = TRUE;
    +          }
    +        }
    +      }
    +    } else {
    +        parent::prepareView($entities_items);
    +    }
    +  }
    

    to be compatible with any parent implementation?

  • 🇩🇪Germany Anybody Porta Westfalica

    Any plans to finish this @asherry and @Vivek Panicker?

Production build 0.71.5 2024