Children block not rendering children in Layout Builder

Created on 26 August 2020, over 4 years ago
Updated 6 June 2023, over 1 year ago

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

πŸ› Bug report
Status

Needs review

Version

2.0

Component

Menu settings

Created by

πŸ‡¬πŸ‡§United Kingdom Syntapse

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Status changed to Postponed: needs info about 2 years ago
  • πŸ‡ΊπŸ‡ΈUnited States dalemoore

    Is 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 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.

  • Status changed to Needs work almost 2 years ago
  • πŸ‡¬πŸ‡§United Kingdom AndyF

    Thanks 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!

  • πŸ‡ΊπŸ‡ΈUnited States freelock Seattle

    Hi,

    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():

      protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
        switch ($operation) {
          case 'view':
            // There is no direct viewing of a menu link, but still for purposes of
            // content_translation we need a generic way to check access.
            return AccessResult::allowedIfHasPermission($account, 'administer menu');
    

    "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:

    /**
     * Implements hook_ENTITY_TYPE_access().
     */
    function my_module_menu_link_content_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
      if ($operation == 'view') {
        return \Drupal\Core\Access\AccessResult::allowed();
      }
      return \Drupal\Core\Access\AccessResult::neutral();
    }
    

    ... since doing this is one of the main goals for this module, would it make sense to add?

  • πŸ‡ΊπŸ‡ΈUnited States asherry

    @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.

    • If we remove the extra call to ->build() in ::getMenuLinkItemContent our menus with layout builder work
    • If we leave it in, all other menus work, but the menus with layout builder break.

    Looking 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.

    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'd like to see what people think of this before I dive into anything, but, I would definitely build out a prototype and see if this might work if people think it's worth exploring, or maybe this is something that's already been tried.

  • πŸ‡ΊπŸ‡ΈUnited States asherry

    Also 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, any prototype I do would be for the 3.0.x version.

  • πŸ‡ΊπŸ‡ΈUnited States asherry

    Sorry, 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.

  • Status changed to Needs review over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States asherry
Production build 0.71.5 2024