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.
We need to implement a Drupal 8 style plugin type. These will be optionally used to style a block or region before passing the output to the layout plugin when rendering the variant.
This will allow us to start porting D7 style plugins to D8!
Sandbox branch
http://cgit.drupalcode.org/sandbox-dsnopek-2290237/log/?h=styles-2296437
Comment | File | Size | Author |
---|---|---|---|
#90 | panels-implement_style_plugin-2296437-90.patch | 35.33 KB | Rory Downes |
#89 | panels-implement_style_plugin_2296437-89.patch | 56.65 KB | Rory Downes |
#77 | interdiff-2296437--63-77.txt | 4.52 KB | drclaw |
#77 | panels-implement_style_plugin-2296437-77.patch | 59.05 KB | drclaw |
#64 | interdiff-2296437--62-63.txt | 13.64 KB | drclaw |
Comments
Comment #1
dsnopekComment #2
rlmumfordI've been doing some work towards this. Will get a patch up asap.
Comment #3
dsnopekAwesome! I'm looking forward to seeing it. :-)
Comment #4
rlmumfordThis code is just experimental. (I haven't tested anything yet).
It's written to depend on fregas layout module. Hopefully it will provide a very rough starting point to move forward from.
Comment #5
dsnopekIn the layout issue (#2296431: Implement layout plugin type (or get it from somewhere)), we're now depending on frega's 'layout_plugin' sandbox. I've re-rolled this patch to depend on those changes and committed it to the 'styles-2296437' branch on the 'd8panels' sandbox:
http://cgit.drupalcode.org/sandbox-dsnopek-2290237/log/?h=styles-2296437
Currently, this still doesn't actually work, due to the issues in the layouts branch which will need to get fixed first. But I wanted to get this work into the sandbox right away.
NOTE: This patch is against the layouts branch in #2296437: Implement style plugin type - this won't apply against Panels 8.x-3.x or d8panels 8.x-3.x.
Comment #6
andypostsuppose plugin.manager.panels.style is a proper name
Comment #7
rlmumfordHere's an updated patch, no inter-diff because most of it is from scratch. Added a style dialog to both regions and blocks on the edit page. Allowed a choice between two plugins, Default and List. Next step is to add settings to the dialog so that style plugins can be configurable.
Changed the plugin name to panels.style, as per comment #6.
This applies against d8panels.
Comment #8
dsnopekComment #9
mglamanPatch is not applying anymore for me. I'll try again within PhpStorm and see if it pulls some magic and re-roll.
Comment #10
dsnopekWe've also had a couple of discussions where we talked about doing style plugins in CTools instead, and allowing them to apply to any block, not just blocks used in Panels. Of course, in Panels there also need to be region styles which might make sense as a completely different concept? Or can we have those apply to theme regions as well?
Comment #11
mglamanMoving the concept of styles to ctools so it can be abstracted and used across the Block system is pretty nifty. I unfortunately read #10 after fixing patch :) Had issues in code.
Sounds like, though, regions would just be an annotated extension of styles.
Comment #12
stevectorI saw some twitter discussion about style plugins: https://twitter.com/dsnopek/status/661527359619600385
I agree with David that it is a good idea for style plugins to simply change the theme hook on the block. The same concept could be applied to regions. Does this issue need to switch to the CTools queue?
Comment #13
stevectorTo clarify, David, do you think the theme hook would change from 'block' to 'my_style_plugin' or do you mean using suggestions so 'block' becomes 'block__my_style_plugin'?
Comment #14
dsnopek@stevector: Hm. I'm not sure! The theme suggestion approach seems like a good idea. But either would work from my perspective. So long as we're changing the '#theme' on the block, rather than wrapping the block in something, that would be best!
Comment #15
japerryIRC convo today with EclipseGC:
Now that panel panes are blocks, there is a much better argument that the implementation of styles should be done in ctools, and that other modules (like classy panels styles) can extend the ctools implementation.
How does this sound?
Comment #16
swentel CreditAttribution: swentel commentedI guess as long as we can pass in other variables which can be configured on the style form, that all sounds good to me. If not, that would be a regression for us the way that we use styles in D7 on panes.
Comment #17
Shawn DeArmond CreditAttribution: Shawn DeArmond as a volunteer commentedIs this issue still valid since the Block Styles module exists?
Comment #18
rlmumfordThats a good find! It solves one of the two uses for the panels style plugins. Panels style plugins also allow you to choose a particular style for a region. That said, we should look at building those plugins on top of the styles API
Comment #19
andypostToday faces with absence of styles) thought to implement a-la https://www.drupal.org/project/panels_accordion
Here's a code/implementation review of patch #11
The main confusion is inability to separate plugin's availability/applicability for each kind of build (region and block)
Suppose they need separate interfaces
Plugin should expose something
static::getBuilders()
or define in annotation "no_block|no_region" to be faster (prevent classloading)Also plugins could have "settings form" to be exposed somehow, nice to have one example (List type: ul/ol)
So overall is good starting point
PS: https://www.drupal.org/project/block_styles looks interesting
trailing whitespace
need to be removed
Any reason for separate method?
why not $this->block->uuid()?
better to inject
I think default implementation should be "naked"
so default will not be empty
This leaves no way to implement a region-only style... suppose regression
Probably there should be only one static method **getBuilders()**
Anyway there should be separate interfaces for each type of builder.
Also plugin abilities cound be pointed in annotation so no reason to instantiate plugin to decide applicability of plugins to panel part.
We can't wrap block into list?
So plugin implements default block builder from base implementation?
Suppose this plugin should be only for region that means not-applicable to block!
Any reason to have empty interface?
Comment #20
josebc CreditAttribution: josebc at Vardot commentedCurrent patch is really old, I managed to make it work with blocks by re-rolling - kindoff - the previous patch from mglaman to work with the new version.
please note that this still needs lots of work and review (sorry im not that familiar with panels code)
Comment #21
josebc CreditAttribution: josebc at Vardot commentedre-roll with support form regions styles
Comment #23
sylus CreditAttribution: sylus commentedThis is awesome, thanks so much :)
I fixed up the testing issues with PanelsDisplayVariantTest.php so only the StandardDisplayBuilder.php remains. I am still learning prophecy but with regards to the following:
Can this be mocked with Prophecy or is it a Demeter violation?
Comment #24
sylus CreditAttribution: sylus commentedCorrect patch.
Comment #25
sylus CreditAttribution: sylus commentedComment #28
sylus CreditAttribution: sylus commentedOne more try, sorry for the noise!
Comment #30
sylus CreditAttribution: sylus commentedDown to three errors in StandardDisplayBuilderTest.php
Comment #32
sylus CreditAttribution: sylus commentedUpdating patch to latest panels dev / 8.x-3.0-beta5.
Comment #34
brunodboComment #35
csedax90 CreditAttribution: csedax90 commentedAfter applied the patch #32 to latest stable module version, drupal said:
Class 'Drupal\panels\Plugin\PanelsStyle\PanelsStylePluginManager' not found
Comment #36
FeyP CreditAttribution: FeyP at werk21 commentedI made some changes on top of patch #32 so that style plugins could provide custom settings again. Attached is a patch against 8.x-3.x-dev and an interdiff between patch #32 and this patch. Let me know what you think.
Comment #38
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedFix remaining errors in StandardDisplayBuilderTest.
Comment #39
andypostSkimmed last patch and I think "base" should be moved to "default"
needs to be added
needs to be removed
https://www.drupal.org/docs/develop/standards/coding-standards#indenting
Comment #40
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedThanks for your review @andypost! I fixed the CS issues.
I'm not convinced, that we should really do this. While I just built on-top of what's already been implemented by our fellow community members, it seems to be a common pattern to have a base plugin for all plugins to extend and a default class that extends it as the default plugin, even if it means, that the default plugin class is basically empty. Since there might be a point in the future, where we might want to add code to the default plugin without changing the base plugin, this doesn't seem as weird to me as it might look at first. But let's just wait a bit and gather a few more opinions. If at the end the consensus is to move, it's fine with me.
Comment #41
andypost@FeyP I know that's a common pattern but I still not sure it's good idea and #2296423: Implement layout plugin type in core takes different approach
Comment #42
sylus CreditAttribution: sylus commentedShould this still be tagged as needs review? Tests are passing and looks like it was reviewed by a few people including myself. Perhaps we should switch this to RBTC or is there still something missing?
Comment #43
jwineichen CreditAttribution: jwineichen commentedWhen I try to apply this patch, I get a hunk failed message when it tries to patch the StandardDisplayBuilder.php file. I only kinda know what I'm doing so I'm not sure what that means.
Comment #44
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedThere was a new release 2 days ago so the patch probably doesn't apply any more and needs a reroll. I'll try to prepare that asap, thanks for the heads up.
Comment #45
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedOk, obviously there was no new release 2 days ago, I was looking at the wrong branch ;). But the patch needed a reroll none the less. So here we go...
Comment #46
andypostthis needs config schema for this properties
$layout var is undefined
better define proper interface expecting style as PanelsStyleInterface as function argument
public probably should be defined in interface
Comment #47
DamienMcKennaLets consider this for the next beta.
Comment #48
samerali CreditAttribution: samerali as a volunteer and at Lechleider Mitchell LLC commentedWhat about D8.3 & Panels v4 support. these patches are actually against the old layout_plugin module.
We probably need to change all layout_plugin references to D8.3 & V4 of the module.
Comment #50
jorgik CreditAttribution: jorgik as a volunteer and at AnyforSoft, Drupal Ukraine Community commentedComment #51
jorgik CreditAttribution: jorgik as a volunteer and at AnyforSoft, Drupal Ukraine Community commentedHi, I've re-rolled last patch for 8.x-4.x-dev
Patch is working great, but 1 test are failing, because we have http://joxi.net/vAWl0Y5ikg3ydr.jpg this issue https://www.drupal.org/node/2867795
Comment #53
DamienMcKennaComment #54
jorgik CreditAttribution: jorgik as a volunteer commentedComment #55
drupov CreditAttribution: drupov commentedNew re-roll against latest dev (commit dd6e30d).
Leaving this at "Needs work", because of the tests fail, as mentioned in #51
Comment #56
drupov CreditAttribution: drupov commentedFixing tests.
Comment #57
drclaw CreditAttribution: drclaw at Fuse Interactive commentedThought I would take a stab at fixing the tests on this one, but also made a few tweaks:
Patch is attached with an interdiff. I may have fixed the outstanding test fail as well, but we'll see if testbot agrees.
Something doesn't feel right about having the StylePlugin responsible for rendering regions and blocks. As we can see with the List style plugin, sometimes we'll want them to just render one or the other. But the interface forces defining both build methods. In the very least I think we need to break up the interface into one for each type (block, region) which plugins can then choose which ones to implement based on where they want to be available. Or one further would be to just have separate plugin types for each (although from reading the comments above this may introduce some kind of regression / backwards compatibility issues?)... Anyway, for now I haven't made any major changes like that. I figured it would be worth some discussion at least before pursuing any major rewrites.
Comment #58
drclaw CreditAttribution: drclaw at Fuse Interactive commentedUpdated config schema and added config to support setting the default panels styles (was previously hardcoded to "panels_default"). No settings page yet so it has to be done through
settings.php
. I can do a settings page up, but was hoping to get a patch review before proceeding too much further :)Comment #59
andypostNot sure this change needed, it's a implementation details for plugin to implement this methods
Instead of this settings better to add fallback plugin
this makes every plugin to implement configuration form but some styles could have no settings & forms
they also could be a container params but I think fallback plugin more predictable
Comment #60
andypostExample of fallback plugin #2249303: Implement fallback plugin for Block plugins
Comment #61
drclaw CreditAttribution: drclaw at Fuse Interactive commented@andypost Thanks for the review!
RE: PluginFormInterface & Item #2 in your comments
I think it is needed since
buildConfigurationForm
,validateConfigurationForm
, andsubmitConfigurationForm
are all being called in\Drupal\panels\Form\PanelsBlockConfigureFormBase
. Whether or not the plugin has a form or settings doesn't really matter, they still need to define these methods since they'll always be called when the plugin is selected.It's possible there's a different pattern we can use here, but I feel like this is pretty similar to how other plugins handle optional forms. Field formatters for example do pretty much the same thing (@see Drupal\Core\Field\FormatterBase). Thoughts?
RE: Fallback Plugin
I quite like the idea of a fallback, but I think it's different than my intention with the default settings. The default plugin settings are so you can set which plugin is selected by default when adding new blocks / editing regions with no settings yet. The panels_default plugin doesn't really do anything so I could see people wanting to set their own default (myself included).
However, a fallback plugin for when a previously configured plugin no longer exists I think is a good idea. I'll get working on that one this week.
Comment #62
drclaw CreditAttribution: drclaw at Fuse Interactive commentedNew patch with fallback plugin so we don't WSOD when a style plugin goes missing. Currently falling back to rendering the region/block using the base class. Not sure if that's the best way to go but it seems better to me to render something rather than nothing? Missing plugin message is logged.
Comment #63
andypostThat looks like some nitpicks left but overall great!
not sure that related to scope of the issue
This logic could be simplified if style manager can accept empty plugin ID and resolve it to default/fallback inside manager to hide implementation
not sure that useful, other plugins can't call parent with this defaults
is there useful trait in core for that or maybe base class
makes sense to add variant name somehow to help debug it
$this->t()
needs $this->t()
no reason for isset()
Comment #64
drclaw CreditAttribution: drclaw at Fuse Interactive commentedThanks again for the review!
Drupal\Component\Utility\NestedArray::mergeDeep()
label()
method on the PanelsDisplayVariant class to support this... it feels a bit overreaching but isn't necessarily outside the realm of modules supporting each other without explicit dependencies so I can live with it I think...Comment #65
jorgik CreditAttribution: jorgik as a volunteer commentedThe last patch works fine for me. Thank you Chris
Comment #66
drclaw CreditAttribution: drclaw at Fuse Interactive commentedI'm wondering now if the settings for default block/region styles should actually be set on the variant rather than a global setting? Could be more flexible for more complex editing interfaces that make use of the IPE...
Comment #67
ericmulder1980 CreditAttribution: ericmulder1980 as a volunteer commented@drclaw i would think it makes more sense to apply block block/region styles to the variant rather than adding it globally. Even better would be if you could set a default in global but would be able to override it on the block instance level.
In my specific use case, using the IPE, users never touch the global panelizer configuration but only place blocks on predefined templates. There are some defaults but further from that users are free to place custom block types (text, image, video) and even place multiple instances per block.
I'm afraid i won't be of much help programming this but am willing to review, test and document this feature.
Comment #68
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commentedLooking through this.
Does the base style (and by extension, the default style) really need the "container" class added? This could potentially cause problems for anyone using a bootstrap-based theme. I think expected behavior would be that the default style does nothing, and then other style plugins would actually make modifications.
Comment #69
dbjpanda CreditAttribution: dbjpanda commentedI am getting this error after applying #64
Comment #70
tim.plunkettI'm sure #68 contains copy/pasted code, but it reminds me of #2934223: layout_builder module has a hidden dependency on block module:
'#theme' => 'block'
only works if block.module is installed, and Panels doesn't depend on it.Comment #71
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commentedI brought my question in #68.3 to the weekly #layouts meeting on slack. Based on the discussion, I thought it prudent to post the full conversation here, as the general opinion seems to be around getting better support for styles in core itself.
I'm not entirely sure what the next course of action is here, but I'm just documenting this for maintaining a record of that original conversation.
Comment #72
drclaw CreditAttribution: drclaw at Fuse Interactive commentedThanks for your points in comment #68 and for posting this @WidgetBurritos!
So it kind of sounds like the maintainers are leaning towards a higher-level solution, probably with some core changes, which means it could be a little while before we see it. Also if the final solution for Panels ends up being related to those changes, it makes for an awkward migration for anyone using this patch to whatever that looks like.
So, if we're going to have to wait for upstream changes before being able to do styles in the panels module, I wonder if what we're doing in this patch is better suited for contrib for the time being? I _think_ we can do everything for panels block styles through alter hooks. The only thing we can't alter is the panels regions output, but maybe we can get a small hook put in for that for now... The advantages I see in doing this in contrib are:
I'd be willing to give it a shot in a separate module but would like to hear what people think before diving in too deep... Also I may be overlooking some major thing that makes doing this in contrib impossible/illogical/insane :)
Comment #73
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commented@drclaw I definitely think most of this could live as a separate contrib module, although I'd have to reevaluate everything that's happening in the patch. I'd be willing to do some work with you on this. Perhaps a sandbox module for now?
Comment #74
dsnopekI haven't looked at the more recent implementations on this issue, but in D6 & D7 in practice, most style plugins just swap out the theme hook. So, a style plugin relating to the theme hook used (which is kinda what it sounds like in #71) sounds about right to me.
Comment #75
mohammed76has anyone started working on a contrib solution?
Comment #76
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commented@mohammed76 Unfortunately I have no not had a chance. I can't speak for the others.
Comment #77
drclaw CreditAttribution: drclaw at Fuse Interactive commentedHere's a re-roll of the patch with added block hooks to better support quickedit, contextual links etc.
On another note I'm planning on tackling the contrib solution in a the next month as I have a project that's going live in July that needs it (they don't want a patch this big looming on their live site). Will keep this thread updated with progress!
Comment #78
drupov CreditAttribution: drupov commentedTested #77 - everything seems to apply and work fine. See the repo - https://github.com/drupov/d8-panels and check out
branch "2296437-implement-style-plugin" there.
A question: how can a custom style plugin be created then (in a custom module)?
Comment #79
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commented@drclaw @mohammed76 FYI: It does appear someone has already taken this patch and created a module out of it:
https://www.drupal.org/project/panels_extra_styles_d8
I'm not exactly sure how up-to-date it is with the patches in this issue, but might be easier to patch that module, than maintain a massive panels patch.
Comment #80
drclaw CreditAttribution: drclaw at Fuse Interactive commented@WidgetsBurritos Looks like that module is actually just a StylePlugin that depends on the patch in this issue. It doesn't add the style plugin functionality itself.
Haha at first I was like "phew, that's gonna save me some time!" :P Oh well, starting on this tonight so hopefully I'll have something working soon!
Comment #81
WidgetsBurritos CreditAttribution: WidgetsBurritos at Rackspace commented@drclaw, my bad. I misread that description, and didn't investigate it too closely. Sorry about that.
Comment #82
drupov CreditAttribution: drupov commented@drclaw - you're the best!
Comment #83
jorgik CreditAttribution: jorgik as a volunteer commentedHi, @drclaw do you need some help according to your contribution solution?
Comment #84
drupov CreditAttribution: drupov commentedThis seems to works pretty neat. I've updated the repo https://github.com/drupov/d8-panels - check out branch "2296437-implement-style-plugin"
git clone -b 2296437-implement-style-plugin git@github.com:drupov/d8-panels.git
and follow the installation steps to see it in action.There is a custom module d8_panels which demos the creation of a custom style plugin ("wrapper"). The code is inspired from panels_extra_styles_d8, but has some improvements and the idea is to show how to make a plugin standalone, without an additional module. There are custom configurations on it and it uses a twig template for the output. Of course based on the latest patch form #77. See the "/test" path in the installation for a demo of a wrapped region and pane (even with title wrappers) on a custom panelized page manager page:
https://ibb.co/kbAM9d
One this is a bit buggy: when I open the pane configuration form for a pane the custom style plugin is not recognized. Switching to default and back to wrapper then shows all the configuration settings:
https://ibb.co/jERiNy
Should we set it to "Needs review"?
Comment #85
drclaw CreditAttribution: drclaw at Fuse Interactive commentedFor anyone wondering about the contrib solution, I've got a sandbox going with a mostly working version https://www.drupal.org/sandbox/ceastwood/2981033. It's not quite ready yet for testing as I'm still ironing out some kinks, but the bulk of the patch port is done. Will post again when we're ready for testing, just wanted to update in case anyone was wondering if I actually was doing anything :)
Comment #86
drclaw CreditAttribution: drclaw at Fuse Interactive commentedI think the contrib solution is ready for testing. https://www.drupal.org/sandbox/ceastwood/2981033
For anyone that has been using the patch in this issue, there are notes on how to migrate in the readme as well as on the sandbox project page. The tl;dr is that your config should be migrated automatically, but you'll need to refactor your style plugins.
Thanks!
Comment #87
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedThanks for taking the time to create the sandbox module. I've installed it on one of our sites to replace the patch and so far it's working great.
Comment #88
NWOM CreditAttribution: NWOM commentedThank you everyone for your work on this! I managed to get it all working after making a few patches
Currently Panels Extra Styles D8 depends on the patch, rather than the contrib module, and neither module is compatible with D9 (while Panels Style isn't compatible with anything over D8.5).
Here is a compilation of everything I am using in order to get both modules working together and for D9 compatibility.
Panels Style
#3031437: Error when region style set to default
#3062867: D8.5^/D9 compatibility - User temp store moved to core
#3179208: D8.7^/D9 compatibility - ConfigurablePluginInterface is deprecated
#3179124: D9 Version Requirements
Panels Extra Styles D8
#3179234: Use Panels Style contrib module as a dependency rather than Panels patch
#3179230: D9 Compatibility
I hope this helps others as well!
Edit: I may have spoken too soon. I cannot save block configurations currently due to the errors mentioned here: #3062867: D8.5^/D9 compatibility - User temp store moved to core.
Comment #89
Rory Downes CreditAttribution: Rory Downes at Big Mallet commentedHi,
I have a Drupal 8 site using the patch in #63. However, when converting to Drupal 9 I get an error from drush:
In YamlDiscovery.php line 24:
/var/www/rory2.bigmallet.bigmallet.co.uk/web/modules/contrib/panels/panels.routing.yml: Duplicate key "panels.region_edit_style" detected at line 36 (near " _c
tools_access: 'machine_name'").
In YamlSymfony.php line 40:
Duplicate key "panels.region_edit_style" detected at line 36 (near " _ctools_access: 'machine_name'").
In Parser.php line 335:
Duplicate key "panels.region_edit_style" detected at line 36 (near " _ctools_access: 'machine_name'").
I find that the patch in #63 adds three duplicate sections for panels.region_edit_style. I am presuming that this is an error and the Symfony upgrade included in Drupal 9 is rejecting this. To this end I have re-rolled that patch with just one added and attached in case it helps anyone else.
The same could be done for the patch in #77.
Regards Rory
Comment #90
Rory Downes CreditAttribution: Rory Downes at Big Mallet commentedSorry, but the patch file I just submitted in #89 was corrupted. The replacement does work.
Regards Rory