When rendering the same node in different Views displays on the same page, all instances of the node receive theme suggestions for the last View.
Rough steps to reproduce
- Create Views
foo
andbar
each with a displayblock_1
and their row format configured to show content (instead of fields). - Place both Views displays on the same page, e.g., via Layout Builder, with
foo
first andbar
second. - Enable theme debugging.
- Inspect the markup to see that all instances of a given node receive theme suggestions for last View, i.e.,
node__views__bar
andnode__views__bar__block_1
.
Cause
- Views implements hook_theme_suggestions_HOOK_alter() to add the suggestions. It relies on a special key on the node object called
view
(a ViewsExecutable) to pull the View ID and display ID. - TranslationLanguageRenderer::preRender() provides that ViewsExecutable on the node entity.
- But that node entity was loaded via NodeStorage:load(), which allows for static caching of Node objects via EntityStorageBase::getFromStaticCache().
- Static caching of the Node objects means that the same instance is being shared across all Views on the page, and therefore the special
$node->view
key gets overwritten by subsequent Views.
Solution
I'm not sure, but perhaps #2511548: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data will mitigate this by allowing TranslationLanguageRenderer::preRender() to pass the ViewsExecutable via context rather than as a special key attached to the Node object.