Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
For Custom StylePlugin
/**
* Style plugin to render each item as my style.
*
* @ingroup views_style_plugins
*
* @Plugin(
* id = "my_style",
* module = "my_views_style_plugin",
* title = @Translation("My Style"),
* help = @Translation("Displays rows as my style."),
* theme = "views_view_my_style",
* type = "normal"
* )
*/
Views trying to locate views-view-my-style.tpl.php
in core/modules/views/templates
rather modules/my_views_style_plugin
Proposed resolution
Adapt views_theme() to not assume that views is the only module providing views templates.
Remaining tasks
Commit it!
User interface changes
None
API changes
This just fixes the bug, so no API change.
Comment | File | Size | Author |
---|---|---|---|
#60 | 1911492-60.patch | 987 bytes | damiankloip |
#56 | 1911492-56-provider-module.patch | 600 bytes | tstoeckler |
#51 | 1911492-51.patch | 19.29 KB | damiankloip |
#51 | interdiff-1911492-51.txt | 1.77 KB | damiankloip |
#48 | 1911492-48.patch | 19.21 KB | jibran |
Comments
Comment #1
damiankloip CreditAttribution: damiankloip commentedBut then what if a custom style plugin wanted to just use one of views' theme functions? Wouldn't that change in logic break that? I haven't checked this properly btw :) This is just from looking at that diff and what I remember of views_theme...
Comment #2
jibranHow about this? If you want to use views'/any other theme functions add theme_path in your annotation.
Comment #4
jibranSeems random failure.
Comment #5
jibran#2: custom_styleplugin_template-1911492-2.patch queued for re-testing.
Comment #7
tim.plunkettThe views_theme() logic coming from the annotations works for our current use cases, but might not work for contrib, as seen above. Either way, we need tests to try putting theme functions and template files in various subdirectories.
Comment #8
jibranI will try to write tests.
Comment #9
jibranComment #10
derhasi CreditAttribution: derhasi commented@tim.plunkett, do you have a hint for what tests to write?
I'll give it a try.
I wrote a port for a views style plugin, where that bug made it totally complicated to implement the template: #1932830: D8 Port
Comment #11
derhasi CreditAttribution: derhasi commentedThere's my first approach for a test that checks for a module defined template file. The test will fail, as there isn' already a fix for that issue ;)
The generall problem, that we have to deal with a lot of confusion in the hook_theme() implementation, when implementing themes for other modules. Additionally by default template files should be located in the templates subdirectory as stated in [#1805952].
Comment #12
dawehnerThis seems to be nearly ready already, do they really break, let's see what the testbot tells us about that.
Just wondering: Have you tried to use ViewUnitTestBase? These ones are way faster to execute, and you don't use actual page requests but just API calls, so this seems to be possible.
... should be Contains \ now, sorry
Comment #14
derhasi CreditAttribution: derhasi commentedSo, the test fails as expected.
@dawehner, you may be right with
ViewUnitTestBase
, I haven't test it yet. I will do after we could clarify some of the points below ;)I think we should also cover the test cases,
For the first case, that module should have to set register_theme = FALSE and theme to the desired template - or is that wrong?
For the second case, there is no handling at all for the moment?
I guess the theme_path variable is something we cannot use really anymore with the Annotations (or is there something like drupal_get_path() for that), to point to a different module's directory.
Additionally I think we should better document that views theme register part. I could not find any documentation on that. Where is a good practice to document that Annotation-Parameters?
Comment #15
jibranI have merged the two patches. #11 and #2. But test will still fail because it tries to locate template file in
core/modules/views/tests/views_test_data/
instead ofcore/modules/views/tests/views_test_data/templates/
. It passes when tpl file is moved tocore/modules/views/tests/views_test_data/
Comment #16
derhasi CreditAttribution: derhasi commentedjibran, that's the problem. In D8 template files should by default be located in /templates, @see Template files are now located in a templates subdirectory.
The problem lies in the fact, that via annotation we should be able to implement a "theme file", e.g. a "mymodule.theme.inc" that in most cases would be located in the module's root, but on the other hand we are expected to provide a "directory" via the "theme path" annotation.
We have to make sure this default behaviour is implemented. Additionally we still have the problem with modules wanting to reuse another module's theme definitions.
My suggestion would be to implement the following
register_theme
has to be set to FALSE.module
has to be set in every plugin (other than views plugins). It is used to locate the module's root directory.theme_path
is NOT used to alter the destination of template file. Therefore I'd suggest to remove it completely and ...theme_file
to locate the theme include file. Therefore it may contain folders, but should always be relative to the module's root.This should be all fine with the needs of core. Every module that needs a totally different implementation might use hook_theme() or hook_theme_registry_alter() and set register_theme=FALSE.
Imho, the views theme auto-generation should be held very simple and should not clutter up with own functionality, that could be easily implemted by the core theme hooks.
To make the suggested changes more clear, here an example for the annotation of the existing Rss RowPlugin in the node module, that needs to add register_theme = FALSE to be consistent.
I'd very much like to hear your opinion on that. And then might to provide a patch to that.
One question though: were is the best practice to document those Annotation params?
Comment #17
dawehnerYeah I really think the templates should be located in the templates directory. If someone really wants to put in somewhere else, implementing hook_theme itself/alter it seems to be an acceptable way.
Comment #18
derhasi CreditAttribution: derhasi commentedSo, I finally put it together. Therefore I sort of reworked views_theme(). I added a bunch more comments and tried to better document the specification.
The interdiff goes against my last patch in #11.
Comment #19
dawehnerI'm really wondering whether this is right here ... what else then views will register these theme functions.
... "Contains \", sorry.
Oh I see you set views_view for all the displays, as it's the default value, mhhhhhhhhhh
We currently not force plugins to set the module key, but I think this would be valid at some point. Instead of watchdog() you could also call debug().
allllllways ;)
Great addition to the documentation!
Comment #20
damiankloip CreditAttribution: damiankloip commentedI think I agree with #19,
register_theme = FALSE
is reserved in my mind for plugins that don't want to register OR use any theme functions.I think we may need to wind this back in a bit, as essentially we are trying to remedy the fact that we can't compute and values in the plugin definition as before e.g.
drupal_get_path('module', 'my_module')
etc...Comment #21
derhasi CreditAttribution: derhasi commented@dawehner, register_theme has to be set to FALSE as that plugin shall not create a theme definition by itself. As those are plugins of the comment, block and node module, those need to make clear that they do not define that theme but simply use it (form views module).
For plugins that want to register the theme (currently the default behaviour as pluginmanager sets register_theme to TRUE), a module definition is needed. Maybe we shall change that default to FALSE.
@damiankloip, a plugin that does not want to use any theme functions, simply should not define "theme". register_theme is - as the name says - for registering that theme function to hook_theme().
That theme auto-register in the plugin definition is only a quick way to add theme and template definitions. All parts that are auto-registered can also be handled by the module itself in a more advanced way. Therefore the auto-register part does not need that full flexibility of setting using drupal_get_path(). Thats why -imho- that implementation should be and can be hardcoded to the expected path /templates.
Comment #22
damiankloip CreditAttribution: damiankloip commentedI think you are missing what I meant, I'm not saying it should do more. I'm saying that is the essence of what needs to be solved.
Also, unless a plugin is overriding render() itself, it will be expecting a 'theme' key in the definition.
Comment #23
derhasi CreditAttribution: derhasi commented@damainkloip, ok now I'm confused and really don't understand what you meant, I'm defenitely missing something. Maybe you can make it more clear for me :D
Comment #24
dawehnerI would vote to leaf it to TRUE, as the most used case is the one, where views should register the theme for you.
Oh perfect, this makes sense!!
@damiankloip
I'm confused as well, do you think we should get rid of the automatic registering?
Comment #25
jibran#18: views-template-test-1911492-18.patch queued for re-testing.
Comment #27
Manuel Garcia CreditAttribution: Manuel Garcia commentedConverting views_accordion here to d8, stuck due to this issue... tried applying the patch, not working:
Comment #28
Manuel Garcia CreditAttribution: Manuel Garcia commentedHere's a partial reroll of patch #18.
I've only rerolled the part on views hook_theme implementation.. the rest of the previous patch (tests etc) I've left out...
At least this patch applies and gets plugin's twig files located properly.
Comment #29
Manuel Garcia CreditAttribution: Manuel Garcia commentedFull refactor of #18...
I hope I haven't missed anything, a lot of changes, and some are now located at different places...
Comment #30
Manuel Garcia CreditAttribution: Manuel Garcia commentedOops forgot to add the new files.
Comment #32
Manuel Garcia CreditAttribution: Manuel Garcia commentedI guess I'm not so sure about making this patch... :S any pointers?
Comment #33
pcambraPatch looks fine to me, did a re-roll and used git --staged just in case it's not a testbot hiccups
Just one comment, though
Why is this text here?
Comment #35
jibranThis should be drupal_render($output). @ see ViewRenderTest.php
this should be
views-data-test-display-template.html.twig
To check this assertion
Comment #36
jibranThis should be green. And this is my first php to twig template conversion ;)
Comment #38
Manuel Garcia CreditAttribution: Manuel Garcia commentedAwesome thanks for following up on this =)
Looks like this change is making it not green? Don't ask me why though...
Comment #39
jibranIt is still failing. I have fixed the old view and some docs.
Comment #41
jibranOnly
StyleMappingTest
is showing template not found exception. New tests added to the patch are working fine now.register_theme = FALSE,
in Annotation.module/template/views-view-my-style.html.twig
or functiontheme_views_view_my_style
iftheme = "views_view_my_style",
in Annotation.So here is a new case
MappingTest
views style plugin just want to usetemplate_preprocess_views_view_mapping_test
and has no theme function/template(that is whyStyleMappingTest
is showing template not found exception).If I put
register_theme = FALSE,
in annotation I get this failure becausetemplate_preprocess_views_view_mapping_test
in not called.Any suggestions.
Comment #43
jibranFixed some docs, removed redundant class and reverted extra changes.
Comment #45
dawehnerComment #46
dawehnerAs these are the default themes, could we also remove them, just wondering ...
#1969388: Change notice: Add dedicated annotations for Views plugins introduces a proper plugin annoation so we might want to move all this documentation later?
This class needs some docs.
No need for this empty line.
Isn't it called "provider" now?
Comment #48
jibranFixed both of failing tests. Thanks @dawehner for the review.
Drupal\views\Plugin\views\PluginBase::themeFunctions()
.module
key in @Plugin annotationComment #49
damiankloip CreditAttribution: damiankloip commentedNope, provider is added for us (and is for all annotated plugins) when the annotations are discovered. The module key will be removed.
Comment #50
jibranOk. This is a major bug and because of this I am unable to port my views related module to D8. Replacing module key with provider key seems more like a normal task. So can we please move this point to follow up issue?
Comment #51
damiankloip CreditAttribution: damiankloip commentedNo, because this is a really small change, and should definitely be included in this patch. Why rely on a key that might not be there (when we need it to be there) when we have a provider key that is baked into our annotation discovery?
I have saved you the bother and made that change. This is all we mean :)
Comment #52
jibranThanks @damiankloip for expalining this and for the change. This change is awesome. I thought we have to change all the annotation of views plugins with this as well.
Something like #1969388-50: Change notice: Add dedicated annotations for Views plugins @olli suggested
. @dawehner said
Sorry for the confusion.
This a redundant now because provider is always set.
Comment #53
damiankloip CreditAttribution: damiankloip commentedI think maybe we should leave it in there; you never know what people may do with altering definitions etc... :)
Comment #54
dawehnerI don't want to bikeshed but this blocks like every style plugin in contrib from being ported.
I updated the issue summary so it is a bit nicer to read.
Comment #55
Dries CreditAttribution: Dries commentedPretty straightforward and much needed. Committed to 8.x. Thanks!
Comment #56
tstoecklerThe use-case of \Drupal\Core providing views theme implementations or whatever is a bit far-fetched, but for correctness this should actually check whether $def['provider'] is a module or not.
drupal_get_path('module', 'Core')
simply makes no sense.Comment #57
jibranNice catch.
Comment #58
dawehner+1
Comment #59
catchCommitted/pushed to 8.x, thanks!
Comment #60
damiankloip CreditAttribution: damiankloip commentedI don't really see much point in checking this too, we're adding (at the moment at least 2 to 3) extra function calls for every plugin of every type...for an edge case that is never going to happen, we're babysitting ourselves?
I guess this *could* be useful if some module wanted to provide some theme function on behalf of another, but that's about it.
If we are keeping this in, can we at least not get the module handler for every plugin of every type (which I think is 19)? :)
Comment #61
tstoecklerYes, that makes sense as well.
Comment #62
catchThat works.
Is there an issue open to watchdog/throw the exception? Silently failing is not good.
Comment #63
damiankloip CreditAttribution: damiankloip commentedI guess if we're adding this, we might as well minimise the function calls :)
I'm not even sure if we want this watchdog message/todo anymore? As we can't determine between a plugin providing for another module and anything else. Aside from that 'provider' will always be set from the annotation discovery, so will always be there.
Comment #64
derhasi CreditAttribution: derhasi commentedI originally intended this @todo for a developer that forgot to annotate the provider for the plugin. It should help the developer to do stuff right, for that throwing an exception might be the best choice?
Besides: if modules are now called providers (I missed that), we should update the documentation. I could not find the part, where it is documented in code currently, maybe someone can help me ;) ... it simply has been to long I last looked into D8 core :D
Comment #65
damiankloip CreditAttribution: damiankloip commentedComment #66
catchThrowing an exception in hook_theme() is going to mean it's impossible to render a page until the bug is fixed. Personally that works for me given this can only happen when a module is in development but we need to figure out what we're doing in these cases. Would be good to discuss this a bit more.
Comment #67
derhasi CreditAttribution: derhasi commented@damiankloip, where do have that information from? The current implementation (calling views_get_plugin_definitions()) does not really say something about that. I do not find any code currently that states "provider" is filled in the definition for each plugin.
In addition we have still some Class documentation in Drupal\views\Plugin\views\PluginBase talking about modules and not providers. If there is an auto-fill of the provider for each plugin (generally in D8 Core or only in views?), using that module attribute might be obsolete.
Comment #68
damiankloip CreditAttribution: damiankloip commented@derhasi, as mentioned, this comes from the Annotation discovery, so take a look there (AnnotatedClassDiscovery). We have also already discussed the fact the the 'module' key is obsolete, as we're using provider (I've just added a novice issue to remove these).
Can we keep this focused on this issue? I've created two follow ups. Catch, this should take care of the concerns/discussion about the exception throwing? So I think we should commit #60, and put this issue to bed.
#2070609: Remove obsolete "module" keys from Views plugin annotations
#2070613: Figure out error handling in views_theme
Marking back to RTBC as per #61, if anyone is unhappy with this, feel free to change back.
Comment #69
damiankloip CreditAttribution: damiankloip commentedbah
Comment #70
derhasi CreditAttribution: derhasi commented@damiankloip, thanks for pointing me in the direction. I will have a closer look there. ... and for opening the two issues.
+1 for resolving this ticket with #60
Comment #71
catchWorks for me. Committed/pushed to 8.x.
Comment #72.0
(not verified) CreditAttribution: commentedblub