Problem/Motivation
Views currently does not show theme suggestions, due to a bug in core: #2118743: Twig debug output does not display all suggestions when an array of theme hooks is passed to #theme
Mark Carver though pointed out in #2118743-167: Twig debug output does not display all suggestions when an array of theme hooks is passed to #theme that views could also use hook_theme_suggestions
Proposed resolution
Use hook_theme_suggestions()
instead of arrayed theme hooks.
Remaining tasks
Postponed till #2511548: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data is finished.
User interface changes
None
API changes
Deprecates ViewsPluginInterface::themeFunctions
and ViewExecutable::buildThemeFunctions
and replaces them with equivilent themeSuggestions methods.
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#92 | 2923634-92.patch | 16.18 KB | tcrawford |
#84 | interdiff_22_84.txt | 558 bytes | phparkle |
#84 | 2923634-84.patch | 16.74 KB | phparkle |
#83 | interdiff_76_83.txt | 633 bytes | pcambra |
#83 | 2923634-83.patch | 24 KB | pcambra |
|
Issue fork drupal-2923634
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:
Comments
Comment #2
dawehnerThis seems to work ...
Comment #3
BerdirWe need to be careful to not break plugins and customizations that rely on this and might customize it. I see you still call the themeFunctions() method, but I could imagine that some weird cases like feed output or so might use things differently. I know I did some tricks with custom feed things in the past, e.g. with https://www.drupal.org/project/views_googlenews.
Comment #4
dawehnerIndeed, nothing is ever easy.
@Berdir
I tried to make this opt in as in: If you don't set #views_plugin, nothing happens. Do you mind pointing me to the place you refer to with "some tricks with custom feeds"?
Comment #6
markhalliwellComment #7
markhalliwell@dawehner, the patch in #2 is essentially the same solution I came up with in my head yesterday when going through Views' code, so I think we're on the right track :D
---
I'm not sure what specific "tricks" @Berdir is referring to. I did look at the code for this module and nothing seemed to jump out at me; it seems pretty straightforward.
http://cgit.drupalcode.org/views_googlenews/tree/src/Plugin/views/style/...
http://cgit.drupalcode.org/views_googlenews/tree/src/Plugin/views/row/Go...
As you can see with the above, these invoke
$this->themeFunctions()
directly and doesn't provide#views_plugin
, so this contrib module wouldn't be affected.I don't think we will have to worry about affecting other contrib modules at all as long as this remains "opt-in" as @dawehner says. Regardless, this will definitely need a change record and heavy promotion so Views plugin authors know to update their code and to stop using
$this->themeFunctions()
directly.In fact, I think the existing method should probably be deprecated and a new one created named
themeSuggestions
, move existing code to this new method and then invoke this new method from the old one. This would allow IDEs (like PhpStorm) to indicate to developers that they shouldn't use this method directly anymore. A link to the TBD change record could be added even.---
I'm sure the above patch was just focusing on seeing if this would work in the first place, but let's not forget about ViewExecutable::buildThemeFunctions too.
Comment #8
dawehnerThis might be already everything needed to fix those failures ...
Comment #10
maxplus CreditAttribution: maxplus commentedThanks,
patch from #8 is showing all my views theme suggestions now in twig debug
Comment #11
RedEight CreditAttribution: RedEight at 95Visual commentedPatch #8 worked beautifully.
Comment #12
markhalliwellPath #8 was just the intital POC and it seems stable enough.
There's still work to be done though as I mentioned in #7.
Comment #14
andypostMaybe better use specific
hook_theme_suggestions_HOOK_alter()
for each allowed plugin instead of common one?Comment #15
RedEight CreditAttribution: RedEight at 95Visual commentedI'm not sure if the issue I'm experiencing is related to this patch or if views actually checks templates in the wrong order.
Here is a twig debug suggestion that works and goes from specific at the top, to more generic at the bottom.
As you can see, I have my own custom template that is loading successfully for my paragraph of type 'p-view-reference'.
With the patch in #8 I can see the template suggestions as follows.
You can see that the order of listed suggestions is from most generic to most specific, exactly the opposite of the others. Also, my more specific template
views-view--services--homepage.html.twig
refuses to be used and it always choosesviews-view.html.twig
.NOTE: The paragraph override still works and displays correctly with this patch. It's only the view suggestions that are incorrect and don't work with #8
Comment #16
andypost@RedEight #2752443: Incorrect order and duplicate theme hook suggestions
Comment #17
gambrySuggestions are expected to be returned with ASC specificity, ie from
system_theme_suggestions_field()
:We may need to either array_reverse() here or on the themeFunctions().
I understand returning the suggestions from
views_theme_suggestions_alter()
is much easier and quicker then implementing all the singles instances of hook_theme_suggestions_HOOK(), so IMHO +1 for that.Comment #18
dawehner@RedEight
Do you mind trying out the other patch and report whether the two together works for you?
Comment #19
dietr_ch CreditAttribution: dietr_ch at EntityOne commentedApplying both patches doesn't solve it. Also see gambry's comment there.
Comment #20
gambryI've got a
related_content
view with ablock
display and a customviews-view--related-content--block.html.twig
template.This are my output with all scenarios:
With #2923634: [PP-1] Use hook_theme_suggestions in views:
With #2923634: [PP-1] Use hook_theme_suggestions in views with array_reverse():
With #2752443: Incorrect order and duplicate theme hook suggestions + #2923634: [PP-1] Use hook_theme_suggestions in views:
With #2752443: Incorrect order and duplicate theme hook suggestions + #2923634: [PP-1] Use hook_theme_suggestions in views with array_reverse():
With #2752443: Incorrect order and duplicate theme hook suggestions with fix (#40 .4) + #2923634: [PP-1] Use hook_theme_suggestions in views with array_reverse():
Comment #21
gambryWorking on this.
Comment #22
gambryAttached patch to reverse suggestions array output as the ThemeManager would expect and test coverage.
Some outstanding doubts the reviewer should take in consideration are:
- I still think using
hook_theme_suggestions_alter()
is our best option, otherwise we need to implementhook_theme_suggestions_HOOK()
for each single hook, which increase the amount of code without reason. Also developers providing their own plugins will require their own hook_theme_suggestions_HOOK(), while with the _alter() we do the job for them.- I'm reversing the suggestions array inside
views_theme_suggestions_alter()
, but wondering if outputting the right order fromViewExecutable::buildThemeFunctions()
is better.Comment #23
markhalliwellHas no one read #7?
Comment #24
NickGee CreditAttribution: NickGee commentedConfirming #22 works!
The only minor issue is that one views template suggestion is repeated (the last one):
Steps for testing:
I will leave status as-is due to the duplication of the final view template suggestion. Once this is resolved we can retest and go to RTBC.
Comment #25
PierreMarcel CreditAttribution: PierreMarcel as a volunteer and for Therefore commentedI agree with #24. I tested and got the same result. Lets get a few more community members testing it, but the initial issue has been covered on the #22 patch
Comment #26
markhalliwellThis is reversing the entire $suggestions array, not just the view plugin suggestions.
That being said, most of this is premature optimization due to #2752443: Incorrect order and duplicate theme hook suggestions which is an entirely separate issue from this issue and shouldn't be included here.
As far as the "order" of these view plugin theme hook suggestions, I would like to again recommend (#7) that this issue add a dedicated
themeSuggestions
method (using the correct order) and deprecate the oldthemeFunctions
method.---
Last, but not least, this still (#7) hasn't addressed ViewExecutable::buildThemeFunctions.
Comment #27
gambry@markcarver my bad. I had read #7 but in my mind probably got mixed up with your comments on #2752443: Incorrect order and duplicate theme hook suggestions. I beg pardon.
Your suggestions make sense to me, I will update my patch adding your suggestions in #7.
Good catch! will fix.
If you are referring to the
array_reverse()
then is not premature. Views is sending the suggestions in the wrong order. See in #17 how 'field' suggestions order is returned.If you are referring to #24 - #25 than you are correct and #2752443: Incorrect order and duplicate theme hook suggestions will fix that issue. As the problem is just with the base hook being repeated as last suggestions I don't think #2752443: Incorrect order and duplicate theme hook suggestions is a blocker for this issue.
Not sure what you mean exactly. Are you thinking about a re-factor of the method name similar to
themeFunctiona()
?Comment #28
markhalliwellIt is when we can simply create a new method designed specifcally for theme hook suggestions that returns the correct order in the first place and thus eliminating the need for
array_reverse()
in the first place :DCorrect.
The above patch(es) take care of the plugin theme hook suggestions.
However, ViewExecutable::buildThemeFunctions is for the View entities themselves which still populates
#theme
with an array of theme hooks. This will also need to be converted to use a new method specifically for theme hook suggestions and then deprecate the existing method.This whole thing stems from the fact that Views is using an antiquated theming technique to provide "theme hook suggestions" by passing an array of theme hooks to
#theme
instead of a single string. That includes ViewExecutable::buildThemeFunctions, not just its plugins.Comment #29
gambryPerfect! I thought you meant premature as "the ThemeManager will already revert those". I already mentioned I don't like the reverse to stay in the *_alter_hook.
Just to be clear again - better safe than sorry :D - buildThemeFunctions() itself just builds the array, it's how other piece of codes make use of it we need to refactor. Is that what you mean?
My idea was to deprecate
PluginBase::themeFunctions()
as well asbuildThemeFunctions()
in favour of new methods, so it looks like we are on the same page again.Said that I won't be able to work on this until the Winter Open Source Sprint, so if anyone want to tackle #27 and #28 in the meanwhile feel free to do it.
Comment #30
markhalliwellCorrect. That is the problem. Views shouldn't be passing an array of theme hooks to anything.
The only thing that should be an array when dealing with theme hooks is suggestions, which now have dedicated alter hooks.
This may help explain things a little better:
ViewExecutable::buildThemeFunctions
(view entity) ===PluginBase::themeFunctions
(view plugins)So far, this issue has focused primarily on
PluginBase::themeFunctions
(view plugins).Good. I was envisioning something along the lines of:
Using
array_reverse()
here would be appropriate since the newthemeSuggestions()
method should return the correct array order and this must provide BC support.Since its likely to not be used at all (or at the very least very infrequently), it's OK to implement it here as performance isn't the primary goal of BC code and the performance impact of adding in
array_reverse()
here is rather negligible given that it will be deprecated.Comment #31
BerdirBC is hard. (Can I have a trademark on that sentence? I seem to use it in every second issue)
It needs to go in both ways. If someone customized that method in a plugin, it still needs to work, we can't just break that. And that's actually pretty hard to do. Only idea I had so far is some trickery with moving the BC version of themeFunctions() to a __call() implementation and then in the new method, check if the plugin implements a themeFunctions() method, if yes, call it and trigger a deprecated warning.
Comment #32
markhalliwellHm. Maybe, the new
themeSuggestions
method should check if the deprecatedthemeFunctions
method was overridden in a subclass (https://stackoverflow.com/a/16523542). If it was, then the new method would invoke that, reverse the array and trigger a deprecation notice.If it wasn't then it would return the normal theme hook suggestions.
Comment #33
ttamniwdoog CreditAttribution: ttamniwdoog as a volunteer commentedWorks great! Thanks for the patch
Comment #34
markhalliwellSetting back to CNW, see #26-#32, which still hasn't been fully addressed.
Comment #35
dawehnerIs this what are you asking for?
Comment #36
markhalliwellThis should have the array of theme suggestions and the
themeFunctions
method should be calling this method and usearray_reverse
.Adding something to an existing interface is a backwards incompatible change (at least that's what was told to me before).
---
This also, still, does not not address
ViewExecutable::buildThemeFunctions
.Comment #37
dawehnerBut well, we cannot change the behaviour of the function in the ViewExecutable, so we have to reverse twice?
Comment #38
markhalliwellNo.
The new
themeSuggestions()
method should not have/usearray_reverse
at all. It should order the suggestions correctly to begin with.The only
array_reverse
that should happen would be inViewExecutable::buildThemeFunctions
andPluginBase::themeFunctions
because they should now be invoking the newthemeSuggestions()
method for both classes (which should already have the correct array order). That is whyarray_reverse
in these existing methods is important: to keep BC and not change the expected behavior.These existing methods should also be marked
@deprecated
.Comment #39
dawehnerThis absolutely makes sense!
Comment #40
dawehnerWell, which plugin instance should ViewExecutable call? This is a function
Comment #42
markhalliwellHm. I think something is getting lost in translation. I'll see if I can't clear it up real quick.
Comment #43
markhalliwellOk, let's see if this makes more sense.
I also went ahead and fixed some of the tests, so everything _should_ pass now.
Comment #44
markhalliwellComment #45
Anonymous (not verified) CreditAttribution: Anonymous commentedThanks for great works! Twig debug the only tool for get info about suggestions, so at least a Major status (Critical for
novicetheming).#43 patch works perfect! RTBC++
One nit is duplicate
'views-view-unformatted.html.twig'
suggestion in list:Looks like @gambry in #20 (last part) found solutions for this. But I'm not competent in the question of how this is implemented. And I absolutely agree if this will be postponed to the follow-up.
Comment #46
markhalliwellYes, that will/should be handled by #2752443: Incorrect order and duplicate theme hook suggestions.
Comment #47
Anonymous (not verified) CreditAttribution: Anonymous commented@markcarver, thank you for clarifying this point! (and thanks for the patience, now I see that I just repeated one of the posts above, to which the answer was given).
Change Record and 1 CS typo - the remaining reasons for the delay here? I started writing CR, but of course, we need someone more computational than me.
Comment #48
markhalliwellThis really should use
#context
, not arbirary#views_*
properties.Comment #49
markhalliwellHere's a patch that takes into account the above issue. Will set to CNR and test it once that issue makes it in.
Comment #50
Anonymous (not verified) CreditAttribution: Anonymous commentedUpdated CR per #49.
Also noted that with #43 views pager does not show any suggestions.
But with #49 + #2511548-37: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data pager suggestions show OK.
Comment #51
akalam CreditAttribution: akalam at Metadrop commentedSolution described on #50 solved the issue for me. After applying both patches the theme suggestions are properly displayed.
Comment #52
jwilson3Comment #53
markhalliwellComment #55
hanoiiFor what it's worth, here's a re-rolled patch that applies to both 8.7.x and 8.6.0.
Making the interdiff was not easy, but basically it was just some coding standard issues on `core/modules/views/tests/src/Functional/ViewsTemplateSuggestionsTest.php` are already in.
Comment #56
frobUpdated IS with link to issue that this issue is waiting on.
Comment #57
John Cook CreditAttribution: John Cook at Creode commentedI've re-rolled the patch from #55 for 8.7.x.
Comment #58
John Cook CreditAttribution: John Cook at Creode commentedAn undefined index caused a load of errors. I've added a quick return if the index hasn't been set.
Comment #59
markhalliwell#58 isn't needed once #2511548: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data gets in, which this issue is postponed on.
Comment #60
John Cook CreditAttribution: John Cook at Creode commentedNew patch. This one actually appears to work.
(I think there's going to be one of the tests failing – a difference in ordering of arrays)
Comment #61
markhalliwell@John Cook, please stop reverting the patch to work without context.
This issue is dependant on #2511548: Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data.
Apply the patch from that issue and then use #55.
Comment #62
lpeabody CreditAttribution: lpeabody commentedPatch from #2511548 solved the billion warnings I got about #context not being set.
Comment #63
markhalliwellHeres a semi re-roll and modification of the deprecation version.
Comment #64
markhalliwellUpdated CR: https://www.drupal.org/node/2962549
Comment #65
markhalliwellRemoved the
views_plugin
variables that were added to views theme hooks prior to the#context
switch.Comment #67
rajveergangwar#22 works for me with charm.
Comment #68
jennypanighetti CreditAttribution: jennypanighetti commented#65 and the related issue patch worked for me.
Comment #69
alphawebgroup#65 can not be applied anymore...
Comment #70
shaalI re-rolled patch #65
Comment #73
macherif#22 works for me. Thank you @gambry .
Comment #75
TylerMarshall CreditAttribution: TylerMarshall as a volunteer and at Acro Commerce, Underscore Software Inc commentedThis patch I am using in #22 requires for deprecation that the base theme be set in the theme file. Should I make this against the latest patch 65, or off of 22 which I am using?
Comment #76
leymannx#70 gave me the following notice all over the page on D8.9:
I just added another wrapper to check if context is set fixes it for me.
Comment #77
a.dmitriiev CreditAttribution: a.dmitriiev as a volunteer and at 1xINTERNET commentedLast 8.9 patch breaks theme suggestions for views, for example media-library template from classy is not found anymore
Comment #79
preciado04 CreditAttribution: preciado04 as a volunteer and commented#22 it's working like a charm. Thanks so much!
Comment #80
unqunq CreditAttribution: unqunq commented#22 it's working for me as well. Thank you @gambry
Comment #83
pcambraI was looking at #3139335: [D9 ONLY] The 'core_version_requirement' constraint requires the 'core' key not be set, but test modules might end up with both and I think comments 6 and 7 refer to a couple of things stale on the views_test_suggestions_theme.info.yml file, here's an updated patch for those on 9.x
Comment #84
phparkle CreditAttribution: phparkle as a volunteer commentedReroll #22 for D9.
Comment #86
thalemn CreditAttribution: thalemn commentedI'm using 9.4.8 with PHP 8.0 and have applied the patch in comment #22. Thank you @gambry.
The twig debug info is displayed in the DOM, not in the inspector. Is this the expected output?
I tried the patch in comment #84 with the same results (thank you @phparkle).
If this is the expected results, I'm OK with that; at least I have twig debugging information.
Comment #87
perarg CreditAttribution: perarg commentedI applied #84 in 9.5.0 and it's working as expected. Suggestions are now displayed. Thank you :)
Comment #88
captain hindsight CreditAttribution: captain hindsight commentedJust a quick question on this, I couldn't find a more appropriate issue. I wondered why ViewExecutable::buildThemeFunctions prefers (or even involves) the display_id as first argument over the view id.
Is this intended? For me this looks a little bit like gambling, to even involve display_id as first argument. I stumbled on this after using a "views-view--something.html.twig" and wondered why the display of a view matched another html.twig, because its display id matched it, which I never expected...
Comment #89
aiphesHi,
So @captain hindsight , do it be necessary to patch to get views template suggestions with display id or just adding code into .theme file ? Something like:
$suggestions[] = 'views_view__' . $variables['view']->id(). '__' . $display['id'];
Comment #90
julio_retkwa#83 it's working fine for me. Thanks !
Comment #92
tcrawford CreditAttribution: tcrawford at Liip commentedI am currently upgrading a project to Drupal 10 and so I have re-rolled #84 for D10.
The patch (2923634-92.patch) is identical as #84, except for removal of the changes to /core/modules/aggregator/src/Plugin/views/row/Rss.php, due to the removal of the aggregator module from core. I have not created an interdiff as the first patch no longer applies on D10.
I hope this assists if you are currently upgrading to D10. As the issue is postponed I have not created a patch against D11.
Comment #93
manikandank03 CreditAttribution: manikandank03 as a volunteer commented@tcrawford, thanks for the D10 patch.
#92 patch cleanly applied on Drupal 10.1.1.
Comment #94
miiimoooWith the patch in #70 against 9.x I got this for example for an exposed views block:
With the latest patches here against 10.x I only get
Going back to #83 against 10.x brings back the theme suggestions (form---VIEW_ID--DISPLAY_ID.html.twig,..) (though it doesn't apply cleanly due to the patch for core/modules/aggregator/src/Plugin/views/row/Rss.php)
Something went missing in #92
Comment #96
miiimoooRe-rolled patch from #83 to apply cleanly against 10.1.x
Comment #97
ben.hamelin CreditAttribution: ben.hamelin at Oomph, Inc. commentedI did not dig in to this much, but just noting that during an recent upgrade to 10.1 (from 9.5) this patch was breaking suggestions for views - existing template overrides (e.g. views-view-list--[machine_name]) were not being used. Removing the patch resolved for me.
Comment #98
Abyss CreditAttribution: Abyss at DevBranch for Drupal Ukraine Community commentedThis doesn't work quite right for Drupal 10.
Example:
Comment #99
Abyss CreditAttribution: Abyss at DevBranch for Drupal Ukraine Community commentedComment #100
miiimooo@ben.hamelin Have you tested wit the re-rolled patch from #96? I did that re-roll because previous patches were broken after upgrading to 10.1
Comment #101
webdrips CreditAttribution: webdrips commented#92 works for me (Drupal 10.1.5), thanks.
Comment #102
ressa CreditAttribution: ressa at Ardea commentedThe patch applies with som difficulties against 10.2.2, but I don't get file name suggestions for Views table:
Applying the patch: