Problem/Motivation
In page_manager, there is a concept of a "variant". Usually used with "pages", they can be used to provide alternate configurations and are selected based on certain conditions.
For example, they can present different configurations of blocks to users with different roles.
Usually they collaborate with a layout, and are stored by an entity.
However, they are standalone plugins, and can be instantiated directly, and can choose to not hand off to a layout.
In contrib, these can be used by modules like Panels, Context, Panels Everywhere, Panelizer, and possibly even Display Suite.
This way, both Blocks and contrib "replacements" will use the same API.
Proposed resolution
Add the basic interfaces and plugin manager for variants.
Write a "Full Page" variant and use it to replace the internal logic of block_page_build(), block_list(), and block_get_blocks_by_region().
Remaining tasks
N/A
User interface changes
N/A
API changes
API addition:
New plugin type
API change:
Removed block_list() and block_get_blocks_by_region().
| Comment | File | Size | Author |
|---|---|---|---|
| #27 | interdiff.txt | 6.86 KB | tim.plunkett |
| #27 | variant-2286357-27.patch | 28.2 KB | tim.plunkett |
Comments
Comment #1
tim.plunkettHere it is. There are some things that might be overkill/leftover from page_manager, but the changes to block.module are the exciting part.
Comment #2
larowlan+ return \Drupal::service('uuid'); +The full page variant could override this and inject the uuid service, it already implements container factory plugin interface
Looks great
Comment #3
tim.plunkettFair enough!
Comment #4
tim.plunkettOkay, talked over with @EclipseGc, and we agreed to remove the block and region handling. Not all variants will need it.
This should be the bare minimum.
Since I was essentially just deleting code, an interdiff wasn't really possible.
Comment #5
tim.plunkettInjected the view builder, and cleaned up/expanded the unit tests.
Comment #6
tim.plunkettRerolled for hunk conflicts after #2278541: Refactor block visibility to use condition plugins
Comment #7
jibranclass doc missing.
Comment #8
tim.plunkettAdded a doc block, and injected the theme negotiator instead.
Comment #9
eclipsegc commentedI don't see anything in here that makes me think we shouldn't commit this now.
Eclipse
Comment #10
moshe weitzman commentedLooks good. The @Annotation and @inheritdoc blocks make me want to poke my eyes out but that's not invented here.
The method should be called 'build'. We have been careful in the past to reserve the word render to refer to the process of turning a render array into HTML. In this case we are building the render array, not rendering it.
Comment #11
tim.plunkettFair point, thanks @moshe weitzman!
Also noticed a stray comment about block_list().
Comment #12
tim.plunkettIt's been a long week.
Comment #14
eclipsegc commentedStill RTBC.
Eclipse
Comment #15
benjy commentedAwesome, I like this issue. :)
Do we need this if it's empty?
Comment #16
tim.plunkettIt's a nice thing to have, to ease the burden of subclasses. See the other base classes implementing PluginFormInterface, or even FormBase.
Without that, then every variant would need an empty validate method.
Comment #17
dawehnerProbably this patch should have been waved through, in that case sorry. Can we please add a tag for that?
Nothing in this patch explains what a display variant actually means.
Is there a reason why the account is not passed in here? This seems to be something which could be done in a follow up,
but why should we ... this patch introduces new code already.
OT: Did we ever considered to move the namespace, annotation class, cache key and alter hook name into parameters in the service definition?
Don't we no longer sync the namespace in the actual code and in the tests?
Doesn't the theme negotiator provides its own caching? One less variable is one less possible static caching bug.
If getRegionAssignments() would document the return array the inline docs would not be needed ...
Should we better document why we have to hide errors here? This does not seems to be obvious for me.
Missing @covers annotations.
Can't we use the interface? This might be a leftover from my previous fuckups.
Comment #18
tim.plunkett5) I cannot write \Drupal\block\BlockInterface[][], double nesting does not work.
9) getActiveTheme() is not on the interface
I can clean up some of the other bits tomorrow, but I believe they are minor.
And I don't know what you mean about waving this through.
Comment #19
tim.plunkett1) Fair
2) Fixed
3) No, but that's an interesting idea.
4) Fixed
5) Fixed
6) As I said, I wish I could do \Drupal\block\BlockInterface[][] but I cannot.
7) Because PHPUnit invocation matching triggers https://bugs.php.net/bug.php?id=50688 :(
8) As I said, getActiveTheme() is only on ThemeNegotiator, not on ThemeNegotiatorInterface.
Just minor clean ups, still RTBC.
Comment #20
andypostIs API change, also leaving no API to get regions and their blocks
admin label better to wrap in t()
Comment #21
tim.plunkettThose were not API functions to begin with, and you can still get regions and blocks the normal way, see system_region_list and entityQuery.
To your second point, it's in *.api.php , doesn't matter.
Comment #22
dawehnerNot sure how fair this is tbh. Drupal people have a massive amount of missuage of all the "API"s.
Is there a chance we document that?
Comment #23
berdirOT: Did we ever considered to move the namespace, annotation class, cache key and alter hook name into parameters in the service definition?
Yes, this was considered and discussed in Portland, whThiere I worked on DefaultPluginManager. However, the needed arguments were a bit more complex back then (an array), and it was not possible to have everything in services.yml, and @yched was against splitting this up.
Seems like it should be possible not, would be quite nice. We would have to make those methods public, though, I think they are protected right now.
Comment #24
tim.plunkettI will write a change notice for those two functions.
Added a comment about the @uasort.
A new issue for #23 would be worth looking at, but is really OT here.
Comment #25
tim.plunketthttps://www.drupal.org/node/2291171
Comment #26
wim leersHaving worked quite a bit on
BlockViewBuilderand touchedblock_get_blocks_by_region()etc., the overall approach and changes in this patch look great!Comment #27
tim.plunkettReroll for the RouteMatch commit. This now addresses #17.5, since we're using the interface directly.
Also, we now have a core.api.php for subsystems, so I moved the hook docs there after checking with @jhodgdon.
Comment #28
tim.plunkettComment #29
webchickSpent a good hour on this with Tim, mostly with docs. The patch itself is pretty straight-forward... it introduces a new concept of a "display variant" and uses one of them ("full page") to render out full page views from Block module, in lieu of calling functions like block_get_blocks_by_region(). Apart from that change it's 90% copy/paste boilerplate code that you need to implement a plugin, and then tests.
We struggled with the docs of "display variant" for awhile though. It's tricky because core doesn't (yet) use the concept of displays; that may come or not as a result of #2292733: [meta] Introduce Display objects. And display variants themselves are incredibly generic, and can be used for everything from a full page display ala Block module to a single "block" content ala mini panels to even a simple http response code type of deal. In the end, we settled for a description of what HEAD does with this patch as an example, and kind of left it at that. I think that's enough for someone who comes across this term and says "wtf?" to have a reasonable shot at being directed how to read up on how it works, and this entire description will get overhauled anyway when/if the display issue makes it in, so didn't make sense to go from 80% => 100% in this case.
Apart from that, the only things that stood out to me were the losing of some "orientation" comments around the removed code in block_page_build (restored a one-liner there) and the @uasort thing that's already been mentioned above, but that's got docs next to it explaining what's going on.
This is a nice change overall that's not very invasive on its own, but nevertheless introduces some very nice flexibility that hopefully all of the various "core block/layout replacement" modules out there can make use of, without each inventing their own wheels. Change notice looks fine.
Ergo, committed and pushed to 8.x (with some docs modifications). Thanks!