Problem/Motivation
Child item blocks are not rendering at all in Layout Builder mode.
I was expecting that CUSTOM MENU LINK FIELDS->Children would render any child menu items but this is broken.
Steps to reproduce
1. create a hierarchy of menu items.
2. enable layout builder for a parent.
3. add a section/block: CUSTOM MENU LINK FIELDS->Children
4. Enable title so you can see it.
5. The Children block is empty see image
Proposed resolution
The Children Block should render Child items.
Better solution: The Children block renders children if non-null or a link if this is an end-leaf.
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | Screenshot 2023-02-13 at 2.56.20 PM.png | 330.74 KB | dalemoore |
| #25 | Screenshot 2023-02-13 at 2.57.29 PM.png | 332.48 KB | dalemoore |
| #25 | Screenshot 2023-02-13 at 2.59.22 PM.png | 242.57 KB | dalemoore |
| #25 | Screenshot 2023-02-13 at 2.57.59 PM.png | 181.88 KB | dalemoore |
| #9 | Screenshot 2021-10-07 at 12.53.26.png | 59.96 KB | alexander.levitsky |
Issue fork menu_item_extras-3167363
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
Syntapse commentedComment #3
Syntapse commentedI have tweaked a variety of configuration items and its now working not entirely sure why it wasn't. Some default configuration with examples would be very helpful to new users in the future.
Comment #4
tisteegz commentedI am having this problem as well. My layout seems to be working fine but because the layout just has "Children" in it the children links aren't displaying. I realise it is probably because it is only showing the children and not the link itself? Would you be able to put your layouts/settings which you changed to get it to work in here so I can see what I have done wrong? Thanks!
Comment #5
djween commentedHaving same issue where I have several children menu items but "Children" field block doesn't render when using layout builder. However other blocks (menu and non-menu types) do render when placing them in same section as "Children" field block.
Comment #6
ral1239 commentedExperiencing the same issue. No children links displayed when using Layout builder.
Comment #7
scottsawyerI am opening this issue because several people are still experiencing this issue (myself included). I've tried every sort of configuration of the menu / menu block of expanding children, etc. In layout builder, there are no configuration options for the children field itself other than whether or not to display the title.
Comment #8
solenity commentedHere is a patch for this. It fixed the issue with the "Children" block not rendering correctly on a site running Drupal 8.9.19.
Comment #9
alexander.levitsky commentedConfirming that patch from #8 fix the problem.
It has happened after the patch from this issue was merged.
For my instance, the children block is rendering but in the incorrect place. It doesn't take into account the configuration from the layout builder and just renders at the end of all content configured in the layout builder.
Comment #10
jsutta commentedWe're experiencing a similar issue on Drupal 9.3.0. Like Syntapse, we're using Layout Builder to build a mega menu. However, our menu is being displayed twice: once in the right place and then again below the block created by the Layout Builder layout.
I followed the link provided by alexander.levitsky in #9 and found that manually reverting the changes introduced in 3227764 fixes the issue. The patch included in #8 in this issue also fixes the issue.
Comment #11
poindexterous commentedI'm running into this as well. Drupal 9.3.x
It looks like reverting
in getMenuLinkItemContent in MenuLinkTreeHandler back to
and removing
from the changes made in 3227764 has fixed the issue for me. I don't know enough about the entity view display to know what the difference is between why $view_builder->build($render_output) and EntityViewDisplay::collectRenderDisplay($entity, $view_mode)->build($entity) seem to be returning different render outcomes, but it look as though the latter method returns the menu children to the correct div.
Since those changes were made to improve performance (if memory serves from reading the other related issue) I am hesitant to start up a patch to roll that back. Does anyone have some insight on why the two are producing a different render outcome? From a quick glance at the docs (I have yet to dive deeper) I'd be under the impression they'd return the same thing.
Comment #12
intrafusionExperiencing the same issue as #9 and the patch from #8 solves the problem
Comment #13
dalemoore commentedCosigned on #8 fixing this issue. I don't know enough about what those two lines of code are doing or why they're needed, but commenting them out fixes the issue to where the children are rendered in the section properly, instead of below the layout builder area. I would definitely request that the next update include this (or whatever necessary) fix since this will be a huge use-case for this module I think moving forward?
Comment #18
vladimirausThanks
Comment #19
saranchuk_hys commentedAfter update to 2.18 Children block not rendering, but show before
so unpatch children-block-not-rendering-3167363-8.patch solve this issue for me
Comment #20
volegerComment #22
vladimirausReverted and made a release.
Please provide screenshots for future patches.
Comment #23
herved commentedOh sorry I guess I'm to blame for this.
But just a heads up, have a look at comments #2 and #3 from #3227764: Performance hit when rendering menu items (menu entities built multiple times).
The reason why this pre_render logic was there initially came from #3034814: Output individual fields or children only which breaks now that it got removed by the patch from this issue here.
Now personally I don't need this feature but it might be important for some users/sites.
Comment #24
vladimirausThanks @herved.
If anyone needs this functionality, please update MR.
I'm also hiding patches so MR is a source of truth.
Comment #25
dalemoore commentedIs the issue that those of us using Layout Builder to create our mega menu and those who aren't are getting two separate results? Actually applying the patch (https://www.drupal.org/files/issues/2021-10-06/children-block-not-render...) is the only thing that seems to work with Layout Builder for me.
Is it possible to satisfy both use cases, those using Layout Builder and those not?
Just to re-iterate, without the patch in #8, in Layout Builder the menu renders BELOW the Layout Builder section, not within it.
A few screenshots with my crappy in-progress building after months off this project :)
BEFORE patch:
Notice the Layout Builder section and the menu are on the same hierarchy level, completely outside of the two column section. Screenshot of menu below, with links below where they should be...
AFTER patch:
The menu is now within the second layout region DIV within the two column section. Screenshot below with patch applied, with links where they should be.
Comment #26
andyf commentedThanks everyone for the time already spent on this! I'm in the same boat as #25, #8 seems to fix menu item extras and layout builder for me.
And agree it'd be great to get more details on the regression the release caused. I just did a super-simple test with two menus, each with three levels. One was set up to display normally, and the other set to use LB with a per-item LB override on one of the links to add a simple block. I was able to get both of the menus to display, including children, with the patch. (And without the patch as in #25 the LB children still display, but they're completely outside of the LB manageable area.)
Tentatively moving to NW for the regression...
Thanks again!
Comment #27
freelockHi,
I'm not sure I was hitting the same issue, but I found something that makes me wonder how people could use this for megamenus at all. After spending hours in a debugger on a site with thousands of menu links, I got to the bottom of our problem at least.
On the site in question, we had been using layout builder to make a megamenu with a bunch of menu blocks, loading from another menu. This worked fine -- until the client went to add some inline blocks. This also worked fine -- for admins -- nobody else could see the blocks at all.
It all boils down to this code in \Drupal\menu_link_content\MenuLinkAccessControlHandler::checkAccess():
"administer menu" permission is needed to view menu_link_content entities, as well as MenuItemExtrasMenuLinkContent, which extends them...
And Layout Builder's inline block entity checks for dependent permissions before rendering -- e.g. to render an inline block, the user needs a positive permission to view the block itself AND to view the entity containing the layout. (I guess menu_blocks don't enforce this...).
Because only users with "administer menus" had a view permission on the menu link content entity, that made it so no normal user can see regular inline blocks added to a menu link using Layout Builder.
The fix was easy -- implement a hook_ENTITY_TYPE_access hook to grant this view access. Here's sample code:
... since doing this is one of the main goals for this module, would it make sense to add?
Comment #28
asherry commented@freelock that seems like a separate issue that might need its own ticket.
Regarding what's happening in
MenuLinkTreeHandler::processMenuLinkTree, our site is dealing with this issue on both sides.::getMenuLinkItemContentour menus with layout builder workLooking into what happens specifically with both "view" and "build", I'm realizing that "view" will call build, but, it designates that to the #pre_render process. Build is the important part, it's where all the default fields and variables are set, and it's what calls hook_entity_view, (which is what layout builder uses to process). We need all that to happen, but since we're in a "preprocess", we're already in the theme rendering. It's always going to be hard to build out an entity and all its fields in one area of the theme rendering for another area of the theme rendering.
I think maybe it might be worth re-thinking/re-factoring this from higher up. Right now everything starts from:
hook_preprocess_menu.An alternative maybe to override the service that actually builds the menu. There is
menu.link_tree, that service could be overridden and then all the logic to do an entity "view" could properly go in there. Then when that render array is rendered, it will properly call #pre_render, and then send it to the theme layer before preprocess is called.So instead of:
- build menu
- render menu
- pre_render (empty)
- preprocess
- menu item extras entity view
- menu item extras entity build
- twig file
It would be:
- build menu
- menu item extras entity view
- pre_render - build out menu item extras entity
- preprocess (variables are already available)
- twig file
Another alternative is maybe we don't need to hook into the existing block menu and this module could provide its own block plugin (with a derivative). I think that might clutter the UI, and it would be way more overhead, but it might still be a cleaner solution.
I committed a prototype to this issue's branch. There would still be other changes needed, this is just to see if everybody thinks it's a good approach. For example, we should probably also change the name
processMenuLinkTreeto something else, or maybe even combine that class into the MenuLinkTree class.Comment #29
asherry commentedAlso I hope this is ok, but, this is a problem that's in both 8.x-2.x and 3.0.x. I hope it's ok that I change this. The change I made is based on the 3.0.x branch.
Comment #30
asherry commentedSorry, I'm changing this back, I'm realizing the current merge request repository doesn't have 3.0.x and I don't have access to add it in. I might create another ticket in the meantime so I can use this patch with 3.0.x.
Comment #31
asherry commentedComment #32
volegerregarding #27 please followup a known issue in core #2915792: MenuLinkContentAccessControlHandler does not allow "view" access without admin permission, making these entities inaccessible via REST, JSON API and GraphQL and entity reference fields