Problem/Motivation

System module's SystemMenuBlock implementation always adds the menu active trail, including when all items are expanded, however many themes don't actually use the menu active trail active link information to change styling - e.g. the top menu or especially footer menu looks the same regardless of which page you're on.

Because the menu trail support requires adding the menu trail cache context, this can result in a lot of identical variations of main/footer menus which otherwise could be a single entry. Dropping it would also save the time from calculating the menu trail itself, which isn't that much but is non-zero.

Steps to reproduce

Proposed resolution

  • Add an additional configuration option "Show the same menu markup on every page " (ignore_active_trail) to system menu blocks to control this behaviour
  • it should only be available when menus are set to 'all items expanded' and the level is set to 1
  • Active trail cache context is not added when ignoring the active trail
  • New config property key is set as requiredKey: false so that it's optional and can be left unset
  • Making the config property optional means that an upgrade process can be pushed to after deciding on #3530727: [meta] Just in time updates and[#352122]
  • Since the config property is optional, its only possible values is TRUE. If unchecked in the form, the property is unset from the block configuration

Remaining tasks

Tagged for usability review of the block config form changes. Screenshots below.

User interface changes

Config form

Before

Admin menu block with menu levels open

Admin menu block with Expand all menu items open

After

Initial form with new "Add a CSS class..." checkbox checked and required
Admin menu block with new Add a CSS class... checkbox checked and required

Check "Expand all menu links" and "Add a CSS class" checkbox is now not required
Admin menu block form with Expand all menu links checked

Set initial visibility level to 2 and "Add a CSS class" checkbox is now required again
Admin menu block form with initial visibility level 2

Set initial visibility level to 1, number of levels to 1, and uncheck "Expand all menu links" and and "Add a CSS class" checkbox is now not required again
Admin menu block form with initial level 1, number of levels 1, expand unchecked

Introduced terminology

API changes

Add a boolean config property ignore_active_trail to menu block config schema. It is not a required key on the schema, and it is only set when it is TRUE. For any menu block with that set to TRUE, the active trail will not be computed for the menu and active trail will not be in the menu markup.

Also add validation that ignore_active_trail can be true only in one of the following conditions:

  • Initial visibility level = 1 and Number of levels to display = 1
  • Initial visibility level = 1 and Expand all menu links checked

Data model changes

Release notes snippet

Issue fork drupal-3529464

Command icon 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

catch created an issue. See original summary.

godotislate made their first commit to this issue’s fork.

godotislate’s picture

Status: Active » Needs review

MR 12375 is up.
I added tests for the active trail functionality, but I didn't do one for the #states handling in the UI. Is that needed?

Also, I wonder if there needs to be either help text in the description or more conditional logic so that the new setting isn't applied when the start level is configured to be greater than 1? Effectively it creates an empty menu if the start level is greater than 1, the menu is set to expand all items, and ignoring the active trail is enabled.

    // For menu blocks with start level greater than 1, only show menu items
    // from the current active trail. Adjust the root according to the current
    // position in the menu in order to determine if we can show the subtree.
catch’s picture

Also, I wonder if there needs to be either help text in the description or more conditional logic so that the new setting isn't applied when the start level is configured to be greater than 1

We might need both #states and config validation for that?

godotislate’s picture

Added more #states handling and the config schema validation constraint.
Also added functionaljavascript test for the form.

catch’s picture

Only thing I'm wondering here is whether instead of the negative we could use 'Use active trail' or similar.

Then the #states could only show the levels etc. options if it's checked, otherwise hidden. However that would complicate the upgrade path because we'd need to set it for existing config using those options to prevent them being hidden in the form when it's edited.

godotislate’s picture

Yeah, I went with the negative to make the upgrade path easier (NULL being the same as FALSE), despite that it makes the wording maybe a bit awkward.

Though maybe setting the value of the new property in defaultConfiguration() to TRUE makes that concern go away?

godotislate’s picture

Then the #states could only show the levels etc. options if it's checked, otherwise hidden. However that would complicate the upgrade path because we'd need to set it for existing config using those options to prevent them being hidden in the form when it's edited.

Thought about this some more. If we have the new "track active trail" (wording TBD) field control the level and expand_all_items, and assuming "level" is set to 2, or expand_all_items unchecked, then when going from "track active trail" checked to unchecked, those fields would be hidden. And the result might be a bit unexpected to the user, even if help text is provided. We'd probably also have to disable those fields when "track active trail" is unchecked, because #states can't change field values. Then in the form submit handler, we'd have to interpret those NULL values as level = 1 and expand_all_items as TRUE.

catch’s picture

Though maybe setting the value of the new property in defaultConfiguration() to TRUE makes that concern go away?

As in NULL and TRUE would be treated the same? I don't remember doing this but it seems possible. However:

Thought about this some more. If we have the new "track active trail" (wording TBD) field control the level and expand_all_items, and assuming "level" is set to 2, or expand_all_items unchecked, then when going from "track active trail" checked to unchecked, those fields would be hidden. And the result might be a bit unexpected to the user, even if help text is provided.

Yeah it starts getting complicated, good to think about how much work it would be before doing all the work.

Part of the problem might be the 'active trail' wording which is really an arcane internal menu system concept.

What about this for the checkbox label:

Show the same menu markup on every page

With description:

When this is checked, the menu will have the same markup on every page. Otherwise the current page's position in the menu structure will be calculated and an 'active' class added to relevant menu links if it is found.

And then it's only possible to have the same markup on every page if you're not showing different levels of the menu etc. so it would still (hopefully) make sense that it's only available when those options are not being used.

godotislate’s picture

Made the text changes and pushed. Thinking about this now, though:

When this is checked, the menu will have the same markup on every page. Otherwise the current page's position in the menu structure will be calculated and an 'active' class added to relevant menu links if it is found.

The class added in the core theme templates is menu-item--active-trail. There's also an is-active class added to a menu link if it is the current page, but that is added through JS. Still I wonder if "active" is not informative enough? Also, I'm not sure what the antecedent to the final "it" in the description text is.

My attempt/suggestion for an edit:

When this is checked, the menu will have the same markup on every page. Otherwise, the current page's position in the menu structure will be calculated and an "active-trail" class added to menu links in the current page's menu hierarchy.

catch’s picture

That looks good. I couldn't think of a good wording for 'the current page may or may not be in the active trail' but ""active-trail" class added to menu links in the current page's menu hierarchy." covers it implicitly really well.

godotislate’s picture

MR updated per #12.

catch’s picture

This looks great to me now.

The last remaining question for me is the nullable config. It avoids having to have an upgrade path, but it means saving menu blocks in the UI will gradually introduce the new config key over time. The other option would be to make it not nullable, and have a config entity update to add the default everywhere, as well as a hook_entity_presave() for exported config.

After discovering #3521221: Block plugins need to be able to update their settings in multiple different storage implementations I think this is probably the way we should start doing things though - e.g. allow a gradual update over time with runtime code compatibility.

godotislate’s picture

Yes, the issue with LB overrides mentioned in #3521221: Block plugins need to be able to update their settings in multiple different storage implementations, among others, is why I wanted to avoid doing an upgrade path. I think it's okay to have the config key introduced over time on block saves?

For block entities specifically, I wonder if we can change get() so that calling get('settings') will merge in configuration from the plugin collection. That way additions in defaultConfiguration() from the plugin will be picked up in the loaded block entity after a cache rebuild. That doesn't really change anything here, but it could maybe apply to other situations?

nicxvan’s picture

The issue with this is how often do these blocks get resaved?

godotislate’s picture

The issue with this is how often do these blocks get resaved?

Here, it doesn't much matter because NULL/undefined is the same as FALSE for the new property, and FALSE is always a valid value.

It'd be an issue for any new block property that doesn't work like that. What I suggested in #15 could help address that, but if there are constraints where the default value is not valid with existing configuration, that would be another problem.

A just-in-time API could maybe do address above with an optional callback parameter. If it's not passed, then the default API behavior is to merge in default configuration from the plugin, otherwise the callback function would handle any logic.

nicxvan’s picture

I was more concerned about how long we'd need to handle the missing config.

After looking at the actual code it's not really a huge concern.

alexpott’s picture

@catch asked my opinion on the nullable approach. I think it is a good one because the new key is not added during a config import so you're not getting unexpected changes. The one thing that gives me pause is how are we going to tell any modules or recipes that supply this config that they need to update. I.e. will we leave tis key as optional...

catch’s picture

@alexpott I think we'd need to leave the config key as optional permanently if nothing happens after this issue. We could open a follow-up to make it non-optional and try to implement that using the to-be-decided APIs in #3530727: [meta] Just in time updates and #3521221: Block plugins need to be able to update their settings in multiple different storage implementations though.

godotislate’s picture

Updated MR per feedback and adjusted tests.

godotislate’s picture

Issue summary: View changes
Issue tags: +Needs Review Queue Initiative

Updated the IS proposed resolution to match the work done so far.

smustgrave’s picture

Status: Needs review » Needs work

Could we update the some before/after screenshots of the new config form. May need UX sign off.

Think it would need a CR?

godotislate’s picture

berdir’s picture

Note: https://www.drupal.org/project/menu_trail_by_path adds this as a third party setting per menu as opposed to the block, so the context is still there, but by disabling it for a menu link the footer it will always have the same empty value and as a result, not vary.

This overlaps and you can then end up with a somewhat confusing situation where you enable it on the menu but not the block. Or the other way round, where it's enabled on the block but actually disabled on the menu. That means the block can force disabling it but can't force enable it.

I think that's OK and it's probably not worth to reconsider and move to the menu (and support more than one state).

catch’s picture

I haven't tested it but my understanding of doing it at the menu level would mean it would also prevent modules like menu_breadcrumb from working, where it's fine for the breadcrumb to vary by active trail because that's what you want there. So having it at the block level means you can combine a relatively static menu while also using that structure to determine breadcrumbs.

godotislate’s picture

Issue summary: View changes
benjifisher’s picture

Status: Needs review » Needs work
Issue tags: -Needs usability review

Usability review

We discussed this issue at #3536866: Drupal Usability Meeting 2025-07-25. That issue will have a link to a recording of the meeting. (See the second half of the recording.)

For the record, the attendees at the usability meeting were benjifisher, rkoller, and simohell. I am adding issue credit for them.

We all agreed that the option should be reversed. The current label (title), "Show the same menu markup on every page", does not give enough information, so the user has to read the description (help text) to figure out what it means. It is sort of like trying to describe what an option does not do instead of describing what it does.

We did not have time to recommend replacement text, but start with something like

Add the active-trail class

Maybe just use that and keep further explanation in the help text. In the help text, mention the pros and cons: the theme may style the active-trail class, but it has a performance impact.

If you want more feedback from the usability team, a good way to reach out is in the #ux channel in Slack.

benjifisher’s picture

This issue reminds me of some work I did several years ago. I even gave a few presentations on it. (The most recent is https://slides.benjifisher.info/caching-midcamp-2020.html#/strategy. I have to do something about the TLS certificate.) At the time, it did not occur to me to make the same change in Drupal core.

Why not use JavaScript to add the active-trail class? It is a lot simpler: JavaScript is really good at traversing the DOM, and the current PHP code is a little messy.

But code simplification is just a side benefit. The real advantage is that you can cache the navigation and still have the active-trail class.

benjifisher’s picture

catch’s picture

We add the 'active' class in JavaScript, which is based on 'is the link pointing to the actual page you're on', but we can't easily do that with the active trail class because it's based on a calculation of where the current page sits in the menu tree - the link can be added to the parent of the page even when the page doesn't actually show in the menu at all, the only way to add it via JavaScript would be to do an AJAX request, or calculate the active trail out of band and add it to Drupal settings or something then have javascript add it from there. It would also be JavaScript that's required to render pages to anonymous users whereas currently zero JavaScript is at all out of the box.

benjifisher’s picture

I see. That is different from what I worked on a few years ago. There, the navigation came from the book module, and it contained the full structure of the book. So all my JS had to do was find the current page in that tree and then climb up the tree, adding the active-trail class.

catch’s picture

It's complicated by the menu allowing you to show which levels to use. So you can have a four level menu, only show the top level, but the three levels underneath all impact the active trail.

godotislate’s picture

I'm not sure what the best path forward is.

After making the switch in the UI from essentially "ignore active trail" to "show active trail", if we flip the config property to match, then we end in the position of needing to update existing block configurations and how to deal with them in layout builder. We could just update global block configs, leave LB blocks unchanged, and then in code treat the "show_active_trail" property being unset to be the same as TRUE.

Alternatively, we could leave the property as "ignore_active_trail", and then in the block config form submit, flip the form value* before saving to config. I don't know if that's done anywhere else though, and it seems counterintuitive and bad DX.

*I think there's also some consideration needed on how handle the form value because the checkbox can be disabled by states, though maybe the easiest thing would be not to disable the field and only set visible/invisible.

catch’s picture

Add the active-trail class

I tried to avoid this when we originally started work on this issue, because the concept of the 'active trail' does not exist in the UI anywhere else in Drupal core and I'm not sure we should introduce it here.

By highlighting it as the checkbox label, it promotes the concept above where I think it should be for users (ideally not at all, but minimally introduced by this MR out of necessity). #33 / #34 show exactly how difficult it is to keep track of the difference between 'active' and 'active trail'.

Yet another option would be to add the configuration option without any UI, the problem with that is discoverability of what can be a very significant performance improvement.

godotislate’s picture

Yet another option would be to add the configuration option without any UI, the problem with that is discoverability of what can be a very significant performance improvement.

Random thought would be to do some sort of check in the status report, though the detection would likely be limited to globally placed menu blocks, and maaaaybe menu blocks in LB defaults. But then being able to set the config property would require some pretty technical knowledge, whether setting via drush or the config sync UI or whatever.

catch’s picture

Just to expand a bit:

The current label (title), "Show the same menu markup on every page", does not give enough information, so the user has to read the description (help text) to figure out what it means.

I think that

Add the active-trail class

has exactly the same problem, or is possibly slightly worse - e.g. only a tiny, tiny fraction of experienced Drupal users will know what the 'active trail' class is, so everyone will need to read the description anyway. But by making the active trail concept the main thing, it becomes more important to understand what it is, vs. deciding that 'yes, I do want my main menu to look the same on every page'.

benjifisher’s picture

We looked at this issue again at #3540379: Drupal Usability Meeting 2025-08-15. (Present: benjifisher, rkoller, simohell.)

We still think that something positive ("Add a CSS class") is clearer than something negative ("Be the same on all pages"). But you make a good point about not mentioning the "active-trail class" in the UI. Can we compromise on something less specific, like one of these?

  • Add a CSS class to parent links
  • Highlight the ancestors of the active menu link with a CSS class
  • Add a CSS class to ancestors of the current page
  • Add a CSS class to links leading to [or above] the current page

The goal is that the typical user will have to read the help text (description) once, and then the label should be enough when they return to the configuration form. So the label does not have to say too much. On the other hand, the help text should explain

  • This option has an effect when the block is shown on a page listed in the block.
  • It applies to all "parents" or "ancestors" of the current page that are shown in the block.
  • Adding the CSS class has performance implications.
benjifisher’s picture

@godotislate:

I think the BC problems are easier to handle than you suggested in #36.

A boolean field effectively has 3 possible values: TRUE, FALSE, or NULL. When rendering the block and inspecting the value of the new config item, treat NULL as TRUE.

Someone (@alexpott) once commented that ... ?? TRUE had a bad "code sniff" or something like that. So probably add a code comment, explaining that this is for BC.

catch’s picture

Status: Needs work » Needs review

I've rebased, and then implemented @godotislate's idea:

Alternatively, we could leave the property as "ignore_active_trail", and then in the block config form submit, flip the form value* before saving to config.

This is not what we usually do in core, but:

1. It allows the UI change to be reviewed/tested without completely re-doing all of the logic

2. The API logic for me works better with ::skipActiveTrail() as the concept, because it's not only the UI class that is related to the active trail, but also whether all menu items are expanded, whether we're starting from level 1 etc., it's just that we collapse all of those things in the UI via #states.

godotislate’s picture

Status: Needs review » Needs work
StatusFileSize
new5.32 MB

Couple questions on the MR.

I also pulled the latest changes down locally and took this screen recording.

  • Menu level 1
  • Number of levels 2
  • Expand all items
  • Add CSS class unchecked

After saving and re-opening, the dialog showed it as checked.

https://www.drupal.org/files/issues/2025-12-01/Screen%20Recording%202025...

catch’s picture

Moving this out to the issue:

So now that we're using the positive statement for the UI, I wonder if the checkbox should show as disabled and checked when it can't be interacted with. This would make the backend handling a bit more complicated, since a disabled field does not submit a value. But with the UI logic this way, it makes a little more sense to me visually to use disabled instead of invisible.

So I nearly started working on this, but we can't automatically uncheck the checkbox when the other values change, because it might already have been checked. Even if we wrote custom js for this and stored the previous state etc., it would still be weird if it was checked and unchecked based on other fields I think.

Two other options came to mind, one when I was updating things and one just now:

1. Always show the checkbox but toggle 'required' vs. not depending on the other fields.

2. Change this to radios, completely drop the states logic, rely on validation to either show an error or automatically update the radio.

godotislate’s picture

Hmm, maybe we just leave it as toggling visible/invisible then?

One more thing I noticed in testing again just now: we added the condition that a level 1 menu with depth of 1 can also ignore the active trail in the UI, but this isn't being handled in the API. I just tested and the active trail class appears when the checkbox is unchecked, and looking at the logic in build() seems to confirm. I don't think this is related to the issue in the screen recording in #43.

catch’s picture

Had one more idea which is hide the level selector when the checkbox is unchecked. And then make the checkbox required if the depth <> 1 and expanded is off (and always show the checkbox otherwise). This could be combined with changing to a radio (if we rely on validation for that last bit).

Didn't look at the API handling since diving into the form, so it's quite possible that case isn't handled yet.

godotislate’s picture

Thinking about it some more, my feeling is the best way to go would be to make the checkbox always visible. Make it required via states except when depth = 1 and level = 1 or depth = 1 and expand all items = 1. Browser validation will prevent the user needing to wait for submission backend processing to get an error message. This is also probably one of the easiest implementation paths on the FE and BE as well.

The drawback is that the user may not get great feedback about why the checkbox is required, but this might be OK compared to drawbacks with other methods.

This is just my own opinion though, and I am not a UX expert.

catch’s picture

I can give #47 a try, and then we can see how it looks in practice - it should not be a lot different than the current logic with a bit of luck.

catch’s picture

Status: Needs work » Needs review

OK the 'required' on vs not is subtle, but it feels like a clearer indication than it disappearing when it's also supposed to be on.

Updated some of the test coverage for these changes too.

catch’s picture

Also updated Umami menu config to use the new key since it only has one level of menus.

This in turn means the changes shows up on performance tests. The 'cool cache' test shows the real improvement here - the menu is now included in the site wide caches so doesn't need to be built and cached again.

godotislate’s picture

Status: Needs review » Needs work

Did some more manual testing and added MR comments to fix some form behavior with the checkbox state and saving.

catch’s picture

Those last round of suggestions fixed a bug in the implementation, which results in very significant changes to performance tests - also confirms that the umami footer block does query the menu table and active trail all the time despite having no links in it.

catch’s picture

Priority: Normal » Major
Status: Needs work » Needs review

I think this is ready for review again. Bumping priority to major because the impact here is significant.

Once this lands we should open a follow-up for Drupal CMS to configure blocks without this (assuming they're not relying on the active trail behaviour).

godotislate’s picture

I have reviewed the changes and tested with Umami locally, and this looks good.

Nice work to set the configuration the Umami footer and header menu blocks. It really demonstrates the performance gains.

I am +1 for RTBC, but since this issue has never made it to RTBC and I did a lot of initial work on the MR, I think it'd be best to get another pair of eyes for RTBC +1.

Updated the IS with new screenshots and documented API changes.

catch’s picture

Updated the change record for the new language on the form.

catch’s picture

Rebased. This takes around 12 queries off several different request scenarios, if we add it on to other recent improvements, it's taking us under the 50% threshold on some requests for queries/cache operations.

Cumulative front page performance test diff of 11.x + this MR vs. 11.2.x HEAD.

   /**
@@ -49,16 +52,16 @@ protected function testFrontPageColdCache(): void {
     $this->assertSession()->pageTextContains('Umami');
 
     $expected = [
-      'QueryCount' => 381,
-      'CacheGetCount' => 471,
-      'CacheSetCount' => 467,
+      'QueryCount' => 232,
+      'CacheGetCount' => 314,
+      'CacheSetCount' => 314,
       'CacheDeleteCount' => 0,
-      'CacheTagLookupQueryCount' => 49,
+      'CacheTagLookupQueryCount' => 27,
@@ -119,16 +122,16 @@ protected function testFrontPageCoolCache(): void {
     }, 'umamiFrontPageCoolCache');
 
     $expected = [
-      'QueryCount' => 112,
-      'CacheGetCount' => 239,
-      'CacheSetCount' => 93,
+      'QueryCount' => 68,
+      'CacheGetCount' => 176,
+      'CacheSetCount' => 75,

And node page:

@@ -115,16 +117,16 @@ protected function testNodePageCoolCache(): void {
     $this->assertSession()->pageTextContains('quiche');
 
     $expected = [
-      'QueryCount' => 191,
-      'CacheGetCount' => 210,
-      'CacheSetCount' => 65,
+      'QueryCount' => 86,
+      'CacheGetCount' => 171,
+      'CacheSetCount' => 60,

godotislate changed the visibility of the branch 11.x to hidden.

godotislate’s picture

Rebased for merge conflict in the performance test.

catch’s picture

Adding a hopeful issue tag. This will be most useful for sites with large mega menus - because they simultaneously don't need the active trail behaviour usually (all links are shown on all pages) and also have a big expensive menu to render for every active trail variation, and also have a lot of unique active trails because there's so many links in the menu.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

godotislate’s picture

Rebased and update performance tests stats to resolve merge conflict.

berdir’s picture

Status: Needs review » Needs work

> This will be most useful for sites with large mega menus - because they simultaneously don't need the active trail behaviour usually (all links are shown on all pages) and also have a big expensive menu to render for every active trail variation, and also have a lot of unique active trails because there's so many links in the menu.

Somewhat off topic, but In many cases, such mega menus still need the active trail classes to style the active section/trail. We tried a few things in a project where we not only have such a menu but the site also has dozens of sections with their own version of the menu. This results in thousands of variations of the main navigation. We experimented quite a bit with pushing things into JS, but it's surprisingly noticeable, especially when you click through multiple pages in the same section. An intermediate option is to use the depth limit option in menu_trail_by_path so that it only needs to built variations for the top-level links, but for our specific site, that's complicated too. another idea is to do some kind of post-processing in PHP, a bit like that active link class stuff.

The other aspect of the cost of these large menus is invalidation, because every time you save a node form with menu_ui for a node that's in that menu, you basically invalidate your whole site as every page has the node cache tag for every linked node. I'm working on that in #3485030: Avoid saving menu links through node form when they do not change + https://www.drupal.org/project/menu_cache.

('ve been planning on writing a blog post on all this for a while, but would love to do it after that core issue is fixed and there are actually improvements in this space).

Back to this issue. That doesn't mean that it's not useful, it is useful for various use cases, especially secondary/footer menus and is a bit more performant on that than what menu_trail_by_path is doing, but maybe not quite as much for that mega menu use case.

Posted some comments on the MR. The CR looks pretty good to me and I think clarifies the styling part. I find the last part about config import a bit confusing, why does it specifically mention that? Wouldn't it be sufficient to say "explicitly changed in the block configuration", it doesn't really matter how that's done (you could use also use drush cset, or an update function, or ...)

godotislate’s picture

I can review the MR comments later, but for now, I made the change to the CR. Wrote it a long time ago, so who knows what I was thinking then. :)

godotislate’s picture

Status: Needs work » Needs review

Added shouldSetActiveTrail() method to consolidate the logic.
Also added a blockValidate() implementation to validate the required state of the active trail checkbox when submitting via LB or any AJAX submit that bypasses browser form validation. PHPStan wanted the `void` return type declaration added, and if I tried the @return void annotation instead, PHPCS wanted a description for that, so I just added the type declaration. I checked, and the contrib module Menu Block does not implement blockValidate(), so that at least is safe.

Also, having the checkbox in the form be named ignore_active_trail while it functions as the opposite of that was breaking my brain, even though I knew what was going on. So I renamed the form element add_active_trail_class, and its value is the inverse of the ignore_active_trailconfig property.

godotislate’s picture

Rebased for performance tests again.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

I think this is ready now. There's a lot of code for validation, states, and extra careful checks to not break the active trail when it should work, but it's all pretty sensible. There are some limitations to this, but many sites have secondary/top/footer menus that do not have active trail styling and it helps with those quite a bit.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new3.15 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

godotislate’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: +no-needs-review-bot

Not sure why the bot thinks there's a PHPStan issue, but rebased anyway and tests are still passing. Back to RTBC.

catch’s picture

Rebased again.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed ba110231a9e to main and 97c31d32ebf to 11.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • alexpott committed 97c31d32 on 11.x
    feat: #3529464 Make menu trail behaviour in SystemMenuBlock optional
    
    By...

  • alexpott committed ba110231 on main
    feat: #3529464 Make menu trail behaviour in SystemMenuBlock optional
    
    By...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.