3

I have a situation where two Paragraphs on single page may potentially reference the same entity.

The affected paragraphs have a field to change their colour, and this colour value is passed down to the referenced entity (via hook_preprocess_[entity-type]) for use in its template.

  • Node

    • field_paragraph

      • Paragraph1

        • field_colour
        • field_entity_reference (references entity:1234)
      • Paragraph2

        • field_colour
        • field_entity_reference (references entity:1234)

When I update Paragraph 1 to change its colour, this is currently affecting the colour of Paragraph 2 (because the entity is cached, including the colour value that is preprocessed into it).

I have tried adding a cacheable dependency (in hook_preprocess_[entity-type]) to transfer the cache tags for the paragraph to the entity, so that when the paragraph is updated, it invalidates the cache for the entity it is referencing:

$renderer = \Drupal::service('renderer');
$renderer->addCacheableDependency($variables, $referring_entity);

I have also tried replacing $variables in the above with $variables['elements'] and $variables['content'], but either way this does not seem to work as I expected.

Any advice appreciated.

6

So the easiest option likely is to just disable caching completely for the embedded entities.

In hook_entity_view(), unset $build['cache']['keys']. They are then still cached as part of the paragraph render cache, but don't have their own cache entry anymore.

To avoid not caching them when they are shown somewhere else, you should use a special view mode when you integrate them in paragraphs and only disable caching for that.

Note that you could also set max-age = 0 but that means "this content must not be cached at all", that information would bubble up to the paragraph and host entity and none of those would be cached anymore. That's not what you want.

Or you could change your approach and apply that color through a class that is set on the paragraph level, without changing the HTML of the embedded entity. Doesn't work for everything, but for a simple color change, that is likely easier to implement.

  • Thanks berdir, that is exactly the perspective I needed. In my case this content type is only ever displayed in the referenced context, so keeping a separate cache for the entity inside the paragraph made no sense. – autopoietic Aug 9 '16 at 8:37
1

The accepted answer worked for me, but I'd like to update with another method that also worked in my case and kept the rendered entities cached:

function hook_preprocess_paragraph(&$variables) {
  foreach (Element::children($variables['content']['field_your_field']) as $index) {
    $child = &$variables['content']['field_your_field'][$index];

    if (your view switching logic) {
      $child['#view_mode'] = 'your_new_view_mode';

      // Update cache keys
      array_pop($child['#cache']['keys']);
      $child['#cache']['keys'][] = $child['#view_mode'];
    }    
  }
}

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.