MenuItem route should not inherit language from menu

Created on 29 September 2023, 9 months ago
Updated 18 January 2024, 5 months ago

Problem/Motivation

MenuItem's route entity is always in Menu's language regardless of request language.

Steps to reproduce

- Have multilanguage site. For example English default and German.
- Have your menu's language English
- Add menu link referencing a node.
- Enable translation for Menu links
- Create German translations of menu links.
- Create German translation for node referenced from menu link.
- Make request in German

menu(name: MAIN) {
    items {
      title
      url
      route {
        ... on RouteInternal {
          entity {
            ...on NodePage {
              title
            }
          }
        }
      }
    }
}

See that title and url are German but route > entity > title is in English.

This is caused by this code in MenusSchemaExtension.php:
First

// Set the menu language context.
$builder->context('langcode', $builder->callback(
  fn (?MenuInterface $menu) => $menu?->language()?->getId())
),

In our case it is always English regardless of request's language.
Then for MenuItem:route:

$builder->produce('url_or_redirect')
  ->map('path', $builder->fromParent())
  ->map('language', $builder->fromContext('langcode')),

In our case it is always English regardless of request's language.

Proposed resolution

For url_or_redirects's language get value from Url's option or just use request language.

Another option could be adding language argument to menu query.

🐛 Bug report
Status

Fixed

Version

2.1

Component

Code

Created by

🇧🇾Belarus Yury N

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Yury N
  • 🇦🇺Australia AlMunnings Melbourne

    Ahh I thought I was helping when I made that change. Obviously not!

    I observed that the menu() query was inheriting the route() queries language in the same request without any real instruction, possibly off the static cache context. Which looked a little buggy to me. So I locked it down.

    Seems safest to make the language arg explicit on the menu() query to load the correct language on the menu link, then set the route language off the resulting url’s option.

    Does that sound right? Basically do what you say 😅

    Really appreciate the help with the multi lingual stuff!

  • 🇧🇾Belarus Yury N

    Yes, language argument would be great

    • almunnings committed 93eb7331 on 2.0.x
      Issue #3390590: MenuItem route should not inherit language from menu
      
  • Status changed to Needs review 9 months ago
  • 🇦🇺Australia AlMunnings Melbourne

    Coolio, thats on dev

    - Had to fork `route_entity` data producer completely to ensure it checked entity->hasTranslation.
    - Introduced a `url_translated` data producer to set the language on a URL entity.
    - Added a langcode arg to the `menu` query.

    From what I can tell this works pretty much as requested.

    Have a play, let me know
    Thanks

  • 🇧🇾Belarus Yury N

    It seems to work for route. Thank you.
    But menu item itself (title for example) is untranslated.

  • 🇦🇺Australia AlMunnings Melbourne

    Hmmmm
    I cant quite figure out how to get the translated menu items to load in then. Google is pretty full of misdirection around it.

    I can translate the URL, but I'm still digging around on how to get the actual translated menu link.

    The closest to a related issue i can find is https://www.drupal.org/project/drupal/issues/2466553 🐛 Untranslated menu items are displayed in menus Needs work

    Perhaps a better approach is to go all the way up to where the menu loads and add a MenuTreeParameters on the MenuTreeStorage to filter by language. Not really sure. Bit of messing around to get it to work.

    I'll keep having a play in the background

  • Status changed to Needs work 9 months ago
  • 🇦🇺Australia AlMunnings Melbourne
    • almunnings committed d5e00560 on 2.0.x
      Issue #3390590 by almunnings: MenuItem route should not inherit language...
  • 🇦🇺Australia AlMunnings Melbourne

    Translations are the gift that keep on giving.
    Lets try these changes to menu, query, nodeTypes.

    At the top of those queries is the DataProducer language_context which changes the language at the negotiation level, whic will trickle down.

    Changing langcode in one query will change the entire language negotiation for the remainder of the query. The side effect is you cannot mix and match language queries.

    Reason is to to Deferred promise nature of GraphQL, changing a language mid query does... weird things when entities load in different orders.

    But perhaps this is enough so long as its documented.

    Have a go at dev again please :)

  • Status changed to Needs review 9 months ago
  • 🇦🇺Australia AlMunnings Melbourne
  • Status changed to RTBC 9 months ago
  • 🇧🇾Belarus Yury N

    I was also thinking about using language negotiation in some way. Found that GraphQL module has it's own negotiation plugin. But did not understood where this "context" comes from.

    Your solution covers our use cases. Thank you.
    Moving to RTBC.

  • 🇦🇺Australia AlMunnings Melbourne
  • 🇦🇺Australia AlMunnings Melbourne
  • Status changed to Fixed 8 months ago
  • 🇦🇺Australia AlMunnings Melbourne
  • 🇧🇪Belgium CedricL

    The translations are coming through for items, but the field 'name' isn't being translated. I added the translation for the title of the menu here.
    /en/admin/structure/menu/manage/MENU_ID/translate/fr/edit. But when querying the menu in french it still gives the label in the original menu language (Dutch) but the items are in french as should be.

    Extra visual info: https://imgur.com/a/RCY8rGp

    Ticket should be re-opened.

  • Assigned to AlMunnings
  • Status changed to Needs work 7 months ago
  • 🇦🇺Australia AlMunnings Melbourne

    Thanks for finding that.
    Ok cool, lets re-opened and get that menu label translated.

  • 🇦🇺Australia AlMunnings Melbourne

    Sorry for the delay!
    Adding `setConfigOverrideLanguage` into the pot seems to help this along.

    Have a play, let me know how you go.

  • Status changed to Needs review 7 months ago
  • 🇦🇺Australia AlMunnings Melbourne
  • 🇦🇺Australia AlMunnings Melbourne
  • 🇦🇺Australia AlMunnings Melbourne
    • almunnings committed f2c5683d on 2.1.x
      Issue #3390590 by almunnings, Yury N, CedricL: MenuItem route should not...
  • Status changed to Fixed 6 months ago
  • 🇦🇺Australia AlMunnings Melbourne
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024