.../Field/FieldFormatter/CommentDefaultFormatter.php | 12 ++++++++++++ .../FieldFormatter/EntityReferenceEntityFormatter.php | 18 +++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 154edf6..eba2654 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -145,6 +145,18 @@ public function viewElements(FieldItemListInterface $items) { if ($this->getSetting('pager_id')) { $build['pager']['#element'] = $this->getSetting('pager_id'); } + // Entity field formatters are run during the #pre_render phase of + // rendering an entity. Therefore, that is the time when this function + // runs. After that #pre_render callback, all cache tags must be + // available. However, this field formatter is highly exceptional: it + // renders *other* entities (i.e. entities within an entity). Those + // other entities come with their own #pre_render callback that must + // be called in order for the cache tags associated with them to be + // included with those of the main entity. Hence we must render the + // the other entities *immediately* (which includes running their + // #pre_render callback), otherwise their associated cache tags won't + // bubble up. + drupal_render($build, TRUE); $output['comments'] = $build; } } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php index d8d9d41..a7e19f6 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php @@ -93,8 +93,6 @@ public function viewElements(FieldItemListInterface $items) { } if (!empty($item->target_id)) { - $elements[$delta] = entity_view($item->entity, $view_mode, $item->getLangcode()); - // Entity field formatters are run during the #pre_render phase of // rendering an entity. Therefore, that is the time when this function // runs. After that #pre_render callback, all cache tags must be @@ -102,15 +100,13 @@ public function viewElements(FieldItemListInterface $items) { // renders *another* entity (i.e. an entity within an entity). That // other entity comes with its own #pre_render callback that must be // called in order for the cache tags associated with that other entity - // to be included with those of the main entity. Hence we must run the - // other entity's #pre_render callbacks *immediately*, otherwise its - // associated cache tags won't bubble up correctly. - if (isset($elements[$delta]['#pre_render'])) { - foreach ($elements[$delta]['#pre_render'] as $callable) { - $elements[$delta] = call_user_func($callable, $elements[$delta]); - } - } - unset($elements[$delta]['#pre_render']); + // to be included with those of the main entity. Hence we must render + // the other entity *immediately* (which includes running its + // #pre_render callbacks), otherwise its associated cache tags won't + // bubble up. + $referenced_entity_build = entity_view($item->entity, $view_mode, $item->getLangcode()); + drupal_render($referenced_entity_build, TRUE); + $elements[$delta] = $referenced_entity_build; if (empty($links) && isset($result[$delta][$target_type][$item->target_id]['links'])) { // Hide the element links.