Problem/Motivation

<front> menu links do not receive active trail classes. Reports for this problem since D7 have been about the <li> element that wraps links, but the problem can apply to the anchor links as well, depending on the theme. This is the case with Olivero where both the <li> and <a> should receive active trail classes.

Steps to reproduce

  1. Install Drupal with the Standard profile and Olivero as the theme
  2. Visit the front page.
  3. Inspect the HTML of the "Home" link in the navigation menu at the top of the page.
  4. Verify that the <a> has the attribute data-drupal-link-system-path="<front>".

Expected results

The menu link's <li> should have the .primary-nav__menu-item--active-trail class and the <a> should have the .primary-nav__menu-link--active-trail class.

To verify the expected behavior create a new node of any type, add it to the menu, visit the node, and then inspect the new menu link's HTML.

Actual results

Neither the <li> or <a> have the expected classes.

Proposed resolution

Update MenuActiveTrail::getActiveLink() to check whether <front> menu links should be returned as being active for the current request.

Before:
A screenshot of HTML showing the menu link missing the active trail classes

After:
A screenshot of HTML showing the menu link with the active trail classes after applying the merge request

Remaining tasks

  • Review the MR
  • Change record?

User interface changes

With the additional classes being applied to <front> links, there could be changes to the appearance of those links. These changes will be theme-specific.

API changes

The path.matcher service is added as a dependency to the menu.active_trail service.

Original reports

I've installed the bootstrap theme in a Drupal 8 site.
In the default main menu the home link is never active.
When I'm in the home page the class="is-active" won't appear.

This issue is not confined to any one theme. This appears to be a core issue.

See screenshots:

Active class missing (illustration)

active class missing

Active After Applying Active Class

Active Property after applying active

D7 explanation:

There is a bug with the "active-trail" class not showing up on <li> for menu items with Drupal 7.14. The problem is that "active-trail" is missing for a menu link to the front page (path "<front>"), all other links have "active-trail" just fine.

The situation is also slightly different for the horizontal primary link tabs that can be switched on from theme settings Toggle display - Main menu, than they are for the vertical navigation in the Main menu block. In the horizontal tabs the front page <li> has "active" but not "active-trail". So "active" could be used to do get around this issue for horizontal menus. But unfortunately if you want the vertical menu, there is no "active" nor "active-trail".

I verified that both "active" and "active-trail" are missing with a fresh install without any added modules on Drupal 7.4 to 7.14. The behaviour is identical with Bartik, Garland and Stark themes, as well as Zen.

The current MR fixes the bug by adding special handling for the front page when adding the active-trail class.

A better solution would be to get the 'in_active_trail' variable correctly set for links to <front>, but unfortunately I could not find out how to do that.

Issue fork drupal-1578832

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

ttiurani’s picture

StatusFileSize
new1.14 KB

Attached is v2 of the patch, which is better because it does the special case handling in the place the 'in_active_trail' variable is set. With this patch caching works like it should.

ttiurani’s picture

There seems to be a bigger problem on menu.inc than just the missing "active-trail". I stumbled on a second problem when trying to create a submodule on menu_block which hides inactive menu items. Setting 'hidden' to TRUE works great for every other link except the one(s) pointing to <front>. The variable change just doesn't stick - it turns back to FALSE right after I set it. I also don't think menu_block is to blame because it doesn't do anything to the 'hidden' variable.

I found one place which is clearly wrong in menu.inc starting from line 2468:

    $path_candidates = array();
    // 1. The current item href.
    $path_candidates[$item['href']] = $item['href'];
    // 2. The tab root href of the current item (if any).
    if ($item['tab_parent'] && ($tab_root = menu_get_item($item['tab_root_href']))) {
      $path_candidates[$tab_root['href']] = $tab_root['href'];
    }
    // 3. The current item path (with wildcards).
    $path_candidates[$item['path']] = $item['path'];
    // 4. The tab root path of the current item (if any).
    if (!empty($tab_root)) {
      $path_candidates[$tab_root['path']] = $tab_root['path'];
    }

The problem is that none of these will find a link to <front>. When I add a fifth condition like this:

    // 5. 'node' matches <front>
    if ($item['path'] == 'node'){
    	$path_candidates['<front>'] = '<front>';
    }

I get a little bit further, but not too much because in menu.inc there is a lot of $map = explode('/', $path); which do not work with <front> which has path 'node'.

So the bug seems to be quite a lot bigger than I anticipated.

ttiurani’s picture

StatusFileSize
new1.14 KB

I fixed my new problem with 'hidden' not sticking by using references to values (i.e. added a few ampersands). But I don't understand why the problem was only with links to the front page and not all links.

Attached is version 3 of the patch. It is against the 7.x branch and does not have tabs or whitespace problems.

The fix isn't perfect as this only adds "active-trail" to the vertical menu, not the horizontal primary links tabs.

I hope this patch will be applied or a better solution is found to new 7.x versions.

kristofferwiklund’s picture

Status: Active » Reviewed & tested by the community

I had the same problem. When change the menu linking for "Home" link from node/6 to the li lost it's active-trail that was used for styling. After applied the patch everything worked as it should.

Might not be the best solution to special case but I don't know if there is any other way.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, fix_missing_active_trail_v3.patch, failed testing.

gagarine’s picture

I think is why using

menu_set_active_trail('my-menu','<front>')

Fail and make the menu block disappear.

I don't understand the tests than fail but we need to add some test for this patch anyway.

CowTownFarmBoy’s picture

I have this problem and am wondering if the proposed patch is really a fix or does it fail in other places. If someone is watching this is this fixed or not?

TIA

ttiurani’s picture

StatusFileSize
new1.15 KB

Attached is a fourth version of the patch with a trivial "isset($item['link_path'])" addition that should make the patch pass those tests. I don't know how to run (or write new) tests, so unfortunately I can't say for sure. Could someone run the tests again?

I don't think this patch causes any problems and it is a fix for the problem, although not very pretty. The real issue seems to be much deeper and harder to solve as I outlined in comment #2 above.

gagarine’s picture

Status: Needs work » Needs review
ttiurani’s picture

Unfortunately the v2, v3 and v4 do cause problems: when you apply the patch and press "Clear all caches", and then navigate to any other page except the front page, "active-trail" doesn't show up. And if you do go to the front page after clearing caches and get "active-trail" to show up, it stays on when you navigate to the user page, which I don't think it should. I also have managed to get "active-trail" to disappear a few times when I went back and forth to the user page and menu.

So it seems that _menu_tree_data() is too complex a method for a quick fix.

The first version of the patch, where the special casing is done in menu_tree_output() is the most stable, but doesn't fix the problem in modules such as menu_block which override that method.

So I guess the only thing to do is to fix this properly. I need to get this to work immediately so I will just do a quick fix in Menu Block.

aliyayasir’s picture

Still have this issue in drupal 7.16

drewschmaltz’s picture

Version: 7.14 » 7.17

I'm also not getting children of in the secondary menu - maybe this is related. Sort of shocked here. Fighting this and the fact that "active" never shows up for "my account".

matulis’s picture

Workaround for the <front> links
http://drupal.org/node/1571058#comment-6788662

jenlampton’s picture

Version: 7.17 » 7.19
Status: Needs review » Reviewed & tested by the community

Patch in #8 works great, thanks @ttiurani!

David_Rothstein’s picture

Version: 7.19 » 8.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D7

As far I can tell, this would exist in Drupal 8 too? Also, #10 indicates there are problems with the patch...

David_Rothstein’s picture

See also possible related issue or duplicate: #1063278: Menu item linked to <front> doesn't know its active

vortex9’s picture

I applied the patch v4 to 7.19, but it does't work

ttiurani’s picture

As I pointed out in #10, only the first version of the patch works, but it is a hack. I ended up using Menu Block to get around this problem.

vortex9’s picture

I'm using Nice menu. I can't combine Nice menu with Menu Block :(

Add this http://drupal.org/node/1571058#comment-6788662
Its works!

jenlampton’s picture

Status: Needs work » Needs review
StatusFileSize
new553 bytes
new573 bytes

Alright, this takes the approach from the comment mentioned above and adds the active class attribute in the theme function - getting around the caching issues caused by the previous approach.

Attached patches for D8, and D7.

zhangx1a0’s picture

patch #20 works great!

Screenack’s picture

Patch core at your own risk. Until core is updated appropriately, I like this solution better: http://drupal.org/node/1571058#comment-6788662

vortex9’s picture

Version: 8.x-dev » 7.x-dev

update to 7.22 and apply #20 - cool!

David_Rothstein’s picture

Version: 7.x-dev » 8.x-dev
peyman_6000’s picture

Issue tags: -Needs backport to D7

fix_missing_active_trail.patch queued for re-testing.

vortex9’s picture

gapple’s picture

Title: Class active-trail not added to <li> when linking to <front> » Class active-trail not added to li element when linking to front page

As per #2126319: <strong>Strip HTML tags for issue titles in listings</strong>, HTML tags in issue titles are not entirely escaped on the listing page, which is breaking validity.

(and has been preventing http://drupalreleasedate.com from being able to parse the page in order to get a count of issues for some time now)

jenlampton’s picture

Patch in #20 still applies cleanly to 7.32

jenlampton’s picture

Issue tags: +Needs backport to D7

adding tag back.

Status: Needs review » Needs work

The last submitted patch, 20: core-fix_missing_active_trail-1578832-20.patch, failed testing.

jenlampton’s picture

Patch in #20 still applies cleanly to 7.39

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

toomanypets’s picture

toomanypets’s picture

This work-around almost works with Drupal 8.1.8...

  1. Disable the default/standard 'Home' menu link on the 'Main navigation' menu:
    /admin/structure/menu/link/standard.front_page/edit

  2. Add a new menu link to the 'Main navigation' menu:
    /admin/structure/menu/manage/main/add?destination=/admin/structure/menu/manage/main

    Menu link title: Home
    Link: /node

But /node is shown when you hover over the Home link, and /node will be exposed to search engines... neither of these are desirable.

I believe this is another symptom of the <front> or /node or / mess.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

alison’s picture

Harrumph, any chance of a fix getting into 8.x soon, or a functional patch for D8? :( :(

(Yes I know I'm not helping....... I'll look now and see if I feel capable enough to do something to help instead of just whining........)

alison’s picture

Errrrr never mind! Apparently it "just works," we just had a config wrong (someone added the menu link via menu admin UI, and linked to the front page or node/1 -- as soon as I removed that link and instead edited node #1 and added the menu link from in there, it worked fine/no troubles).

Sorry and never mind and thanks!

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

alsator’s picture

Using superfish module has resolved it for me

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

legolasbo’s picture

Version: 8.5.x-dev » 8.6.x-dev
Status: Needs work » Needs review
Issue tags: +Needs tests coverage
StatusFileSize
new1.86 KB

I tried fixing this in the part that builds the menu tree, but time constraints on my project force me to take the template_preprocess_menu() route.

legolasbo’s picture

Version: 8.6.x-dev » 8.5.x-dev

Shouldn't have changed the version. Sorry

Status: Needs review » Needs work

The last submitted patch, 43: 1578832-43.patch, failed testing. View results

legolasbo’s picture

Status: Needs work » Needs review
StatusFileSize
new489 bytes
new1.91 KB

Previous patch caused fatal errors with external urls,

Status: Needs review » Needs work

The last submitted patch, 46: 1578832-46.patch, failed testing. View results

jenlampton’s picture

Patch in #34 still applies cleanly to Drupal 7.59.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

lamp5’s picture

I can confirm that code from #46 works well. I use it as my theme preprocess until it will be tested and committed to core.

martijn de wit’s picture

Tried patch #48 as described in #50

When I visit the frontpage. Not only the frontpage link < li > is in the active-trail. But also all siblings.

<ul class="nav navbar-nav">
  <li class="nav-item active">
    <a href="/" class="nav-link active is-active" data-drupal-link-system-path="<front>">Home</a>
  </li>
  <li class="nav-item active">
    <a href="/2" class="nav-link active" data-drupal-link-system-path="node/4">link2</a>
  </li>
  <li class="nav-item active">
    <a href="/3" class="nav-link active" data-drupal-link-system-path="node/5">link3</a>
  </li>
  <li class="nav-item active">
    <a href="/4" class="nav-link active" data-drupal-link-system-path="node/6">link 4</a>
  </li>
</ul>
pdenooijer’s picture

StatusFileSize
new2.07 KB

Improved patch 46:

  • Use PathMatcher->isFrontPage() to check if preprocess is needed.
  • Add extra instanceof Url checks to make sure no WSOD occur.
  • Check if the menu item Url object isRouted instead of isExternal, as only isExternal could still throw an exception if an invalid internal route is in the menu items.
pdenooijer’s picture

Status: Needs work » Needs review
lukassykora’s picture

StatusFileSize
new2.22 KB

This version is working for me.

Status: Needs review » Needs work

The last submitted patch, 54: menu-class-active-trail-1578832-54.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

pdenooijer’s picture

Status: Needs work » Needs review

Sorry lukassykora but your patch is just a less defensive version of my patch and it failed the tests, so changing it back to review on my patch.

mishac’s picture

The patch in 52 seems to make *all* links on the front page have the "active-trail" class instead of just links to the front page :(

adamtong’s picture

StatusFileSize
new43.73 KB

i found a work-around for this issue, just create a disabled menu item for the true home page (e.g. /node/1) under home link.

lpeabody’s picture

Version: 8.6.x-dev » 8.9.x-dev
Status: Needs review » Reviewed & tested by the community

The patch in #52 applied cleanly on 8.7.8 and it worked for me. I cannot confirm the side effect mentioned in #57 - every menu link looks like it has the appropriate classes and only links representing the current page show as is-active.

martijn de wit’s picture

Added an automated test for 8.8 and 8.9 to the patch #52.

Hopefully this can be committed soon.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs tests coverage +Needs tests

I think #60 is missing a patch. This issue needs an automated test in order to be committed.

joseph.olstad’s picture

@Martijn de Wit, can you please dig up the automated test that you wrote and somehow failed to upload to this issue?

joseph.olstad’s picture

Version: 8.9.x-dev » 9.0.x-dev

patch #52 still works great! Just tested it manually.

@Martijn de Wit, could you please find that automated test you wrote 5 months ago and somehow failed to upload?

joseph.olstad’s picture

StatusFileSize
new2.04 KB
new2.07 KB

Had to reroll patch 52 for Drupal 9.0.x

So to simplify I up uploading two patches, one for 9.0.x and the other for 8.9.x/8.8.x/8.7.x

patch 8 is for D7, still applies cleanly, I'll split that into a new seperate D7 issue

joseph.olstad’s picture

Issue summary: View changes
StatusFileSize
new188.27 KB
new189.63 KB

Active class missing (illustration)

active class missing

Active After Applying Active Class

Active Property after applying active

joseph.olstad’s picture

Issue summary: View changes
martijn de wit’s picture

no, sry

joseph.olstad’s picture

after a few weeks of testing, patch 64 has regressions, it caused more than one link to have the active trail classes on the same page

I backed off the patch and removed it from our build.

As a workaround , our links for both of our languages are on one menu, internal links are fine, for external links we're using a workaround with css using a contrib module which allows specifying a class to the link. There's other ways to work around the external links I've used this method and another is to use also html lang attribute then the a element css selector on the href attribute based on a pattern to hide or show the opposite language external link.

Using one menu for both languages our active trail works fine. I'm not sure about the site default page issue haven't noticed it yet.

Anyhow, the patch 64 was derived from the others and I backed it off, no longer using it, doing a workaround instead.

previously we had menus for the default language and another different menu with another language and used block visibility on language for this, but this method proved to break the active trail for the 'other' language. So workaround is to use one menu for both our languages as I mentioned in this comment.

hope this helps.

xjm’s picture

Version: 9.0.x-dev » 8.8.x-dev

We should fix this bug in D8 too, so filing against 8.8.x (which is the current bugfix support branch). The issue will be automatically updated to 8.9.x after the last 8.8.x bugfix release. Thanks for juggling all the different patches for this fix!

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

nicholasthompson’s picture

Just applied patch 64 before reading comment 69... Can confirm 64 adds the in_active_trail too generously 😉

nicholasthompson’s picture

Ahh so the problem for me is that the frontpage is a node (node/1). So:

$validHomepageRoutes = ['', $homepageUrl->getRouteName()];

This contains and "entity.node.canonical" so every menu item that is front or a node gets flagged.

joseph.olstad’s picture

This being not fixed leaves us wanting to fix this.

challenges:

  • keep active trail functionality working for all links even if they are in another language
  • ensure wcag keyboard navigation is not broken by our workaround, which we wouldn't have to do if this issue was fixed.
  • wcag keyboard navigation fix is required because hidden links in a menu are not tabbable and since we display:none the other language link using an eng-only and fra-only / esp-only / jap-only class that goes something like html['lang='fr'] .eng-only { display:none; }
  • this breaks wcag , so go further into javascript now, and remove the .eng-only elements something like $(html['lang='fr']).find('.eng-only').remove(); using jQuery (actual code we're using is not exactly this but just for an idea).
  • By removing the display:none element from the html dom, the keyboard tab works and keyboard menu navigation works hence we can conserve our wcag compliance and accessibility

rather than do these workarounds, we would like to add a menu block per language allowing us to have unique weights for menu links and not have to fuss about external link translation for the url which is not always the same , often each language has an external link equivalient but for whatever reason (maybe explained above) this breaks the active-trail likely due to the bug mentionned above.

Currently we're working around this issue by using the https://www.drupal.org/project/menu_link_attributes menu_link_attributes module to provide a class attribute for links. We put this together on the same menu for both languages instead of a menu for each language (weights is another issue)

We want to make sure to maintain active trail functionality in both languages, there's the active class that indicates that the current link is what we're presently on, this is part of the menu functionality we didn't want to break and also keyboard navigation, due to wanting active trail to work in both languages we used one menu for two languages instead of two menus due to us wanting to work with what works for active trail menu links, one menu, links of all languages, internal links are no problem as they have a label that is translated and the internal link is automatically generated however external links like this one required a change in implementation to both the javascript and css, so we put a eng-only class on the english link that puts display: none on for the english link in french and a fra-only class on the french external link and there's another class attribute also, Drupal will render both links , css hides the other language external link, HOWEVER this does not fully allow wcag compliance in my recent wcag audits, SO we wrote some javascript to remove the other language link after the page is ready before the user navigates with the keyboard so when the menu link is configured as such using the specified class the javascript will also kick in and actually remove the other language link from the front end display which allows keyboard navigation to function correctly (wcag compliance, keyboard navigation is required). So the page renders, the css hides the other language link so it is never visible, then the javascript kicks in and removes the other language link from the html and thus we are able to pass wcag keyboard navigation and use the keyboard and tab key as expected.

it could be easier!

lpeabody’s picture

Assigned: Unassigned » lpeabody
Status: Needs work » Active

I'm going to try and address this in MenuTreeStorage::loadByRoute. Reasoning for this:

Assume you have the front page set as /node/1234. Also assume you have a menu named main and that menu has a single link which uses <front>.

Given the above, currently if you were to attempt to invoke MenuTreeStorage::loadByRoute('entity.node.canonical', ['node' => 1234], 'main'), you would get no results, even though that node is the front page.

I think the best course of action here is for the service to be aware of whether or not the passed route name/parameters represents the front page, and if it does then make the 'route_name' portion of the query part of an OR condition, where that condition also checks for <front>.

EDIT: I realize I didn't explain why this actually solves this issue. Which menu items get flagged as active comes from Drupal's menu.active_trail service. That service uses the current page's route match to get the page's route name and parameters, and invokes the aforementioned function to get the active link, and then it gets that links parents to build the rest of the trail.

The current page's route match will never, ever be the <front> route, it will always be what the actual route object is for that page in the system. So, we have to help MenuTreeStorage understand what the front page is.

lpeabody’s picture

Assigned: lpeabody » Unassigned
Status: Active » Needs work

Opened a MR with a somewhat rough implementation of where I think this needs to go. My local testing has been positive so far, and it appears to fix this issue in its entirety. I am not sure what kind of performance hit this adds. Still needs automated tests.

lpeabody’s picture

Yeah don't use the above branch for anything yet, lots of failed tests relating to cyclic dependencies, I'm hoping to be able to dig into it later today.

pfrenssen’s picture

This is the circular reference error thrown that is mentioned by @Ipeabody:

Circular reference detected for service "plugin.manager.menu.link", path: "plugin.manager.menu.link -> router.no_access_checks -> route_enhancer.param_conversion -> paramconverter_manager -> drupal.proxy_original_service.paramconverter.menu_link".

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
neograph734’s picture

I've previously also noticed some weird behavior in the active trail when the homepage contained a query string (example.org?foo=bar). Weirdest that I fgured out is that there is also JavaScript involved. If you disable Javascript the front page never gets an active trail class.

Linking as relevant issues.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dcam’s picture

The following workaround code was adapted from #64. It corrects the problem of flagging all routes of the same name by also comparing the route parameters.

/**
 * Prepares variables for block__system_menu_block templates.
 *
 * Work around an issue where front page menu links are not set in the
 * active trail.
 *
 * Default template: block.html.twig.
 *
 * @see https://www.drupal.org/project/drupal/issues/1578832
 */
function my_theme_preprocess_block__system_menu_block(&$variables) {
  if (!\Drupal::service('path.matcher')->isFrontPage()) {
    return;
  }

  $homepage_path = \Drupal::config('system.site')->get('page.front');
  $homepage_url = \Drupal::service('path.validator')->getUrlIfValid($homepage_path);
  if (!$homepage_url instanceof Url) {
    return;
  }

  foreach ($variables['content']['#items'] as $key => $item) {
    /** @var \Drupal\Core\Url $url */
    $url = $item['url'];
    if (!($url instanceof Url) || !$url->isRouted()) {
      continue;
    }

    $is_front = $url->getRouteName() == '<front>';
    $is_configured_route = $url->getRouteName() == $homepage_url->getRouteName() &&
      $url->getRouteParameters() == $homepage_url->getRouteParameters();
    if ($is_front || $is_configured_route) {
      $variables['content']['#items'][$key]['in_active_trail'] = TRUE;
    }
  }
}

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

dcam’s picture

Title: Class active-trail not added to li element when linking to front page » Class active-trail not added to li element <front> menu links
Issue tags: -Needs tests

I disagree with the approach in the previous MR that made MenuTreeStorage::loadByRoute() load front page routes. It violates the single responsibility principle and will result in unexpected behavior for calling code.

My own approach is to add a check for the front page to the menu.active_trail service's getActiveLink() function. That function is responsible for determining whether a menu is in the trail or not. <front> is effectively an alias for the front page route. So if anything needs to compensate for these non-standard <front> links, that seems like the most appropriate function to do it.

That said, I was a little confused at first because the docblock for MenuActiveTrailInterface::getActiveLink() is misleading:

  /**
   * Fetches a menu link which matches the route name, parameters and menu name.
   *
   * @param string|null $menu_name
   *   (optional) The menu within which to find the active link. If omitted, all
   *   menus will be searched.
   *
   * @return \Drupal\Core\Menu\MenuLinkInterface|null
   *   The menu link for the given route name, parameters and menu, or NULL if
   *   there is no matching menu link or the current user cannot access the
   *   current page (i.e. we have a 403 response).
   */

There is no "given route" because you don't pass a route to the function. Instead, it gets the current route from the current_route_match service. There's some code smell going on here. I assert that the docblock in the interface is incorrect and needs to be changed. I updated it to say that it looks for a menu link for the currently active route, although even that can't be guaranteed by the interface. There's an argument that the docblock change should be a separate issue, but since we're altering the behavior of this function to look for "alias" links that should be active for the current route, then I argue that it's an appropriate change for this issue.

The lack of route injection for the function also made the test harder to write. I tried to make a kernel test, but eventually punted on that and made a functional test that checks for Olivero's active trail class. I don't like it, but I couldn't figure out how to do it any other way. If someone has suggestions, please let me know.

dcam changed the visibility of the branch 1578832-tree-storage-check-front to hidden.

oily changed the visibility of the branch 1578832-tree-storage-check-front to hidden.

oily’s picture

oily’s picture

@dcam There seems to be a test has got broken. Line 126 of SystemMenuBlockTest.php seems root of the problem?:

  // This creates a tree with the following structure:
    // - 1
    // - 2
    //   - 3
    //     - 4
    // - 5
    //   - 7
    // - 6
    // - 8
    // With link 6 being the only external link.
    $links = [
      1 => MenuLinkMock::create(['id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0]),
      2 => MenuLinkMock::create(['id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => ['foo' => 'bar'], 'weight' => 1]),
      3 => MenuLinkMock::create(['id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2]),
      4 => MenuLinkMock::create(['id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3]),
      5 => MenuLinkMock::create(['id' => 'test.example5', 'route_name' => 'example5', 'title' => 'title5', 'parent' => '', 'expanded' => TRUE, 'weight' => 4]),
      6 => MenuLinkMock::create(['id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'bar_bar', 'parent' => '', 'weight' => 5]),
      7 => MenuLinkMock::create(['id' => 'test.example7', 'route_name' => 'example7', 'title' => 'title7', 'parent' => 'test.example5', 'weight' => 6]),
      8 => MenuLinkMock::create(['id' => 'test.example8', 'route_name' => 'example8', 'title' => 'title8', 'parent' => '', 'weight' => 7]),
    ];
oily’s picture

Added tags including an issue summary update: the current issue summary dates back to Drupal 7. Before and after screenshots for Drupal 11 are needed. The steps to reproduce could be simplified.

Another thing is, it states in the current Issue summary:

A better solution would be to get the 'in_active_trail' variable correctly set for links to , but unfortunately I could not find out how to do that.

This should be investigated.

There is now a failing test so test coverage is in place. There is currently one broken kernel test that needs to be fixed before the issue can be reviewed.

oily’s picture

Issue summary: View changes
oily’s picture

Have updated the Issue summary so it makes more sense in relation to Drupal 11.

There is more work to do. The screenshots need to be updated for Drupal 11 and any discrepancies with the existing D8 and D7 sections in the issue summary can be rectified.

To improve readability, the latest issue summary template should be used.

dcam’s picture

Title: Class active-trail not added to li element <front> menu links » Class active-trail not added to li element of <front> menu links

@dcam There seems to be a test has got broken.

Yeah. I saw that. But it was well past quitting time for the day, so I haven't tried to debug it. That's why I didn't set the issue status to Needs Review. Just from glancing at the backtrace it looked like the change to the service either broke the system menu block or maybe just the test. I'm not sure which.

oily’s picture

@dcam Great work. This is a long-standing bug!

dcam’s picture

SystemMenuBlockTest was failing because it mocks all the routes. But when the menu links were being built for the block they went through the path.matcher service which checked for the existence of the routes. Since they didn't actually exist it threw exceptions. I mocked the service to fix the test.

dcam’s picture

Status: Needs work » Needs review
oily’s picture

@dcam Great!

dcam’s picture

Issue summary: View changes
StatusFileSize
new29.38 KB
new31.62 KB

Issue summary update

dcam’s picture

Title: Class active-trail not added to li element of <front> menu links » <front> menu links are missing active trail classes
Issue tags: -Needs issue summary update
smustgrave’s picture

Status: Needs review » Needs work

Left some comments on MR

Thanks

dcam’s picture

Issue tags: +Needs tests

A kernel test needs to be created to verify the fix.

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

vidorado’s picture

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

I’ve contributed my two cents and implemented it as a unit test, as the necessary mocking was straightforward, just like in the existing MenuActiveTrailTest unit test.

I've tested the MenuActiveTrail::getActiveLink() method, which should return the first <front> route menu link when the current page is the front page and corresponds to a route without its "own" links. This scenario occurs in a default fresh Drupal installation, where the home page is the view.frontpage.page_1 route and the main navigation menu has only a "Home" link provided by the system core module for the route <front>.

smustgrave’s picture

Status: Needs review » Needs work

Super close, just 1 more comment.

vidorado’s picture

Status: Needs work » Needs review

That was a hard one! :)

smustgrave’s picture

Status: Needs review » Needs work

Thanks! just needs a rebase now and think it's good to move up

vidorado’s picture

Status: Needs work » Needs review

Oops! I'm sorry, I was so focused on the test pipeline passing that I overlooked the merge conflicts :)

Thanks for the review!

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, believe this is good to go now.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. 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.

dcam’s picture

Status: Needs work » Reviewed & tested by the community

Updated the target branch. Restoring RTBC status.

oily’s picture

@dcam just re-ran the one failing test. Test that failed, error mentioned CKeditor. Cant see the connection?..

oily’s picture

Pipeline green, test only test fails as it should.

dcam’s picture

Thanks @oily. I forgot to check on the test results after I rebased the MR to make certain it would still apply after all the recent commits to Core.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. 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.

joseph.olstad’s picture

Status: Needs work » Needs review
dcam’s picture

Status: Needs review » Needs work

I'm going to have to iteratively update the StandardPerformanceTest to account for the changes to the cache as a result of the bug fix. Because for some reason my local environment doesn't want to run FunctionalJavascript tests today so that I can do this in one commit.

vidorado’s picture

I could help you out if you want. Let me know here or contact me in slack :)

dcam’s picture

Status: Needs work » Needs review

All the tests are green again. I'm setting this back to Needs Review instead of RTBC only because this wasn't a simple rebase this time. I had to make adjustments to the expected values in the StandardPerformanceTest. They're probably innocuous, but someone should look them over.

vidorado’s picture

Status: Needs review » Reviewed & tested by the community

The new numbers look reasonable to me

dcam’s picture

I rebased again due to a merge conflict caused by this morning's commits to Core. This was an easier rebase than the last one, so I'm leaving it at RTBC.

drupgirl’s picture

Version: 11.x-dev » 10.4.x-dev
Status: Reviewed & tested by the community » Needs work

Marking as needs work, as this patch does not apply to 10.4.

vidorado’s picture

Status: Needs work » Reviewed & tested by the community

That's normal @drupgirl, it has to apply to the last major development branch (11.x in this case)

You can make a backport and publish it here as a patch, for others.

vidorado’s picture

Version: 10.4.x-dev » 11.x-dev
dcam’s picture

Sorry for all the rebasing spam. I've been trying to keep this up to date despite all of the other recent commits. Practically every change to the performance test forces a rebase and update of this MR.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. 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.

dcam’s picture

Status: Needs work » Reviewed & tested by the community

I rebased the MR against 11.x again. Restoring RTBC status.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. 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.

dcam’s picture

Status: Needs work » Reviewed & tested by the community

Rebased again.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. 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.

dcam’s picture

Status: Needs work » Reviewed & tested by the community

Rebased. Again. Restoring RTBC.

nod_’s picture

Looks good to me but outside my scope

longwave’s picture

Status: Reviewed & tested by the community » Needs work

Looks good to me too but we need to do the deprecation dance in the constructor because there are existing contrib modules that extend this service.

dcam’s picture

Status: Needs work » Needs review

I responded to all MR feedback and made the suggested changes. I don't have a good explanation for the typehint removals though.

catch’s picture

Status: Needs review » Needs work

Apparently PHP blows up with a fatal error if they're typehinted. See the results of https://git.drupalcode.org/issue/drupal-1578832/-/pipelines/476013. I don't really get why.

Oh I get it now - CacheCollector doesn't type hint the class, so they can't be constructor property promoted and also type hinted.

In this case what we need to do is remove the constructor property promotion, and add back the type hints.

Needs work for that but I think this is ready otherwise.

oily’s picture

Recent commits trying to achieve #138. I think need to add back in 2 of the params following the same typehint-no-constructor-property-promotion pattern. Also need to figure out which params to put in parent and which to put in the current class constructors.

dcam’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new2.59 KB

I'm daring to self-RTBC this because:

  • The update was requested by a core committer who said the MR would probably be ready afterward.
  • The update removed somewhat arbitrary code style changes in the MR.
  • The update simplified the diff.

But since there are a lot of commits that have happened since #138 I figure that a good, old-fashioned interdiff wouldn't go amiss.

dcam’s picture

This needed yet another rebase due to performance test changes.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work

Left a comment on the MR regarding the deprecation link.

There's also a performance impact here, I've pinged catch about whether we need to fix that here or in a followup.

larowlan’s picture

Discussed with @catch and he was ok with adding the 'load multiple' equivalents in a follow up
Can we get that issue added and update the code in MenuActiveTrail service to add a @todo pointing to the new issue?
That plus a change record (and update the link) and this can go back to RTBC, self RTBC is fine as its only comment/deprecation changes.

Thanks!

dcam’s picture

Status: Needs work » Reviewed & tested by the community

Can we get that issue added and update the code in MenuActiveTrail service to add a @todo pointing to the new issue?

Follow-up issue: https://www.drupal.org/project/drupal/issues/3523497

This needs to link to a change record rather than the nid of the issue

Change record: https://www.drupal.org/node/3523495

Thanks again!

  • larowlan committed c706bf19 on 11.x
    Issue #1578832 by dcam, oily, vidorado, ttiurani, joseph.olstad,...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +Bug Smash Initiative

Committed to 11.x
Published the change record.
Whilst this is a bug it is not eligible for backport because of the constructor BC change.

Thanks all, great to see this one finally resolved!

berdir’s picture

PSA: This broke menu_trail_by_path due to the constructor changes in a way that confused me a bit.

What that module does is alter the service like this:

$definition = $container->getDefinition('menu.active_trail');
    $definition->setClass('Drupal\menu_trail_by_path\MenuTrailByPathActiveTrail');
    $definition->addArgument(new Reference('path.validator'));
    $definition->addArgument(new Reference('router.request_context'));
    $definition->addArgument(new Reference('language_manager'));
    $definition->addArgument(new Reference('config.factory'));

So it gets the new argument added here but then its constructor doesn't expect that.

Don't see how this could do anything different, turns out that's a bad pattern for extending a constructor. Will switch to setters or autowire in #3524724: MenuActiveTrail::__construct() changes in Drupal 11.2 conflict with service alteration

quietone’s picture

The change record for this issue is a repeat of the deprecation message. It should include an example of before and after as well.

Status: Fixed » Closed (fixed)

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

xjm’s picture

Title: <front> menu links are missing active trail classes » [already commited but followup for CR?] <front> menu links are missing active trail classes
Issue tags: +Needs followup

Were #148 and #149 addressed?

quietone’s picture

Assigned: Unassigned » quietone

Assigning to myself to followup in a week or so

dcam’s picture

Since I originally authored the CR I took responsibility for updating it with the before/after examples. But I'm going to leave the issue metadata the same so @quietone can review my changes and address #148 if necessary.

quietone’s picture

Assigned: quietone » Unassigned

@dcam, thanks for updating the CR. Providing extra detail, even for this straightforward deprecation, makes it clear what needs to be done.