Problem/Motivation
When a Feed display is configured for a view the node RSS row plugin removes the #theme
attribute from the built node data, causing the displayed nodes to render their fields individually instead of via the node template. However, the render element still contains the same caching information, causing it to be stored in the render cache as the output for that node & view mode (with a permanent max-age). Any other location where the node is displayed with that same view type will load the cached, incorrect, output.
Steps to Reproduce
1. Create a view with two displays; one Page display and one Feed display.
2. Configure both displays to show nodes using the same view mode
3. Ensure render caching is enabled
4. Rebuild site caches
5. Open incognito(private) browser window
6. Visit the Feed display
7. Visit the Page display
The page display outputs the nodes as concatenated field markup instead of using the node template.
7. Rebuild site caches
8. Load the Page display
9. Load the Feed display
The page display should now use the node template markup.
Proposed resolution
When Views renders an entity display for use in an RSS feed, it should set a cache key to differentiate the RSS-rendered version, so that the RSS-rendered version isn't incorrectly used in other contexts (such as when rendering the same entity display for an HTML page).
Comment | File | Size | Author |
---|
Issue fork drupal-2885098
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 11.x compare
- 2885098-node-rss-views-cache changes, plain diff MR !6257
Comments
Comment #2
gappleComment #4
joelpittetFix the cache context because now some of the theme will render out author user context.
Comment #7
gappleOnly difference from #4 is that the path to
CommentRssTest.php
has changed.Comment #8
mohit1604 CreditAttribution: mohit1604 at Google Summer of Code commentedComment #9
zymbian CreditAttribution: zymbian as a volunteer commentedPatch #7 looks good. Marking RTBC.
Comment #10
catchIf this is supposed to bypass the node template and now doesn't, won't that cause other problems?
Comment #11
gappleI don't understand a reason for the node template to be bypassed in the first place, as it results in an unexpected override of the rendered node contents. If the intent is to output fields directly instead of a display mode, then the view should probably use the 'fields' row formatter instead.
An alternative, that would maintain the current behaviour, is to also remove the cache keys from the node to be rendered.
Comment #12
pifagorlooks good. Marking RTBC.
Comment #14
alexpottTestbot had a hiccup re-rtbcing
Comment #15
alexpottThis seems pretty important to have a test for.
Comment #17
a.milkovskyI am experiencing a similar problem. The patch #11 resolves the caching issue. Using Drupal 8.5.6.
Comment #18
MerryHamster CreditAttribution: MerryHamster at Skilld commentedReroll for 8.7.x
Comment #19
MerryHamster CreditAttribution: MerryHamster at Skilld commentedComment #20
andypostNW for tests
Comment #22
ksbuble CreditAttribution: ksbuble commentedI am at Seattle Sprint and working on this issue.
Comment #23
ksbuble CreditAttribution: ksbuble commentedFollowed steps to reproduce with caching for Page and Feed set to Tag-based (for render caching). Not reproducible with Drupal core 8.7.0-dev environment from Community Tools Download (https://www.drupal.org/tools) using Devel 8.x-2.0 Generate to populate nodes.
Rerolled with code from patch 2885098-18.patch including test cases from drupal-2885098-11-node-views-rss-no-cache.patch.
Comment #24
yogeshmpawarTriggering bots.
Comment #28
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedRe-roll patch created for 9.1.x
Comment #30
Suresh Prabhu Parkala CreditAttribution: Suresh Prabhu Parkala at Specbee commentedPlease review.
Comment #31
mradcliffeThanks for the patch. I moved this back to Needs work. I think at this point it makes sense to work on a test that will demonstrate the bug. I think this is still a Novice issue.
Comment #32
bakulahluwaliaCan't reproduce the bug. Tried the following:
Test Case1:
1) Created view as content with type: article [already have 1 node created as article]
2) the page view with Format:Unformatted list | Settings and Show:Content | Full content. Caching: tag based, Path:/global2020
3) Added new view as feed with Format:Unformatted list | Settings and Show:Content | Full content. Caching: tag based, Path:/feed/global2020
Views output
Test Case2:
1) Created view as content with type: article [already have 1 node created as article]
2) the page view with Format:Unformatted list | Settings and Show:Content | RSS. Caching: tag based, Path:/global2020
3) Added new view as feed with Format:Unformatted list | Settings and Show:Content | RSS. Caching: tag based, Path:/feed/global2020
Output:
Both are showing expected results, page view showing title and RSS showing popup to download file.
Process:
1) Visited RSS page first then page
2) Visited page first then RSS page
3) Also tried with different formats still can't get the cached page.
Comment #33
mradcliffeThank you, @bakulahluwalia. Being able to triage issues is really important too.
I confirm that I tried to reproduce it following the steps and wasn't able to reproduce it.
I changed Caching to something other than None in Administration > Configuration > Development > Performance, and after creating the view, I cleared cache, visited the Feed, noted the fields, visited the page, and I saw the content rendered and the markup was based on the node template.
I think if this issue still exists, we would need to update the Steps to reproduce and write a failing test first.
Comment #34
Berdir> I changed Caching to something other than None in Administration > Configuration > Development > Performance
The _only_ affect this setting has is the Cache-Control HTTP header.
Based on the code, this is about the render cache. I didn't try to reproduce yet, but the fix makes sense to me and I can see that this could happen.
Maybe try with a different view mode, there's special special handling around default, although full should work.
Comment #36
gappleComment #37
amjad1233Hi,
I followed the steps as described in the issue but could not re-produce the results.
Is there anything we need this issue to get moving forward ?
Comment #38
gapple@amjad1233 It is unclear from your screen capture if/when you cleared the cache, and what order afterwards you loaded the HTML and RSS displays of the view.
Does the markup of either display change depending on which display you load first after rebuilding the site cache?
Comment #39
amjad1233Hi @gapple,
Sorry I think you're right. I was doing the wrong cache clearing sequence.
I am just uploading GIF here for anyone to see the issue visually.
@berdir the above screenshot is in Full display mode.
Regards,
Amjad
Comment #40
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedThank you for finding the solution to this. It's been driving me mad on my blog for months. I spent hours and hours tracking down where the problem is from but only managed to figure it was something to do with RSS feeds.
Essentially, the problem is that when you render the node in a RSS feed as a teaser view mode the default node template is used and that template is added to the render cache. This means that when you come to render the node as a teaser using the default template the RSS teaser cache is returned, which gives you the wrong template in your theme. I'm sure this problem exists with other view modes and entities.
I had a go at creating a test for this situation and managed to figure it out. The original fix for the Rss.php class is good, but change to the CommentRssTest test didn't make sense to me.
The good news is that I managed to create a test situation that demonstrates the problem and the fact that the fix is correct. Hopefully everything is clear in the attached patch.
Comment #41
BerdirDescriptions must not be longer than 80 characters. I think the comment is a bit confusing anyway. the comment on the class seems much clearer.
trailing spaces.
not sure if we really need to check the cache directly as well, kind of seems like an implementation detail. Tests like this tend to break if things are refactored.
You should also upload a test-only patch separately and first, to prove that your test fails without the fix.
Comment #42
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedHi Berdir,
Thanks very much for taking the time to review. I agree with all of the points raised. I was wondering about the cache issue as I was writing it. I felt like I needed to check and demonstrate that the cache was correct, but I was also thinking "this _might_ need fixing in the future". I'll need to keep an eye out for that feeling in the future :). Apologies about the code formatting issues, I should have spotted those.
I have a new patch with the changes applied and another patch without the original fix in place to show that the problem exists. Good idea about the second patch without the fix, I hadn't thought of doing that.
Thanks,
Phil
Comment #44
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedAdding interdiff between #40 and #42.
Comment #45
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedComment #46
jplana CreditAttribution: jplana commented+RTBC
I can confirm patch #42 fixed our long-standing problem, similar to other people have reported here: #2915636: node.html.twig intermittently being ignored
The steps I followed to reproduce was:
1. Clear the cache.
2. Visit a taxonomy term feed, for example: /taxonomy/term/%/feed that will generate the cache for the RSS feed
3. Visit a page with a view that displays the same content as the taxonomy term feed. I was getting the 'broken' rows displaying at this point.
Thank you very much @philipnorton42! You're a legend :)
Comment #47
jplana CreditAttribution: jplana commentedComment #48
gappleComment #49
catchIt seems like this will just completely remove render caching from RSS pages. Could we change the cache key instead of unsetting it?
Comment #51
rachel_norfolkTrying this out on https://rachelnorfolk.me to see if it resolves https://twitter.com/rachel_norfolk/status/1389905214359146500.
Of course, an intermittent issue needs a few days to see how it goes…
Comment #54
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedThanks for the feedback catch.
I've had another go at doing this and rather than remove the keys I have added an additional key that references the view rss feed. After some testing this approach appears to work fine and the unit tests created work well also.
This seems like a better approach than just removing the cache keys. Ready for a review I think!
Comment #55
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedLooks like the test got tripped up on a coding standards thing that was introduced since the last coding standards check.
Fixed the issues in that file and re-created the fix.
Comment #56
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedComment #57
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedNoticed an issue in the views.view.test_node_article_feed.yml file were the previous and next characters were being corrupted.
Sorted that out to keep things neat.
Comment #58
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedComment #59
nlisgo CreditAttribution: nlisgo commentedIs this change intentional? If doesn't add value we should remove to reduce the diff.
Comment #60
nlisgo CreditAttribution: nlisgo commentedWe should remove the uuid.
Comment #61
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedThanks for the feedback nlisgo, much apprecaited.
I think the removal of the line in the render() method is fine. It was flagged as a coding standards issue though phpcs running locally and although it is technically out of the scope of the changes I was making, I think having this change ok.
Good spot about the uuid in the config file, I have removed that.
I have also changed the name of the class NodeRSSCacheTest to NodeRssCacheTest, which is also a coding standards change. Since this is a new class for this change I think that's fine in this case. It does bloat the interdiff a little bit though.
Comment #62
nlisgo CreditAttribution: nlisgo commentedThe standard now seems to be static::class or self::class.
Everything else looks good to me.
Comment #63
philipnorton42 CreditAttribution: philipnorton42 as a volunteer and at Code Enigma commentedAlso a good suggestion, I've used static::class as that gets around any late static binding issues with self::class.
Thanks again! o/
Comment #64
gappleI would like to re-up my enquiry #11, that never got an answer:
I still think that having
unset($build['#theme']);
so that nodes aren't rendered through the template system is an unexpected behaviour, and changing the cache keys resolves the cached conflict but patches over a root issue.Comment #65
BerdirViews supports both, and while the pseudo-rendered entity approach in my experience never really works out, just straight out removing a feature far more complex than just fixing this bug. we have to deprecate it, possibly convert existing config to a field based configuration instead, people might need to update their default configuration, ...
Comment #67
smustgrave CreditAttribution: smustgrave at Mobomo commentedCan the issue summary be updated as there 2 proposed solutions. Can we highlight which one was chosen. Will help with the review.
Comment #68
mradcliffeAdds issue summary update tag
Comment #70
smokrisIf I understand correctly, the remaining concerns have all been addressed:
…and the patch still applies, so I'll set this issue back to RTBC.
Comment #71
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue.
While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)
Comment #73
smokrisI converted the patch to a merge request, as instructed by the above needs-review-queue-bot comment.
Comment #75
larowlanLeft some minor comments. Fine to self RTBC after addressing.
Comment #76
larowlanI just applied suggestions for those two comments as they were minor, restoring status
Comment #77
larowlanComment module has the same issue, opened a follow-up #3418181: Comment RSS Views plugin causes wrong entity_view output to be cached
Committed to 11.x
As this is a bug and there is no risk of disruption, backported to 10.2.x