Cache tags from Computed fields do not bubble up to Entity render array

Created on 19 August 2022, almost 2 years ago
Updated 13 March 2024, 4 months ago

Problem/Motivation

I need to add custom cache tags to my custom Computed field. I do this exactly like in entity_test/src/Plugin/Field/ComputedTestCacheableStringItemList.php but the Entity View page does not get tags from the Computed field.

So I dig in and reproduce this issue with the system/tests/modules/entity_test itself, and seems that this is a bug in Drupal Core.

Steps to reproduce

1. Enable the system/tests/modules/entity_test module.
To enable it you must allow showing test modules via this line in settings.php:

$settings['extension_discovery_scan_tests'] = TRUE;

2. Extend the baseFieldDefinitions() in the entity_test/src/Entity/EntityTestComputedField.php to show the field value on Entity View page:

    $fields['computed_test_cacheable_string_field'] = BaseFieldDefinition::create('computed_test_cacheable_string_item')
      ->setLabel(new TranslatableMarkup('Computed Cacheable String Field Test'))
      ->setComputed(TRUE)
      ->setClass(ComputedTestCacheableStringItemList::class)
      ->setReadOnly(FALSE)
      ->setInternal(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'inline',
        'type' => 'string',
      ]);

3. Create a custom controller, where try to create the entity_test_computed_field entity, build a render array for it, and check the tags in it, something like this:

$entity = \Drupal::entityTypeManager()
  ->getStorage('entity_test_computed_field')
  ->create();
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('entity_test_computed_field');
$pre_render = $view_builder->view($entity);
$build = $view_builder->build($pre_render);
dump($build['#cache']['tags']);

You will see only one tag in the list:

entity_test_computed_field_view

But class ComputedTestCacheableStringItemList also adds the field:computed_test_cacheable_string_field custom tag to the field value via this code:

  protected function computeValue() {
    /** @var \Drupal\entity_test\Plugin\Field\FieldType\ComputedTestCacheableStringItem $item */
    $item = $this->createItem(0, 'computed test cacheable string field');
    $cacheability = (new CacheableMetadata())
      ->setCacheContexts(['url.query_args:computed_test_cacheable_string_field'])
      ->setCacheTags(['field:computed_test_cacheable_string_field'])
      ->setCacheMaxAge(800);
    $item->get('value')->addCacheableDependency($cacheability);
    $this->list[0] = $item;
  }

So the issue is that tag is missing in render array. But, as I understand, it should be there, right? If I check the presence of the tag from the computed field incorrectly, please point me to the right way.

Also you can render the full HTML page and check that the field:computed_test_cacheable_string_field cache tag is missing in x-drupal-cache-tags string too.

Proposed resolution

Check if a field item list implements CacheableDependencyInterface in when rendering a field in FormatterBase and, if so, bubble the cacheable metadata to the rendered output.

Remaining tasks

Update issue summary

User interface changes

NA

API changes

No API change, but (arguably) an API addition, see the change notice: https://www.drupal.org/node/3423720 β†’

Data model changes

NA

Release notes snippet

NA

πŸ› Bug report
Status

Fixed

Version

10.2 ✨

Component
CacheΒ  β†’

Last updated about 18 hours ago

Created by

πŸ‡¦πŸ‡²Armenia Murz Yerevan, Armenia

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

Merge Requests

Comments & Activities

Not all content is available!

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

Production build 0.69.0 2024