The function menu_link_get_preferred() returns sometimes the wrong menu item.
In my case, I have a website with i18n and i18n_menu.
I have a view with the path /news. This path is aliased for another language, let's say in french : /actualites.
Then I have a single menu in which I put menu items for each language. I set a language for each menu item.
The problem is that the function menu_link_get_preferred() looks for the router path, not the alias, and doesn't take care of the item language when searching for a menu item candidate.
Would it be possible to add a tag to the query inside menu_link_get_preferred() or add a drupal_alter to filter query results?
Just as suggested here : http://drupal.org/node/881322#comment-4866066
For more information, please see this issue : #881322: Multilevel menu fails to create active menu trail with same link_path in different languages.
Another reason to alter this query is to allow the sorting of duplicate menu items, which allows the active menu trail to use an item other than the last one entered. For example, if, say, node/1 was placed in the same menu in two different places, the second placement would be the active menu trail. With this tag, and an implementation of hook_query_alter() or hook_query_TAG_alter(), the first item can be used instead, allowing the original menu placement to remain in the active trail.
Comments
Comment #0.0
ludo.rmore info
Comment #1
berdirMisread.
Comment #2
berdirComment #3
EtienneRd commentedThere's a tag translatable added many times in Drupal Core, but not used (there's no hook_query_translatable_alter()), that could be added.
Adding it in
menu_link_get_preferred()query would allow i18n_menu to alter it and then filter by language the results.See #881322: Multilevel menu fails to create active menu trail with same link_path in different languages for the upcoming patch to i18n_menu.
Comment #4
EtienneRd commentedApparently, using translatable tag, since it's being used in
_menu_build_tree()is creating issues when administrating translations with the patch I posted in the i18n_menu issue.I simply fixed it, since this tag is NEVER user in the Drupal Core, by deleting its addition in
_menu_build_tree().Applying the joined patch will make the patch I posted in this issue work without any failure.
Comment #5
berdirWrong fix, you should instead use a different, new tag for the query. translatable has a specific purpose (that is not really used anywhere, but that's a different topic, just removing it is not an option as someone out there might rely on it).
Als updated the title and this will need to be added to 8.x first and then backported.
Comment #6
EtienneRd commentedI agree that using an existing tag could cause some issues to users who might be using it.
So I created translatable_preferred_menu_links tag, and I added it to
menu_link_get_preferred().Here's the patch.
I'm posting a patch related to this one in the i18n menu issue.
Comment #7
harrrrrrr commentedThis patch, combined with the one mentioned in the i18n menu issue works when you have a single menu in which you put menu items for each language.
Comment #8
David_Rothstein commentedAs mentioned above, this needs to go into Drupal 8 before it can be considered for backport.
Also, the code comment needs some editing for grammar (or maybe remove the comment altogether? - not sure if it's actually necessary).
Comment #9
czigor commentedI have the same problem as in the issue description. I can confirm that #6 works for D7.
Comment #9.0
czigor commentedfix link
Comment #10
weri commentedA solution with a query tag would be great, but this tag should not translation specific as in the patch #6 ("translatable_preferred_menu_links"). More like "preferred_menu_links" in case we have to alter the preferred menu link in other situations, when multiple menu links use the same link path.
Or would it a better solution when this manipulation is possible over a hook like "hook_menu_link_get_preferred_menu_link($menu_links)" after the query?
Comment #11
jeffamI, too, needed a way to alter the query in menu_link_get_preferred(), and adding a tag was the perfect way to do it.
In my (client's) case, they were adding the same node twice into the same menu, and the second menu item was always activated when they wanted the first one to be.
I suspect that this is because, lacking any order by clause on the query in that function, rows were returned in the order created and the newest one (i.e. the one with the highest mlid) became the preferred candidate for the given path.
With the tag added, I am able to do a simple:
weri's suggestion to use a more generic tag made sense to me, so that's the one I used.
Lastly, I switched this back to Drupal 7 because the query in menu_link_get_preferred() has been replaced with a call to entity_load_multiple_by_properties() (I guess menu links are entities in D8?) and I have no idea how to alter that result set.
Comment #12
weri commentedI reviewed and tested the patch #11. It works as expected and I think it's RTBC.
Comment #13
david_garcia commentedPatch #11 is good.
Comment #15
David_Rothstein commented11: menu.inc-preferred_menu_links_tag-1854134-11.patch queued for re-testing.
Comment #16
David_Rothstein commentedGuess this goes back to RTBC if the test failure was a fluke.
Comment #18
David_Rothstein commentedComment #19
David_Rothstein commented11: menu.inc-preferred_menu_links_tag-1854134-11.patch queued for re-testing.
Comment #21
David_Rothstein commentedComment #22
jmking commented11: menu.inc-preferred_menu_links_tag-1854134-11.patch queued for re-testing.
Comment #23
jmking commentedThere we go. Patch passed testing now.
I'd really love to see this get committed. I'm trying to solve the same issue as jeffam in #11. In fact, I was trying to write a module that would let users specify which of several redundant menu links would act as the "canonical" one. In digging through the code to figure out how Drupal decided which is the preferred menu link, I came to this query and noticed there's currently no way to hook into it, or alter the menu_link_get_preferred output in any way.
Comment #26
David_Rothstein commentedBack to RTBC assuming that was a testbot fluke.
Comment #29
dcam commentedComment #32
dcam commentedComment #35
dcam commentedComment #38
dcam commentedComment #41
dcam commentedComment #44
dcam commentedComment #47
dcam commentedComment #48
David_Rothstein commentedCommitted to 7.x - thanks!
(And yeah, I think there is no aspect of this patch that is relevant for Drupal 8 anymore.)