Default menu block plugin should only show enabled links

Created on 9 June 2025, about 2 months ago

Problem/Motivation

I'm profiling a site that has a large (several hundred/low thousands) number of disabled menu links in its main menu - my understanding is the links are there to support menu breadcrumbs but should never be shown in the menu block.

MenuLinkTree::buildItems() removes disabled items from the tree.

However SystemMenuBlock doesn't call onlyEnabledMenuLinks() when building the initial tree, and build/build/Items runs only menu tree link manipulators have run. As a result, access checks are called on those hundreds/thousands of disabled menu links.

This site may end up overring the menu block to optimize/customize some other things, but I don't see why we'd load disabled menu links for a visitor-facing block like this anyway.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component

system.module

Created by

πŸ‡¬πŸ‡§United Kingdom catch

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @catch
  • Pipeline finished with Failed
    about 2 months ago
    Total: 510s
    #517836
  • πŸ‡¬πŸ‡§United Kingdom catch

    This is a one-liner apart from the comment changes and performance test update.

    While the performance test only shows that the query is updated rather than the improvement itself (the Umami main menu doesn't have any disabled items) that's enough to ensure that this won't regress accidentally.

    I think having this many disabled menu links is not very common, but since we already filter the links out when building the tree after manipulators run, there's going to be no functional change for sites.

  • πŸ‡¬πŸ‡§United Kingdom catch
  • Pipeline finished with Failed
    about 2 months ago
    Total: 577s
    #517852
  • πŸ‡¬πŸ‡§United Kingdom catch

    This breaks workspaces menu integration - e.g. menu links that only exist in a workspace don't get shown in the workspace.

    There are two ways to fix that:

    1. Add an optional bool argument to ::onlyEnabledLinks() so that the condition can be removed in WorkspacesMenuTreeStorage::loadTree() - essentially undoing the optimisation added here, but only when viewing a workspaces.

    2. Bring wse_menu into core, which makes the entire tree storage workspace-enabled.

    I'll see if I can get #1 going quickly.

  • Pipeline finished with Success
    about 2 months ago
    Total: 859s
    #517896
  • πŸ‡¬πŸ‡§United Kingdom catch

    Another way to deal with the workspaces issue would be to only add the ::onlyEnabledLinks() call in SystemMenublock if workspaces isn't enabled, but that would require a ::moduleExists() check, however we could then have a follow-up for workspace-enabled menu trees which would eventually remove that @todo.

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

    Appears to be 1 open thread @catch thoughts on mstrelan comment?

  • πŸ‡¬πŸ‡§United Kingdom catch

    Replied on the MR - I think it would be a problem if that was possible, but I don't think it is for the menu block because there's no way alter this.

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

    Left 1 small question on the MR. Rest looks good.

  • Pipeline finished with Success
    17 days ago
    Total: 1204s
    #543551
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Applied the suggestion, rest LGTM :)

  • πŸ‡¬πŸ‡§United Kingdom catch

    I discusssed this with @amateescu in slack and he's not convinced that this is safe to do.

    The workspaces code operates on any code that's loading a menu tree, not only the system menu block, so it's removing the condition in cases where it could have been added from elsewhere. Unless we add some kind of explicit alter hook for the system menu block itself, it's not going to be straightforward to target this only at that block.

    Moving back to needs work and adding the subsystem maintainer review tag (even if the subsystem is more workspaces than system module.

  • πŸ‡·πŸ‡΄Romania amateescu

    One solution could be for the system menu block to add a "fake" condition to the query (like system_menu_block = TRUE), and workspaces could check for that parameter condition before removing the enabled one.

  • πŸ‡¬πŸ‡§United Kingdom catch

    #14 should work and would allow other modules to tweak the output of the plugin without completely replacing it.

Production build 0.71.5 2024