#1896674: On primary navigation menu, class 'active' is not set on active menu item Added some code for setting the 'active' link class. The way this was implemented breaks other modules' logic. For instance, it completely disregards anything done in hook_preprocess_menu_link() to unset the active link and slaps it right back on there.
The least we should do is set that logic in hook_preprocess_menu_link() so other implementations can undo whatever Bootstrap did. Placing business logic in the theme hook bootstrap_menu_link() is not the best way of doing things.
Also see #1896674-11: On primary navigation menu, class 'active' is not set on active menu item for another reported problem with the code that got added.
Comment | File | Size | Author |
---|---|---|---|
#7 | only_set_active_class-2618828-7.patch | 1.56 KB | markhalliwell |
Comments
Comment #2
regilero CreditAttribution: regilero commented+1
Comment #3
markhalliwellNo patch or further complaints about it.
Comment #4
kristiaanvandeneyndeI'd agree with the "Closed (Outdated)" status if it weren't for the fact that the bug is still very much there.
The code that sets the active class should at least be moved to
bootstrap_preprocess_menu_link()
so that other modules may decide whether they want that link to show as active or not. The other code in bootstrap_menu_link() is fine because it actually relates to how you want to theme the menu link.Comment #5
markhalliwellOk. I re-read the issue(s). I'm still a little unclear as to what the "bug" is exactly.
The problem with using the "active-trail" bit is that it isn't always that accurate either in 7.x; especially if the link's href if
<front>
.Also, whether this code is in
bootstrap_menu_link()
orbootstrap_preprocess_menu_link()
doesn't really matter. They're both invoked after modules.That being said, I'll upload a patch here shortly to see if it helps with what you're talking about.
Comment #6
markhalliwellComment #7
markhalliwellActually, no need for an elseif.
Comment #8
kristiaanvandeneyndeThe issue is that there is no way to strip the 'active' class.
This is because the class will always get added back when styled unless you go out of your way to copy-paste the whole function body of bootstrap_menu_link() into mysubtheme_menu_link() just to remove the part that sets the 'active' class.
It's fine to add classes in a theme function if they are specific to your theme. The 'active' class isn't, however, and should thus be added in a preprocess function so other modules/subthemes can at least remove it again.
Comment #9
markhalliwell<li>
element. That isn't a requirement in core, hence why this is added.I'm trying to compromise here, but you're not understanding what the complexities your proposal actually entails.
The patch in #7 is, more or less, the best I can come up with. Have you tried it?
Comment #10
kristiaanvandeneyndeThe patch in #7 looks fine, but it still doesn't fix the use case where I needed to unset the active class because of this bit:
$element['#href'] == '<front>' && drupal_is_front_page()
.The use case I had was a menu that had two links to the front page and was present on every page, except each link would point to a different space (Spaces module). Consider a space a context.
Because we effectively used that menu as a "space switcher", we needed to unset the active class on the link that was not pointing to the active space. This was impossible without overwriting the theme function, for something that ideally could have been done in a preprocess function.
I still don't see how you consider the active class as something Bootstrap-specific. If you look at menu_tree_output(), menu_navigation_links(), etc. you'll see core actually sets this class regardless of the active theme. It didn't seem to break Bootstrap for me when I removed it, that is.
Anyways, the patch in #7 looks fine for what you changed the issue title to. I'm just detailing the use case I had here which is impossible to pull off with Bootstrap unless you overwrite the entire theme function.
I do understand the complexities behind what I'm discussing here, don't get me wrong. I'm simply debating whether this specific class shouldn't have been handled by a preprocess function instead.
P.S.: I don't mean to annoy you with this, even if I inadvertently have.
Comment #11
markhalliwellLike I said above, there's no other way to get the "active" class on these links. It doesn't get the
active-trail
class or even thein_active_trail
flag set on the original menu item. Not even with a helper module like Menu Trail by Path does this work. This is primarily due to the broken nature of core in 7.x and why in 8.x the entire menu system was replaced with the concept of true routes. This logic cannot be removed. Period.Honestly though, this sounds more like a fundamental architectural flaw in the decisions that were made. Using a not so widely installed (< 3k) contrib module in an attempt to provide another alternative way to solve another type of multi-site scenario. This project simply cannot cater to every single contrib/custom module that decides to do things just a little differently for their use cases. I could understand more if it was something that is a commonly used module/best practice.
I'm trying to understand here. How is copying and pasting < 40 lines of code is too difficult? I honestly cannot understand the rational behind this argument. If it were, say, regarding something extremely more complex like the
page
theme hook.. then sure, this would make sense to do. As it stands now, it literally can be replaced in a sub-theme within 5 seconds.Yes, these functions do add an
active
class, but on the link itself (#localized_options
)... not on the<li>
element wrapping it. That is what I meant by that it is unique to what Bootstrap expects for their nav components to function properly. Theactive
class that is set on the links themselves have absolutely no effect in Bootstrap.Not at all, you're perfectly fine :D A common misconception when people interact with me is that, while I may be annoyed, it's not at them personally. It has more to do with the fact that little to no information was provided to describe the issue at hand, provide steps to reproduce and justification through use cases.
As you can see here, it's taken several comments to get to a point where I actually understand what's going on here (in your situation). I have limited time and that's why the issue was closed after 8 months of... nothing. No further explanation other than "#1896674 introduced broken logic". That doesn't give me a lot to go on when no one else has really complained about this.
I'm not unsympathetic to your issue, I'm just burdened by responsibility to all for the quality and integrity of this code.
---
I still don't necessarily agree the above rational behind moving this into a preprocess function. That being said, this issue will still need a change record regardless to inform people that the logic for this has changed and if they overrode the theme function in their sub-theme, they will need to update it.
Since we're going to have to do that anyway, I suppose we can also go ahead with the move to a preprocess function. The change record can just say that they should remove the logic for this in their overridden theme function and let the base theme handle it. If they did indeed customize this
active
class logic, then they will need to move that into a sub-theme preprocess function.I'll commit a fix for all of this shortly.
Cautionary note: I may still, ultimately, revert this commit/decision if enough people complain about BC breaks. Menus are already a touchy subject in this project and many already customize it to suit their needs. I won't be all that surprised if this causes a lot of grief.
Comment #13
markhalliwellChange record: https://www.drupal.org/node/2778733
Comment #14
markhalliwellComment #15
kristiaanvandeneyndeWell, it's actually a really cool module. It's basically Domain Access, but for other ways of triggering your context (path, taxonomy, ...). It lost a lot of installs to Domain Access over the years because Spaces is more of an API whereas DA offers a good UI.
Oh, right. Subtle but important difference.
Yay, I completely agree with your reasoning.
Naturally.
Thanks for taking the time to resolve this issue!