Problem/Motivation
The original motivation for this issue was a generic OG group-content listing that consumed list_builder handlers. That work was proposed in Gizra/og PR #423, but the PR was closed unmerged when the GitHub repository was archived in 2024 and was never re-filed on drupal.org. OG 2.x has no such consumer.
A list builder is still useful on its own. ogmenu_instance is a content entity with no administrative listing, while /admin/structure/menu/ogmenu/{ogmenu}/overview uses the custom OverviewMenuInstances form to provide one. That form has only a single column, provides no edit or delete operations, and throws an uncaught exception when an instance has lost its group reference.
Proposed resolution
- Add
OgMenuInstanceListBuilder, using constructor injection as discussed in #5–#9. - Show Group and Menu labels with the standard entity operations.
- Override
getEntityListQuery()to preserve access checking and paging. - Add the
list_builderhandler,collectionlink template, admin route, and menu link. - Use the list builder for
entity.ogmenu.overview_form, filtered by bundle, and removeOverviewMenuInstances. - Handle orphaned instances gracefully using
getFieldTargetTypeLabel(). - Add kernel test coverage.
Remaining tasks
Patch #8 predates the PHP attribute conversion in #3623456 and the Drupal 10 accessCheck() requirement. Rewrite it as an MR against 2.x rather than rerolling the existing patch.
Original report:
Problem/Motivation
Over in https://github.com/Gizra/og/pull/423, I'm trying to add a content listing. OG menu instances are content. But since it doesn't have a list_builder handler, it doesn't show up.
Proposed resolution
Take the existing Controller and route for listing menu instances and convert it to a list_builder.
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | interdiff.txt | 3.53 KB | pfrenssen |
| #8 | 2992044-8.patch | 3.75 KB | pfrenssen |
Issue fork og_menu-2992044
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
heddnPretty simple list builder, but now we have one. It will filter by og context, if one is available.
Comment #3
pfrenssenThanks! Let's add some test coverage for this.
Comment #4
pfrenssenI tried this out on an installation with 3 OG Menu types. Since the titles of the menu instances are automatically taken from the group it is currently not possible to distinguish between the different menus that are associated with a single group.
We should add a column for the menu type.
Comment #5
pfrenssenIs there any reason this method is public? It is not part of the EntityListBuilderInterface.
It seems to me that this being set in the constructor should be sufficient, and the method can be made protected.
Are you perhaps planning on calling this from OG code? If this is the case we should add a new interface that contains this method.
Comment #6
heddnIt has to be public, otherwise the code cannot call it. I'm using that style to insulate against upstream changes. See https://www.previousnext.com.au/blog/safely-extending-drupal-8-plugin-cl... for a more complete description.
Comment #7
pfrenssenOK thanks for the link, I understand the reason now why you propose to use this pattern. I have been pondering it for a while but I think I would prefer to still use the standard constructor based approach from core. I think having to update the factory method in the future is just a minor inconvenience, and it might not even be necessary during the life cycle of Drupal 8. I think the benefit of potentially avoiding a few minutes of work in the future is not a strong enough argument for violating the OO principles.
This pattern makes the class some kind of a mix of constructor based and setter based dependency injection. The correct way to handle this would be to use to provide a factory class which is a service in itself instead of a static factory method. Then your class can be protected against upstream changes and you avoid adding any public methods which are not intended to be part of the public interface. Unfortunately this is something that should be fixed in core itself. Using a factory service is a pattern that is supported by the Symfony dependency injection container and is already used in core in a few places, for example
\Drupal\Core\Http\ClientFactorywhich has the non-static factory methodfromOptions().I don't know if there is some kind of initiative planned to move to service based factories in Drupal 9? Could be interesting to avoid these kind of issues.
Comment #8
pfrenssenUpdated patch: it has an additional column for the menu type and the constructor based instance creation which I argued for in my previous comment. I am open for discussion to revert this back to the "safe" static-method-plus-public-setter based approach though if this is deemed to be very important. I am in any case willing to do the required work to update this in the future in case the constructor signature changes.
I also added an initial route for it so the list can be inspected at
/admin/structure/ogmenu_instance. It doesn't have any tests yet. I probably want to get rid of this route again before merging the patch.While working on this I noticed a few hairy issues in the module's code base which I want to address first. I would like to be able to show the human readable OG Menu label in the table rather than the machine name of the bundle, but this is not accessible directly from an OG Menu Instance entity.
What I also would love to have is if we could replace the existing lists at
/admin/structure/menu/ogmenu/<menu_name>/overviewwith this new fancy list builder. We would be able to leverage the OgContext based filter. We might need to write a custom OgGroupResolver plugin for these paths though.Comment #9
heddnI don't have strong feelings about the method to inject arguments.
Comment #10
joelpittetRe-scoping to revive this instead of closing
Comment #12
joelpittetHas kernel test and I think this picks up this really old issue