Problem/Motivation
Providing a UI for an entity type involves a lot of boilerplate code.
In particular, three YML files have to be provided:
- MODULE.links.menu.yml
- MODULE.links.task.yml
- MODULE.links.action.yml
These contain repetitive boilerplate code, where furthermore it's very easy to make a mistake and match up the route names incorrectly.
Proposed resolution
Add a new handler type for entities, 'link_provider'. This defines menu, task, and action links for an entity type.
Provide two link provider handlers in the Entity component that follow the standard admin UI pattern (for example, as used by Media module's entity types):
- DefaultContentEntityLinkProvider
-- defines a local task link for the collection under admin/content, alongside the Content admin listing
-- defines a menu link for the collection as well, so it appears in the admin toolbar
-- defines the 'add new entity' action link on the collection page
-- defines a set of local tasks link for view/edit/delete for a single entity
- DefaultConfigEntityLinkProvider
-- defines a menu link for the collection under admin/structure
-- defines the edit form local task link, which allows Field UI to attach its own tasks for the case that this config entity is the bundle for a content entity.
Both of these link provider handler classes expect to find the route names created by core's route_provider classes.
Entity types that customize their route provider to change or add routes would need to use their own link_provider handler (or keep using hardcoded link plugins of course).
Note that contextual links aren't provided by these, because they're part of Core-core, and contextual links are in a core module.
Remaining tasks
- Get a review from one of the managers of the plugin system. YAML plugins are not discoverable in core/lib (unlike annotation-based plugins), and so the current patch declares the plugin derivatives that are in core/lib/Core/Entity in system module's YAML files. This approach needs framework manager review.
Follow-ons
Convert core's entity types to use these handlers. This is left as as follow-up, because changing an entity type to use a link provider handlers will cause the plugin IDs of the link plugins to change. It's not clear whether the BC policy on plugin IDs applies to menu plugins, and there is no policy or defined way on how to handle YAML plugin ID changes -- see #2922451: [policy no patch] Make it possible to mark plugins as deprecated.
User interface changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #89 | 2976861-nr-bot.txt | 17.9 KB | needs-review-queue-bot |
| #86 | 2976861-nr-bot.txt | 150 bytes | needs-review-queue-bot |
| #83 | Screenshot 2022-10-10 at 3.02.02 PM.png | 143.86 KB | bhanu951 |
| #75 | Screenshot 2022-08-11 at 2.06.24 PM.png | 89.26 KB | bhanu951 |
| #75 | Screenshot 2022-08-11 at 2.06.37 PM.png | 76.75 KB | bhanu951 |
Issue fork drupal-2976861
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
bojanz commentedThe Entity API contrib has code for this that can be borrowed (written by tstoeckler)
Comment #3
joachim commentedThanks for the info! I'll have a look.
Assigning to myself while I work on this.
Comment #5
joachim commentedHere's a patch.
A few notes:
- The declaration of the plugin derivers is in system module. That's because YAML plugin discovery doesn't look in core/lib/, unlike annotated class plugin discovery.
- I've not handled the collection tab for content entities, because that's due to change in #2862859: Create a top level, extendable, "Content" admin menu route that behaves like "Structure".
Comment #7
joachim commentedFixed the codesniffer issues & the failing test.
Comment #8
joachim commentedComment #9
jhedstromThis would be really great!
I think a test should be added, similar to the
RouteProviderTest. One of the test entity types in theentity_testmodule should updated to use this link provider, and the new test can simply verify the menu links are created as expected.Comment #10
joachim commented> One of the test entity types in the entity_test module should updated to use this link provider, and the new test can simply verify the menu links are created as expected.
I've made a start on this at DrupalEurope. I'm making a new entity type within that module, so it doesn't affect existing tests.
Comment #11
sam152 commentedGetting something like this into core would be awesome, the set of links in
DefaultContentEntityLinksProviderare added to almost every entity type, so it would be a huge DX win.I can't think of a better way to connect the dots between the routes and links, besides using the established naming conventions. The template method pattern used is consistent with the route providers, so +1 on consistency.
Comment #12
joachim commentedThanks for the review!
Here is an updated patch which fixes a few minor bugs, and adds a test entity type to the entity_test module that's inside system module's tests.
However, I can't get this entity type to appear in the UI -- its route provider handler doesn't seem to fire. I've probably got some very minor thing not declared properly, but I can't see it.
Comment #14
joachim commented> However, I can't get this entity type to appear in the UI -- its route provider handler doesn't seem to fire. I've probably got some very minor thing not declared properly, but I can't see it.
Entirely the fault of my local setup -- I had another entity_test module in my modules/custom folder!!!
Comment #15
joachim commentedFixed the failing existing tests -- due to the router service not being typehinted as an interface.
Comment #16
joachim commented> - I've not handled the collection tab for content entities, because that's due to change in #2862859: Create a top level, extendable, "Content" admin menu route that behaves like "Structure".
I've spoken to @ifrik at DrupalEurope about #2862859: Create a top level, extendable, "Content" admin menu route that behaves like "Structure", and how soon that might make it into core. The answer is not anytime soon, so this patch here should probably be changed to provide the collection tab for content entities.
Comment #17
joachim commentedAdded kernel tests.
The functional test fails, but the machine I am on is too slow to keep running them to figure them out. Would be great if someone else could move these forward.
So, still to do:
- decide whether having system module declare the plugin deriver classes that are in Core\Entity is OK
- decide whether the awkward checking for existence of routes is OK
- add a collection tab for content entity types
- finish the functional test
Comment #18
joachim commented> - add a collection tab for content entity types
Done.
Comment #19
sam152 commentedThis is seriously nice work and will be a huge DX win. Adding a progress review.
As for the other outstanding points, I'm not an expert on the system module, but the use of the deriver here seems reasonable and I can't think of a good alternative.
I think maybe the reason we have methods like
hasFormClassesandhasRouteProvidersis because those types of handlers have sub-elements, so a check tohasHandlerClasswouldn't be sufficient.Might be worth just leaning on
hasHandlerClassto keep our interface tidy? This is more a preference though, feel free to disagree.Lets add the class as a
@seeas well.Maybe we could say instead "uses the established convention for route names" or something and maybe even go as far as to describe what those conventions are.
I dug into this again after our conversation at DE, looks like a work-around to the exception based control flow would be to call
getRoutesByNames([$route_name])and check if it was empty or not. Not sure if this is the lesser of two evils.I assume this is correct, because the plural label will already be translated:
label_plural = @Translation("content items"),Does field UI really do stuff with config entities?
Maybe list builders are the next kind of boilerplate we need to address 😅
{@inheritdoc}?
Maybe we can lean on
\Drupal\entity_test\EntityTestListBuilderhere?Comment #20
joachim commentedThanks for the detailed review!
> I think maybe the reason we have methods like hasFormClasses and hasRouteProviders is because those types of handlers have sub-elements, so a check to hasHandlerClass wouldn't be sufficient.
There is hasListBuilderClass() and hasViewBuilderClass(), which don't have sub-elements.
> a work-around to the exception based control flow would be to call getRoutesByNames([$route_name])
I think that's definitely better. Thanks for the tip!
> Does field UI really do stuff with config entities?
Yes, because the node type is a config entity, and Field UI adds tabs for node fields to the node type form page. I'll expand that explanation.
> Maybe list builders are the next kind of boilerplate we need to address 😅
I think I maybe filed an issue very early on in the D8 cycle. I'll see if I can dig it up.
I'm working my way through the other suggested changed, new patch coming in a bit.
Comment #21
goodboy commentedFor example,
It may be replaced to
Or even can make helper function like
and then use it as
Comment #22
joachim commentedFurther changes from #19:
> Maybe we can lean on \Drupal\entity_test\EntityTestListBuilder here?
Hmm we could, but I generally tend to think that for tests, it's best not to get clever with code reuse, because that complicates the tests in ways that aren't helpful. If two totally separate test entity types that are for totally different tests share a handler, and in the future one set of tests needs to be changed, then the two sets of tests are entangled and it makes changing them harder.
Changes from #21:
> Or even can make helper function
Good idea! I really like this! It means that all the assumptions about how route names are formed for an entity type are encapsulated in a single method. So entity types that have non-standard route names can subclass the core link providers and override just the one method.
> Should we check $this->routeExists() for $link['base_route'] also?
Yes, good catch!
Comment #23
joachim commentedHere's the interdiff -- the upload button was being glitchy.
Thanks both for your reviews!
Comment #25
joachim commentedWhoops.
Comment #26
sam152 commentedBumping this again today after having to go through and painfully create a stock standard set of links from scratch.
One last question I had, does this meet the needs of any of the existing entity types in core? It would be great to include a real-world use of this and demonstrate how much fiddling it solves?
I'm not sure if this needs a framework manager review or not.
Comment #27
joachim commented> One last question I had, does this meet the needs of any of the existing entity types in core? It would be great to include a real-world use of this and demonstrate how much fiddling it solves?
Good idea!
This default handlers produce a generic UI, such as Media provides, and other contrib modules that add an entity + entity type pair of entities.
I was planning on converting core entity types as a followup, but making a start now isn't a bad idea.
I made a quick start today, and found a problem with the patch: there's no documentation on what the IDs of the generated menu/task/action plugins are, which isn't good when you need to connect other parts of the UI to them, especially as getting those IDs out of the database is a PITA as they all live in the cache tables. So that's something!
Quick list of core entities and and, off the top of my head, what they'll need:
- node & node type: should mostly work OOTB, except for the admin/content menu and task which is different.
- comment & comment type: these don't use a route provider handler, so we can't work with them.
- block content type: might need a few tweaks, still figuring this one out
- media: should work OOTB
- terms & vocabs: might be a bit tricky, as these basically are mixed together in the same UI
- user: probably best leave it, as Profile contrib module and other modules will be depending on the plugin names
Comment #28
joachim commentedOk, I've got block content working! Requires a BlockContentTypeLinksProvider with a few overrides:
- getCollectionMenuLink() needs to return NULL, as there's no menu link for the collection
- getCollectionTaskLink() needs to return a link, as the collection has a task link instead
- the add route is hardcoded, so I've added a helper getAddActionRouteName() to BaseEntityLinksProvider for this sort of case, so that specifying the different route name doesn't require repeating a load of code.
I think rather than either adding this follow-up work as patches here, or creating posting patches to follow-up issues where they'll fail tests and get out of sync with work here, I might create a repo on github as a sandbox for this. That way I can rebase commits so there's always a 2976861 branch & then a 'convert core entities' branch on the tip of it.
Comment #29
joachim commented> I'm not sure if this needs a framework manager review or not.
I would say it needs review from one of the managers of the plugin system, on whether it's OK to declare the plugin derivatives in system module's YAML files, while the deriver class is in core/lib.
Furthermore, regarding the follow-up to use this for core entities, we potentially have a BC problem.
Converting an existing entity type to use a link handler means changing the IDs of menu link, task, and action plugins from the hardcoded ID in YAML files to the derived IDs. There's no way that a change of ID can be avoided, as we use a deriver, so even if we were to customise the link provider handler to match the old IDs, we'd still get a deriver prefix.
The BC policy at https://www.drupal.org/core/d8-bc-policy says:
> Particular plugin classes should not be considered part of the public API. References to plugin IDs and settings in default configuration can be relied upon however.
I think it could be argued either way whether the menu system plugins are included in that, as the 3 menu plugin types aren't especially plugin-ish.
The thing is, if we can't change this over and preserve BC in a D8 minor version, then the question is, *when* can we?
Comment #30
joachim commentedUpdated patch with some fixes for things that got exposed by converting block_content_type:
- added docs on plugin IDs
- added getAddActionRouteName() helper method
- fixed label for add action
Patch and interdiff created by Dorgflow.
Comment #32
joachim commentedI'm eating my own dogfood and using this on a project that has a lot of custom entity types.
I'm liking that this gives me the ability to create my own link handlers, and then customize the UI for several entity types in one go!
I found one bug: content entities actually need to add a menu link to their collection under admin/content as well as the tab link.
Changes since the last patch:
- fixed missing collection menu link for content entities
Patch and interdiff created by Dorgflow.
No idea what the last test failure was about - doesn't seem related.
Comment #33
jhedstromI'm not sure I follow--does this patch require they do so or something breaks?
Comment #34
joachim commented> I found one bug: content entities actually need to add a menu link to their collection under admin/content as well as the tab link.
> I'm not sure I follow--does this patch require they do so or something breaks?
Not at all.
Prior to patch #32, entity types using the handler weren't getting a child menu item under Content when using the contrib Admin Toolbar menu. I had assumed that was Admin Toolbar not handling things in a general manner but hardcoding for core entity types (which it is for other things -- see #3028213: generalize creation of 'add ENTITY' and 'add BUNDLE' links).
But in fact, it turns out that menu item is made in core -- Media has it for instance, as does Comment.
What Media module does with its links has pretty much been my template for the handler, since Media is the core entity type with the most generic UI. (Node has special cases because it's the primary entity type, block content is placed differently, comment has special cases.)
Therefore, I've added that menu link to the handler as well, to match what Media does.
It might be that not having it has an impact in core too, say, if you use the vertical version of the toolbar, but I've not checked.
Comment #35
jhedstromAh, that makes sense. So is there anything left to do here other than a change record and an issue summary update?
Comment #37
joachim commented> So is there anything left to do here other than a change record and an issue summary update?
Functional tests, which I'm working on.
BTW, I've created some custom route & links handlers that cover two cases that core doesn't and shouldn't have to:
- single bundle entity type (like 'user')
- entity type that has bundles, but where the bundles do not come from a config entity
Code is at https://github.com/joachim-n/entity_admin_handlers, with more explanation in the README. I think these nicely show the potential of this patch :)
Comment #38
joachim commentedAnd here's the patch with functional tests.
Comment #40
joachim commentedUpdated the IS.
Comment #41
joachim commentedI'm going to say that a failure in /var/www/html/core/modules/views/tests/src/Kernel/Entity/RowEntityRenderersTest.php:148 is probably not related to this patch...
Comment #42
joachim commentedComment #43
bojanz commentedOne interesting note: This code currently always generates a Delete local task.
However, core only provides a Delete local task for content entities. Delete local tasks for config entities were explicitly removed in #1834002: Configuration delete operations are all over the place. I am guessing that we don't want to revert that conclusion. So we should either define the Delete local task only for content entity types, or never.
I am also unsure what our convention is for defining a List local task for the collection. Core seems to do it for many config entity types.
Comment #44
joachim commentedThanks for the review!
> Delete local tasks for config entities were explicitly removed in #1834002: Configuration delete operations are all over the place. I am guessing that we don't want to revert that conclusion.
Good point. Will change that.
> I am also unsure what our convention is for defining a List local task for the collection. Core seems to do it for many config entity types.
I'll look into it.
Comment #45
bojanz commentedAlso wanted to say that I find the current architecture confusing from a DX standpoint. I would have preferred the contrib Entity API approach of provider per link type, cause that gives me a clear mental mapping of 1 provider to 1 file. Reading through the current codebase required me to do several double-takes to figure out which link type I'm looking at.
Comment #46
joachim commentedThe reason I put all 3 link types into the same handler is that all 3 types work together to create the UI. They're indivisible. You wouldn't want to switch out the code for just one of the 3 types because it would start to get really messy.
I've been consistent (I think!) in naming all the methods so they say which link type they are about, eg getMenuLinks(), getCollectionMenuLink(). Is there anything else that could make that clearer?
Comment #48
manuel garcia commentedI'm very excited about this one, let's do it!
I had a look at the latest patch, which btw applies cleanly against 8.9.x.
I had a go at the failing test, but was unable replicate the failure locally (tested using PHP 7.3, 7.2 and 7.1).
Let's see if the failure is actually still there with the test bot then, setting to needs review for now.
Comment #49
joachim commented@Manuel Garcia that would be great, thanks!
Comment #55
joachim commentedMade an MR so it's easier to rebase in future, and rebased to 9.5.x
Comment #56
larowlanHiding patches now there's an MR
Comment #57
larowlanLeft a review, this is a huge improvement over the current setup
I wonder if its worth converting an existing entity type, e.g. taxonomy perhaps so we also get the benefit of any existing test coverage
Comment #58
aaronmchaleAgree this is a great addition, also left some comments.
+1 one to that, let's see how many we can do here, and open follow-ups for any that aren't a simple change.
Comment #59
joachim commented> I wonder if its worth converting an existing entity type, e.g. taxonomy perhaps so we also get the benefit of any existing test coverage
The problem with doing that is that it will change the IDs of the menu link plugins in that module. There is no clear policy on how to deprecate or remove plugins. And with menu plugins, it's even more complicated, as we can't have the old plugin still function (it would cause a double menu item). We need some sort of way to leave the old plugin ID there as an alias if we want to provide BC for any code that expects that plugin ID.
Comment #60
larowlanShould we also be generating contextual links?
Comment #62
joachim commented> Should we also be generating contextual links?
Not sure, as contextual links come from a core module rather than non-module core.
Does anyone have any thoughts on how to handle the menu plugin ID change?
Comment #63
larowlanGood point, that feels like reason enough to forego contextual links
Comment #65
aaronmchaleAdded comments to MR.
Comment #66
joachim commented> Yeah maybe entity annotation is overreaching, the class property is probably fine for now, maybe we could discuss it more in a follow-up issue?
Follow-up sounds good to me.
Fixed the incorrect parent menu ID, and rebased on 9.5.x.
This is still blocked on the problem of how to handle menu link IDs which will change.
Comment #67
berdir> This is still blocked on the problem of how to handle menu link IDs which will change.
I would not change existing entity types here, verify on test entity types and conversion can be a follow up
Comment #68
joachim commentedI like that plan!
In which case, I think this is ready for review.
Comment #69
bhanu951 commentedHi Joachim thanks for the work you done on this issue.
I tried to test the patch locally, but seems it need work. when I applied this patch seems the link for entity type collection is missing. It also misses the local task links for revisions and translation.
drush gen entity:content
Welcome to content-entity generator!
––––––––––––––––––––––––––––––––––––––
Module machine name [web]:
➤ entity_test
Entity type label [Entity test]:
➤
Entity type ID [entity_test]:
➤
Entity base path [/entity-test]:
➤
Make the entity type fieldable? [Yes]:
➤
Make the entity type revisionable? [No]:
➤ Yes
Make the entity type translatable? [No]:
➤ Yes
The entity type has bundle? [No]:
➤ Yes
Create canonical page? [Yes]:
➤ Yes
Create entity template? [Yes]:
➤ Yes
Create CRUD permissions? [No]:
➤ Yes
Add "label" base field? [Yes]:
➤ Yes
Add "status" base field? [Yes]:
➤ Yes
Add "created" base field? [Yes]:
➤ Yes
Add "changed" base field? [Yes]:
➤ Yes
Add "author" base field? [Yes]:
➤ Yes
Add "description" base field? [Yes]:
➤
Create REST configuration for the entity? [No]:
➤ No
The following directories and files have been created or updated:
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
• /app/web/modules/custom/entity_test/entity_test.links.action.yml
• /app/web/modules/custom/entity_test/entity_test.links.contextual.yml
• /app/web/modules/custom/entity_test/entity_test.links.menu.yml
• /app/web/modules/custom/entity_test/entity_test.links.task.yml
• /app/web/modules/custom/entity_test/entity_test.module
• /app/web/modules/custom/entity_test/entity_test.permissions.yml
• /app/web/modules/custom/entity_test/config/schema/entity_test.entity_type.schema.yml
• /app/web/modules/custom/entity_test/src/EntityTestAccessControlHandler.php
• /app/web/modules/custom/entity_test/src/EntityTestInterface.php
• /app/web/modules/custom/entity_test/src/EntityTestListBuilder.php
• /app/web/modules/custom/entity_test/src/EntityTestTypeListBuilder.php
• /app/web/modules/custom/entity_test/src/Entity/EntityTest.php
• /app/web/modules/custom/entity_test/src/Entity/EntityTestType.php
• /app/web/modules/custom/entity_test/src/Form/EntityTestForm.php
• /app/web/modules/custom/entity_test/src/Form/EntityTestTypeForm.php
• /app/web/modules/custom/entity_test/templates/entity-test.html.twig
I used the above drush command and generated test entity. After that I deleted below four ymls and added the patch from #67 and added "link_provider" = "Drupal\Core\Entity\Menu\DefaultContentEntityLinksProvider", in my entity annotation definition and cleared cache and check the entity type collection list , but it is missing.
• /app/web/modules/custom/entity_test/entity_test.links.action.yml
• /app/web/modules/custom/entity_test/entity_test.links.contextual.yml
• /app/web/modules/custom/entity_test/entity_test.links.menu.yml
• /app/web/modules/custom/entity_test/entity_test.links.task.yml
Basically menu link for entity.entity_test_type.collection route is not available with the patch.
It is also good to add Derivative for contextual links and permissions as well.
Comment #70
bhanu951 commentedComment #71
joachim commented> It is also good to add Derivative for contextual links and permissions as well.
We can't add contextual links as these come from a module -- see #62.
Permissions are a totally separate thing from menu links -- there is an issue for those too: #2809177: Introduce entity permission providers.
Comment #72
joachim commented> I used the above drush command and generated test entity. After that I deleted below four ymls and added the patch from #67 and added "link_provider" = "Drupal\Core\Entity\Menu\DefaultContentEntityLinksProvider", in my entity annotation definition and cleared cache and check the entity type collection list , but it is missing.
You deleted too many .yml files.
I generated a content entity using Module Builder, then deleted the *two* *.links.*.yml files, added the handler line to the entity annotation, resulting in this:
Did a `drush cr` and my entity UI is working fine:
- menu item in admin menu
- collection at admin/content/test_2976861, as a tab alongside nodes/files/media/comments
- action link to add a new entity
- entity has view/edit/delete tabs
Comment #73
bhanu951 commented@joachim thanks for the quick response.
Were you able to see entity_test_type link under structure? Which list bundles and manage fields?
Thats what missing after applying this patch.
Comment #74
joachim commentedSorry, I misread which collection was missing.
I went back to Module Builder, added a bundle config entity, re-generated, removed the links yml files again.
Did you add a links provider to the type entity too? Your EntityTestType.php needs:
Comment #75
bhanu951 commented@joachim that was missing in my code. Thanks After adding that menu link is visible under structure, but it still misses bundle list and add new bundle option in second level menu.
Pls refer attached images for difference between node and custom entity. You can see that second level menu links are not visible while admin toolbar module is enabled.
Comment #76
joachim commented> Thanks After adding that menu link is visible under structure, but it still misses bundle list and add new bundle option in second level menu.
That's because those 2nd level links are all hardcoded in Admin Toolbar module -- see the file /admin_toolbar_tools/src/Plugin/Derivative/ExtraLinks.php. There's an issue to fix this: #3028213: generalize creation of 'add ENTITY' and 'add BUNDLE' links
Comment #77
bhanu951 commentedGot it thanks @joachim
Comment #78
joachim commentedI've been working in this space for a while! :)
Thanks for your attention to detail!
Comment #79
nuezI've tested the MR and as far as I can see it's working well.
Contextual links
I was expecting the contextual links to be part of this proposal, until I found in the issue comments the reasons why this wasn't included. Just saying from a 'consumer' point of view'.
Parent base route
I think the DefaultContentEnityLinksProvider might hardly ever be used 'out of the box' for the lack to control the weight, base route and control over the UI as too many tabs and menu items might be added to the top admin/content menu item.
It's easy enough to extend this class, however could we consider adding a key to the entity type definition that can be used, such as 'link_provider_base_route' and 'link_provider_weight'?
Comment #80
joachim commentedThanks for reviewing!
> I was expecting the contextual links to be part of this proposal, until I found in the issue comments the reasons why this wasn't included
I've added a note about that to the IS to help future reviewers.
> It's easy enough to extend this class, however could we consider adding a key to the entity type definition that can be used, such as 'link_provider_base_route' and 'link_provider_weight'?
I'm torn between on the one hand not wanting to make this MR too complex and have it reaching into inventing new entity type properties, and the DX of not needing to subclass it.
I'll think about it :)
If the weight's not specified in the menu links defined by the LinksProvider, then they'll just be in alphabetical order won't they?
Comment #81
aaronmchaleIn regards to the weights, I just want to highlight this issue #3306388: Delete local task should be the last tab for content entities, the proposal is awaiting sign off at the Usability Group (hopefully I'll get a chance to present it today), but it's a strong case for providing sensible default weights, at least for the Delete local task.
Comment #82
aaronmchaleThe proposed resolution in #3306388: Delete local task should be the last tab for content entities was accepted at #3307567: Drupal Usability Meeting 2022-09-09, so that issue is good to proceed.
Would anyone here also be willing to work on that issue?
This issue should also take account of the solution in that issue, as it will directly impact the solution here.
Comment #83
bhanu951 commentedHi @joachim ,
Seems I observed one more issue. After applying this patch and patch from #3028213-23 I am seeing two menu links for custom entity bundle collection. Please look into the attached images.
I have just generated entities as discussed in #69 and added link_provider in both entity and entity type annotation.
Comment #84
joachim commentedI suspect it's because the patch in Admin Toolbar module is creating the menu items that core doesn't create currently.
If this patch gets in, Admin Toolbar would have to be changed. Or the patch in #3028213: generalize creation of 'add ENTITY' and 'add BUNDLE' links should add defensive guards in anticipation of this issue getting fixed.
Comment #86
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #88
joachim commentedAdded a 10.1 branch and MR.
Comment #89
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #90
joachim commentedThe branch is up to date AFAICT.
Comment #91
smustgrave commentedLooking into MR 3441 I see tests were added so removing that tag.
Remaining tasks mention
So tagging for that.
The 1 failure in the MR seems valid.
Comment #92
joachim commentedRebased branch 2976861-add-an-entity-Links-handler-to-provide-menu-linkstasksactions-for-entity-types for 9.5 and 2976861-10.1-add-an-entity-Links-handler-to-provide-menu-linkstasksactions-for-entity-types for 10.1.
Comment #94
pasqualleI have a question about entity collection listing: Is there a guideline, policy or d.o issue about where the entity list should go in the admin menu?
something like:
- if you extend the ContentEntity class, then your entity listing should be under admin/content/my-entity-plural
- if you extend the ConfigEntity class, then your entity listing should be under admin/structure/my-entity-plural
Some of the examples where this "guideline" does not apply:
Shortcuts (ContentEntity from core) listing is under /admin/config/user-interface/shortcut
Taxonomy terms (ContentEntity from core) listing is under /admin/structure/taxonomy/manage/%vocabulary%/overview
Image styles (ConfigEntity from core) listing is under admin/config/media/image-styles
Workflows (ConfigEntity from core) listing is under admin/config/workflow/workflows
Languages (ConfigEntity from core) listing is under admin/config/regional/language
Entity Browsers (ConfigEntity from entity_browser module) listing is under admin/config/content/entity_browser
Newsletters (ConfigEntity from simplenews module) listing is under /admin/config/services/simplenews
QRCodes (ContentEntity from qrcode module) listing is under /admin/config/services/qrcode
Comment #95
joachim commentedThere isn't guidance AFAICT.
There's a common pattern for content entity type/content entity type bundle pairs of admin/content and admin/structure.
Beyond that, as you say, there's a lot of variance. But the base classes here are meant to cover the common case and can be extended for other cases.
Comment #96
aaronmchaleWhile we were working on the effort to reorganise blocks in the admin UI, we were guided by structured content principles, and we applied these to the Drupal admin menu as follows:
There's a nice organisation there, from individual items up to the whole site.
This isn't formally documented anywhere that I'm aware of (maybe it should be), but we will likely use this to help inform any future reorganisation efforts of the admin UI.
In terms of how that relates to the question on this issue, it allows us to think about this a little more holistically. For collections of content entities, in general those probably fit best under Content; If it's a collection of config entities, those could live under Structure if they facilitate structured content (aka bundles and fields), but those could also live under Configuration if they are not related to structured content.
Comment #98
joachim commented> For collections of content entities, in general those probably fit best under Content; If it's a collection of config entities, those could live under Structure if they facilitate structured content (aka bundles and fields), but those could also live under Configuration if they are not related to structured content.
Are you suggesting we split DefaultConfigEntityLinksProvider into two classes,
- one for config entities for structured content, under Admin > Structure
- one for config entities that live under Admin > Configuration
In which case, for Configuration config entities, we'd need an entity property to specify the base route.
Comment #99
joachim commentedI've decided not to wait for figuring out how to deprecate plugins.
Instead, we can use alter hooks to ensure that plugin IDs are maintained for node and node_type links. We can remove those in due course. In fact, there is already this exact same handling in node module currently!
A separate problem is that core/modules/views/tests/src/Kernel/TestViewsTest.php is failing on a recursive router rebuild, because of Views. The chain goes like this:
- views data needs to know about routes
- the router is built
- MenuRouterRebuildSubscriber tells MenuLinkManager to rebuild() links
- that calls our new EntityMenuLinkDeriver
- BaseEntityLinksProvider checks routes for things
I'm not sure why this circularity is only coming up in Views, and only in that kernel test. After all, I don't get an error when I go `drush cr` with this MR.
Comment #100
joachim commentedOk it looks like it IS Views that's somehow the problem, as if I add this kernel test on this branch, it passes: