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
Currently, a variants configuration is part of the Page config entities configuration.
This makes life a little difficult for a couple reasons:
- Variants have two part IDs: the page id, then the variant id or uuid. This means all the UIs need to pass around the page id, which, if the UI comes from the display variant plugin - shouldn't need to know the page id! See #2511570: Remove Drupal\page_manager\Plugin\PageAwareVariantInterface
- Currently, page manager works around this by making the variant aware of Page, which then couples the variants to Page Manager. But we might want to use the same display variant plugin (for example, the Panels varaint) outside of Page Manager, for example, on a Mini Panel or in Panelizer.
- We can't provide a single variant as part of a Feature
Proposed resolution
Make variants into their own independent config entity!
Remaining tasks
Extract the variant config entity stuff from the wizard patch at #2550879: Use CTools Wizard API to add/edit Pages (and move plugin UI using PluginWizardInterface)- Get current tests all passing
- Add new test coverage for new code
- Review
- Commit
User interface changes
None.
API changes
Lots.
Data model changes
Yes.
Comment | File | Size | Author |
---|---|---|---|
#88 | 2551633-pm-88.patch | 166.43 KB | tim.plunkett |
#88 | interdiff.txt | 11.85 KB | tim.plunkett |
#87 | 2551633-pm-87.patch | 165.97 KB | tim.plunkett |
#87 | interdiff.txt | 1.62 KB | tim.plunkett |
#83 | interdiff.txt | 30.65 KB | tim.plunkett |
Comments
Comment #2
dsnopekI was working on this most of yesterday and it's turning out to be a bit trickier than I thought. But I hope to have a patch up today! Assigning to myself so no one else starts working on it. :-)
Comment #3
dsnopekHere's my first pass at this patch. I extracted the page variant entity stuff from the wizard patch, then attempted to get it working with the existing page_manager UI (so that wizards could just be about wizards).
However... this was super hard. It's kinda working for adding and editing variants, but not much else.
I think the key to making this into an easier patch might be to remove even more stuff, and marshall stuff in/out of the page variant entities. We could then make some of the bigger refactors along with the wizard changes, or as another incremental step.
Comment #4
BerdirI'm not sure I understand the point of this.
As long as variants still have a hard dependency on the page (and I don't see how they could not, with static and route-based contexts in blocks, just to name one example), I'm not sure what we gain by making it separate.
I do see a number of downsides however, it makes dependencies more complex as you have a cross-dependency between the two, that's something the config system can't really handle. If a variant depends on the page and the page on the variant, which one should a config import going to import first?
Comment #5
dsnopekMy main goal is to decouple display variant plugins from the Page entity. In this new model, the page variant entity would be coupled to the Page entity (and the UIs would apply to that) and the display variant could hopefully be made blissfully unaware of the Page. :-) This will be important if we want to use the same display variant plugins for non-page things, like Mini Panels and Panelizer (the view modes, not the full page override).
However, there are some other benefits that EclipseGC is going for! The Features one mentioned in the issue summary is one. I'm pretty sure there are others, but I don't recall them at the moment - hopefully, EclipseGC can jump in on that. :-)
Comment #6
dsnopekI tried to make the issue summary a little clearer.
Comment #7
BerdirYes but again, I don't see how the display *can* be unaware of the page. Haven't look at the patch yet, but i don't see how you intend to deal with the context problem? And when it's not, then the single-variant feature is kinda pointless since it won't work ;)
We created a module called widget which is basically mini-panels as a block and we are still using an old branch of the layout project for that, one of the things that it has there is https://github.com/md-systems/layout/blob/old/src/LayoutRendererBlockAnd..., which in turn uses https://github.com/md-systems/layout/blob/old/src/Plugin/Layout/LayoutBl...), a very simple and generic interface that abstracts the concept of something that provides blocks, regions and context that is then rendered into a template.
Might be considerable easier to bring such a concept into ctools and then just use that in BlockDisplayVariant? See https://github.com/md-systems/widget/blob/master/src/Plugin/Block/Widget... how our usage of that looks like.
Comment #8
BerdirTo be fair, I'm also worried about the fact that we are using page manager in production and such a massive change would result in considerable effort for me to write an upgrade path for our configuration.
But if everyone else thinks this direction makes sense and actually *works* (having variants that do not depend on the page in any way in the end) then don't let me hold you back. I'd just like to avoid a situation where we do all this refactoring and then in the end don't actually gain anything from it.
Comment #9
dsnopekThat project sounds really cool! I'll definitely check it out when I have a chance. :-)
Well, we did it in Drupal 7 using a similar architecture. In D7, we had the 'page_manager_handlers' table which was essentially the "page variant entity" which was coupled to to 'page_manager_pages' (basically, the Page entity). Then the 'panels_display' table held the configuration for the Panels variant (so, the display plugin configuration).
This patch doesn't do any of the actual decoupling yet - just trying to make the Page entity and Page variant entity separation.
I think we'll need to finish #2511570: Remove Drupal\page_manager\Plugin\PageAwareVariantInterface and #2511568: Create "context stack" service where available contexts can be registered before we can really decouple things.
Comment #10
dsnopekUnassigning - I don't think I'll be able to get back to this today
Comment #12
EclipseGc CreditAttribution: EclipseGc commentedGetting involved to help push this forward ideologically.
The primary benefit is actually #3 in the issue summary. Node routes (as an example) have a long history of having variants introduced by feature plugins. When you take over node/{node}, and then you require a single module to own all variants, you're limiting your ability to introduce new node types and corresponding variants for them, which will make site-building an absolute pain, much less more generic site-building attempts.
Likewise, while I'm not certain that variants will be useful for mini-panels, they definitely share a lot of architectural overlap with panelizer (and a little overlap with mini-panels), so moving to this more abstracted feature element will likely result in a "DRY"er solution.
Finally, @berdir specifically, I feel your pain about upgrade path. While I am uncomfortable with so many people using the current page_manager implementation in production D8 sites, I recognize it's happening. Regardless of that, we can't let that fact retard progress on the D8 branch of page_manager, and its current UI and arch was Tim's effort to get SOMETHING, but I don't think anyone wants to maintain (or deal with) the current code in its current form for the next however many years. However, we should probably make a concession to reality here and commit to providing an upgrade path for this change. I've been debating that for a while, and I'm leaning toward including one.
Eclipse
Comment #13
BerdirThanks for responding.
Don't worry too much about my upgrade path worries, I'm aware of the risk of using page manager in the current state and will deal with it. The upgrade path doesn't need to happen here, it could be added later once someone actually needs to do and test that (It won't work anyway otherwise ;)).
My main point is that I'm not sure that we're fully aware if the implications of this and we should test scenarios like config deployments, define who depends on whom and how things like static and route based contexts are supposed to work if a block in a variant uses it, as they are provided by the page at the moment (static could move I guess, route based not so much...)
Comment #14
EclipseGc CreditAttribution: EclipseGc commentedRight, so I can describe how that should work, and as we refactor, if we find that our current reality doesn't match what I describe, we need to change it.
In the case of context injection into plugins (since that's the lion share of your argument/question) it should be irrelevant where the context originates. If a page has defined routes (or takes over a route) with arguments we're upcasting into contexts, those contexts should be injected into the variant entity when executing it. As a practical example:
say we take over the node of type "article" display on /node/{node}. We'll get a node from the route, and the page knows about this. The page then loops over the variant entities it possesses. As it does so, it injects its contexts (from url parameters) into the variants. When we arrive at our "article" variant, the specific contexts relevant to this variant are loaded, our selection criteria are evaluated, and then our page is rendered. If we have a panel that renders something dependent upon the node from the url, this is not horribly relevant to the variant, because internally it maps it to a key by a name ('node' probably since it's {node}). In Drupal 7, we can take a variant from one page, and put it on another, so long as the parameters upcast from the url remain the same. Even if the key of the context were to change, Page Manager will try to guess at the correct context to use, which it does by matching the first context of the necessary type. This logic doesn't exist in the 8.x version yet, but long term should be on our road map. It's also useful for remapping plugin contexts when you remove a context from the variant's scope that had plugins mapped to use it (or when you change the url upcasting on a custom landing page).
TL:DR;
Contexts should be injected through out our process, we should never manually reach backward to the page specifically to get contexts. The plugin mapping that is saved into a variants configuration should be completely ignorant of WHERE its contexts came from.
Comment #15
dsnopekThis is a re-roll but I had to comment out some stuff and just put a @todo by it, so even less stuff works now. :-/ I'm really struggling with making this patch work! I'm tempted to just start over and copy in pieces of the original patch bit by bit as necessary, because there's just too much half working stuff in here that it's super hard to wrangle.
Comment #16
dsnopekI started attempting to re-build this patch piece-by-piece. Hopefully, this'll lead to something more working!
Comment #17
dsnopekOk! While this patch still has loads of problems and lots of things don't work, it does work more than any previous patch. :-) I also removed a bunch of forms and stuff that are really part of the wizard changes. This should be a much better base for work going forward!
Comment #18
tim.plunkettWhy the different path?
Why do we need to list page variants in isolation from their pages?
Out of scope
Comment #19
dsnopek#18.1: Good question! It was like that in the wizard patch. I see no compelling reason to have a new path - we should be able to move that back.
#18.2: Dunno! It was like that in the wizard patch. :-) I'd be fine with removing that.
#18.3: Actually, I think this is in scope and represents what changed. In HEAD,
$page->display_variants
is an array of arrays that is saved to the Page config entity. In the patch,$page->displayVariants
is an array ofPageVariantEntity
objects which isn't saved to the Page config entity - it's just used at runtime to store the entities.So, I can make an updated patch that fixes #18.1 and #18.2 - but I think that #18.3 should stay as it is in the patch.
Comment #20
dsnopekAlright, here's a patch that addresses #18.1 and #18.2.
Comment #21
dsnopekOops! Forgot the action link.
Comment #22
dsnopekThis gets the phpunit tests passing. However, the simpletest tests are still failing quite catastrophically. :-)
Also, I moved some methods from
VariantAwareInterface
directly on toPageInterface
now that those methods are coupled directly toPageVariantEntity
's - there really isn't much point to that interface as it is. (I do have some ideas for reviving something like it later to share between page_manager and panels_everywhere - but we can address that in CTools when the time comes).Comment #23
dsnopekUpdated the "Remaining tasks" a little bit. I'm going to try really hard to not work on this one any more today. My brain needs to recover. :-)
Comment #24
BerdirFirst real look at this...
Haven't seen anything else yet but this looks weird...
Again, only just started. But why is the reference from the display to the page and not the page that has a list of displays?
Config queries by default are slow, but if we do this, we should at least the optimized keys that it offers, see lookup_keys in Block entity.
the rename makes sense but doesn't seem like something that needs to be in this issue?
what are those routes exactly? and is the tempstore stuff really related to this?
You're looking for _entity_create_access: page_variant I think.
That doesn't sound right.
Interesting problem, should a new page auto-create a display, or should it do this at runtime. or just display an errror?
Define config dependencies (make the variant depend on the page) and drupal will do that automatically for you.
is it even valid to change a loaded variant as part of a page?
If yes, then save() is the wrong place for this, needs to be in post/preSave(). Consider save() a final method, since you could just call $storage->save($page)
Yeah. even if you cache it, this still has overhead, while a stored list of display ID's would just be a loadMultiple(). And wasn't one point of this to be able to re-use a display? that's not possible if it has a single, forced reference on a page?
This is very tricky because you don't know if the variant changed.. you might still have the page cached and it might use an old version of the variant. Probably have to load them again. But you might want to consider loading them only on-demand anyway.
You don't need a config prefix if it's identical to the ID. only if you e.g. want to shorten the config name to just page_manager.variant instead of page_variant.
You can define them as a config_export property in the annotation.
a bit strange name mismatch...
Comment #25
dsnopek@Berdir: Thanks for the review! However... I think you're looking at an older version of the patch. :-/ Your points 1, 2, 4, 6, 11 and 13 are all about things that were removed in my updated patches from this morning. Anyway, I'll look into the rest of the points when I come back to this and try to address them!
Comment #26
BerdirGrml, yeah, apparently. sorry :)
Comment #27
rlmumfordHow is this related to #2561963: Display Config Entity. It seems like there could be a lot of duplication of effort.
Comment #28
dsnopek@rlmumford: Well, they both involve making new config entities, but they aren't duplicates!
#2561963: Display Config Entity is an internal implementation detail of the Panels module, designed to make it easier for other Panels-dependent modules to reuse it's display variant (ie. panels_everwhere, panelizer, mini-panels, etc). It's basically an improvement on the Panels API.
Effectively, this means that the variant configuration that gets stored on the page variant entity (which we're creating in this issue) for Panels display variants will just be a reference to the Panels display config entity that's created on #2561963. But that's Panels' business - Page Manager doesn't care. :-)
Unfortunately, for Page Manager users who use Panels display variants, lots of config entities will be created, which is the main downside of this approach. We discussed this at last SCOTCH meeting, and we came away feeling that this was less than optimal, but necessary to preserve important features we had in D7.
On the upside, the number of config entity types matches the number of tables used in D7, and the number of config entities matches the number of table rows in D7. The Panels display config entity corresponds to the 'panels_display' table in D7 (see comment #9 for the rest of the mapping). So, we're basically recreating the same overall architecture as in D7...
Comment #29
rlmumfordThanks for the explanation! I've been trying to keep up with the Port Panels8 meetings but obviously missed that conversation.
Comment #30
dsnopekRe review from #23:
1. Removed in earlier patch.
2. Removed in earlier patch.
3. Yeah, if you think it'd be better to split that into it's own issue, I can do that! This issue makes the inconsistency of that route name even more apparent, because it adds some new "entity.*" route names. Leaving it in this patch for now, though.
4. Removed in earlier patch.
5. Ah, thanks! Fixed.
6. Removed in earlier patch.
7. In D7, you have to select the initial variant type in the creation wizard. Personally, I think this should be up to the UI and not done at the entity level. Any UI that wants to allow users to create a Page without the default "HTTP status code" variant would actually have to remove the variant after entity creation, which seems messy. I'm going to just remove this altogether - but we can continue to discuss this if anyone disagrees!
8. Cool, thanks! Fixed.
9. No, I think you're right - this doesn't make sense. Removed.
10. Hm. This'll need more thought. First of all, no, I don't think we were talking about having multiple pages reuse a variant. The page variants need an upward reference to the page so that we can do the 3rd point in the issue summary, which is to have several Features provide page variants for the same page. But I agree that we probably shouldn't do this in
postLoad()
- it'd be better to load them on demand ingetVariants()
.11. Removed in earlier patch.
12. Cool, thanks! Removed.
13. Ah, cool! I added the 'config_export'. However, Page also implements a similar
toArray()
. Is that really not necessary there either?14. Yeah.. I'm not sure what that's about! I think it might be trying to use the same method name but change the config key. I'll dig into this a bit deeper and see if we can't make them match.
Thanks again for the review!
Comment #31
dsnopekPicking this back up again...
Comment #32
dsnopekThis fully addresses the points that weren't totally addressed in #30. It also documents all the methods on the
PageVariantEntityInterface
, renames some stuff for clarity, and does other little clean-up!Still TODO:
Comment #33
dsnopekAlright, this gets selection criteria and weight working! I also renamed some of the selection criteria methods to match the access condition methods (they were easier to reason about with a normal plural form). Some of the phpunit tests are failing, but the big test push is the next step anyway.
This also removes some now unused classes, interfaces and traits.
Comment #34
dsnopekAlright! This passes almost all of the tests. Still more to do, but this is probably ready for some more in-depth reviews!
Comment #37
dsnopekThis one should actually pass tests. For real. :-)
Comment #38
japerrySounds like we're postponing this one dependent on the page-manager -> ctools move.
I'd suggest re-rolling this patch against patch on #2511566: Add an abstract version of Drupal\page_manager\Plugin\DisplayVariant\BlockDisplayVariant from Page Manager comment 10.
Also for what its worth EclipseGC hates the ConditionVariantInterface so we want to remove it from ctools pretty quickly.
But we also don't want to block the panels folks from using the newly moved code.
Comment #39
dsnopekThis patch removes the
ConditionVariantInterface
. :-) Which is one of the reasons I think we should postpone #2511566: Add an abstract version of Drupal\page_manager\Plugin\DisplayVariant\BlockDisplayVariant from Page Manager on this one.Comment #40
japerrythis will take a while, there are arguments around whether to do this or not. We're moving items to ctools first.
Comment #41
mpotter CreditAttribution: mpotter commentedAlso, from the Features perspective, in D7 we already do this using Features Override and we'll likely just need something similar for D8. I can see the case that the architecture of variants within pages is analogous to displays in a view. Having a config entity have a list of other related config entities is beyond the scope of just panel variants I think. So I agree with postponed.
Comment #42
dsnopekFrom IRC conversation:
But we can jam on this more on Tuesday at the SCOTCH meeting!
Comment #43
mpotter CreditAttribution: mpotter commentedoh wait, I was confusing "pages" with "panelizer". In D7 page variants *are* separate exportables. Sorry. So yeah, we are still debating ;)
Comment #44
mpotter CreditAttribution: mpotter commentedOK, here is a version of the patch that refactors the entityManager->getStorage('page_variant') into protected methods.
Comment #45
dsnopekDiscussed this with Tim on IRC a bit. One of his main issues was the performance associated with loading the variant entities which are associated with the page. Here is a patch that should address this by making 'page' a lookup key on the variant entity.
Comment #46
dsnopekSo, this patch desperately needs to be re-rolled for all the recent changes, but I just noticed that the patch I uploaded in #45 is incorrect - it doesn't have the changes in the interdiff. So, just for completeness, here is the real patch!
Comment #47
dsnopekThis is a straight re-roll of the previous patch. Unfortunately, some of the code it changed is now in CTools so there we'll need to patch it as well to get everything right (although, tests pass and it basically works without the CTools changes): #2580469: Clean-up after Page Manager starts using page variant entities
Comment #49
dsnopekOops! Lost some changes intended for
PageBlockDisplayVariant
that were lost in the re-roll.Comment #51
dsnopekHrm. All tests are passing for me locally. Not sure what's going wrong with the testbot? :-/
Comment #52
dsnopekBlergh. I'm able to reproduce the test failures with the latest Drupal HEAD and page_manager even without this patch. Here's a new issue for that: #2580493: Tests failing on \Drupal::service('cache_contexts_manager')->assertValidTokens($cache_contexts)
Comment #53
dsnopekAlright, the patch is green again!
Comment #54
tim.plunkettJust nitpick fixes for now, added a couple @todos that we need to clean up.
Also rebased it on other nitpick changes I made to 8.x-1.x
Comment #55
Wim LeersHigh-level review. Looking at the entity types and cacheability aspects.
Shouldn't the class be named
PageVariant
? And the interfacePageVariantInterface
?That'd then match the ID. And the form classes.
And every entity type in core.
I'd expect this to be taken care of in the
Page
andPageVariant
config entities' logic. It should be encapsulated there, otherwise everything that deals with Pages and Page Variants will have to repeat this sort of logic.Look at e.g.
\Drupal\aggregator\Entity\Item::postSave()
for inspiration — we have a few of these entity types with very strong coupling amongst each other.Comment #56
dsnopekThanks for the review, @Wim!
1. That name was to avoid confusing the entity with the plugin (we have a plugin and an entity that are "variants") and
\Drupal\Core\Display\PageVariantInterface
which again, refers to the plugin and not the entity. If possible, I'd prefer to keep this name as it avoids confusion (I was personally confused by this the first time I reviewed EclipseGC's wizard patch which used the names you're proposing).2. I think you're getting confused between the plugin and the entity. :-) That code is adding the cacheable dependencies to the plugin, which is only just created, not the entity where we could save the dependencies on the config object. I could see an argument, though, for adding the cacheable dependency information to the plugin in
PageExecutable::selectVariant()
so that it wouldn't need to be repeated by some other code that wanted to render a Page.Overall, we need to agree on a naming scheme to differentiate between the plugin and entity for variants. I have the following proposal:
getVariantPlugin()
,selectVariantPlugin()
and "variant plugin" to refer to the pluginMy current patch doesn't totally do all of the above, so if this was acceptable, it'd need to be updated. What does everyone think?
Comment #57
Wim LeersPageVariantPlugin
andPageVariantEntity
?But my overall point still stands I think: a page entity actually depends on multiple page variant entities: when the page is rendered, it selects a page variant to use. So doesn't it then make more sense to let the page variant entities use the same cache tags as the page entity they are associated with? (Just like e.g. feed item entities use the cache tag of the feed they belong to.)
For minimum consistency, we should then at least rename
Page
toPageEntity
. And per my first point, actually alsoPagePlugin
andPageVariantPlugin
. Or… just go withPage
andPageVariant
everywhere, and rely on namespaces — that's what they're here for. You can still always call the instances' variable names$page_plugin
and$page_entity
.If it's the same as "page variant", then yes, please consolidate all that. But I think that doesn't need to happen here per se; could be a follow-up.
Comment #58
dsnopekWell, there's no PageVariantPlugin - the interface for those is from core, which is
\Drupal\Core\Display\VariantInterface
and optionally\Drupal\Core\Display\PageVariantInterface
. I suppose whereever we "use" those interfaces we could do "as VariantPluginInterface" and "as PageVariantPluginInterface" to make it clear - I'd be for that!I'm curious what Tim thinks! Relying only on namespaces was confusing to me - it's my interation on @EclipseGC's code that changed the class name. In the end, I'm happy to go with whatever Tim wants to do.
Ok, so you're saying that rather than adding cache tags to the variant plugin for the individual variant config entities, we add a
PageVariantEntity::postSave()
which invalidates the cache tag for the page entity? Does thepostSave()
will when importing a .yaml via CMI? If so, that makes sense! It means adding fewer cache tags to the render array.Comment #59
Wim LeersYes, it's called then too. Otherwise it'd be a poor abstraction :) (But given that such edge cases were commonplace in D7, I totally understand your skepticism :D)
Yes, but more importantly: a system that is easier to reason about!
Comment #60
dsnopekOk, here's a new patch that attempts to address #55.2! My first thought was that overriding
::getCacheTagsToInvalidate()
to return the page's cache tags would be enough, but it turns out thatConfigEntityBase
overrides::invalidateTagsOnSave()
and::invalidateTagsOnDelete()
such that the cache tags for the individual entities aren't overridden, only those for the entity type. So, I had to override those too and invalidate the entity's cache tags as well.This doesn't make any changes to naming because I want to find out what Tim thinks first.
Comment #61
tim.plunkettWhy doesn't getPluginCollections include the variant plugin? It can use a single plugin collection like the block->block_plugin relationship.
Do we want to store this? Or just rely on entity static caching?
Also, ewwwwwwwww. Really wish this wasn't necessary.
Would we want to have a PageVariant view builder instead?
bool
This method seems a little out of place. Should it be on the page variant entity?
Comment #62
tim.plunkettComment #63
dsnopekDiscussed #61.3 with @tim.plunkett and we're going to punt on that until after this patch and #2305199: Create a route for every variant and use a "route filter" to apply selection rules.
This patch fixes the remaining points from #61 that weren't fixed by Tim's patch in #62.
Comment #64
dsnopekHere's all the renaming that I proposed in #56, which Tim said he's cool with.
Comment #65
dsnopekAnd this renaming PageVariantEntity back to PageVariant per Tim's request.
Comment #66
phenaproximaNit: The stuff in create() should be broken up into several lines for readability.
One suggestion -- if the variant ID is required, maybe it should be an explicit argument to the method.
I see that variants are sorted by UUID in getVariants(). Why are they keyed by ID here instead of UUID? Should $this->displayVariants be re-sorted after adding the variant?
Nit: Maybe this should be \InvalidArgumentException or something otherwise more specific than \Exception.
Why bother with an isset() check here? Is there some reason $this->displayVariants can't be defined with an empty array as its default value?
This line is strange. $this->entityStorage() is getting the *variant* entity storage, yet this is on the page entity class. entityStorage() should probably be renamed to getVariantStorage() or similar.
$a and $b should probably be type hinted.
I kind of wish this was named pluginId or similar, rather than the more ambiguous "variant".
This one needs an explanation :)
$weight isn't type hinted so maybe this should be $this->set('weight')?
For consistency, should this be $this->get('selection_logic')?
Micro-optimization -- the call to \Drupal::service() can go outside the foreach loop.
@todo? :)
This docblock isn't very helpful.
Should be @inheritdoc.
Ditto.
Ditto.
Already defined in EntityForm, which this form extends.
I don't see how this is being used -- is there any reason to attach drupal.ajax here?
Again, I don't see how drupal.ajax is being used here, so does it need to be attached?
Missing doc comment.
This doc comment is not informative.
Shouldn't this be an interface instead of a concrete implementation?
s/@todo/actual info
Nit: s/plugin id/plugin ID
Nit: s/id/ID
Ditto.
Comment #67
dsnopekThis doesn't address the review in #66 yet. It just re-rolls the patch for the latest changes to page_manager. But it doesn't pass tests yet!
Comment #70
tim.plunkettSmall fixes. Too lazy to run all the tests locally.
Comment #72
tim.plunkettSaving variants also needs to rebuild the router. We have this code on the page, is there any better way to do this @dsnopek?
Comment #73
tim.plunkettComment #77
tim.plunkettOkay my @todo from before was the last bug in PageManagerAdminTest. What else is left?
Comment #78
tim.plunkett#66
1) Fixed
2) Removed this method
3) Should always sort by ID
4) Yep, fixed
5) We do that to help prevent loading them all each time
6) Renamed.
7) We usually don't do this, not sure why. Undone for now
8) Not sure how I feel, unchanged for now.
9) Unchanged
10) Nah, setters are good. We want to discourage usage of the generic set/get
11) Redundant.
12) Unchanged, but yes. Also it should be in a protected method (the service call)
13) Unchanged
14) Unchanged
15/16/17) Fixed
18) This is for typehinting purposes.
19/20) This is needed for the AjaxFormTrait calls to work
21) Fixed
22) Unchanged
23) This has no interface :( But it's a factory, not as bad as the actual class
24) Unchanged
25) Fixed
26/27) Fixed
I also removed the variant ID munging. This will likely break many tests. More to do!
---
So #66 points 9, 12, 13, 14, 22, 24 need addressing still.
Comment #80
tim.plunkettFixed an issue with saving. The way variants are saved is similar to plugin collections, so we fix it in copyFormValuesToEntity.
Comment #81
dsnopekGreen again! :-)
Comment #82
tim.plunkettThis fixes access and the rest of #66. I still have some work to do, just posting progress.
Comment #83
tim.plunkettI spent some time on the plane home looking into PageVariantViewBuilder, and it SO VASTLY simplified things, I want to include it here.
So! The final blocker here....
The breadcrumbs are completely broken now.
First we have the page edit form:
/admin/structure/page_manager/manage/{page}
Then we have the variant edit form:
/admin/structure/page_manager/variant/{page_variant}
Either we should make it
/admin/structure/page_manager/manage/{page}/variant/{page_variant}
or we have to write a custom breadcrumb class.
But there is no way to get from a variant back to it's page, and it is infuriating.
Comment #84
Wim LeersNice :)
Reviewed just that bit:
Hrm… it seems misleading for this to extend
EntityViewBuilder
, because…… that is where all the building happens!
It seems more honest/clear to make this implement the interface directly and make several of the methods no-ops.
Comment #85
tim.plunkettI do that because EntityViewBuilder is a shitty interface. It should be called FieldableEntityViewBuilderInterface...
Also, PageViewBuilder (which we're replacing), does the same thing.
Comment #86
Wim LeersBut that means that e.g.
\Drupal\Core\Entity\EntityViewBuilderInterface::viewFieldItem()
is implemented, which AFAICT makes no sense for page variant entities?I just gave it a try… and proved myself more wrong than right :)
This is basically what you want:
But, note two bits are duplicated from
EntityViewBuilder
. Well… except they shouldn't be, because::view()
doesn't actually add the cache tags fromgetCacheTags()
, which meansresetCache()
is pointless to implement.So, either:
EntityViewBuilder
like your patch does, update it to useEntityViewBuilder::getCacheTags()
inview()
, and override the nonsensical methods to throw a logic exceptiongetCacheTags()
andresetCache()
Comment #87
tim.plunkettGahh I hate EntityViewBuilderInterface so much.
But you're right.
We can't safely throw exceptions in restCache(). But WhyTF is buildComponents public?!
Comment #88
tim.plunkettThis fixes the path structure. I think I'm happy with this now?!
Comment #89
EclipseGc CreditAttribution: EclipseGc commentedLooks good to me! Let's get this in.
Eclipse
Comment #94
tim.plunkettThanks everyone!
Comment #96
dsnopekWoohoo! This is the happiest news of the morning. :-)