Session and content entity switch links do not set the URL language

Created on 11 February 2016, almost 9 years ago
Updated 26 August 2024, 3 months ago

Problem/Motivation

\Drupal\language\Plugin\LanguageNegotiation::getLanguageSwitchLinks() and \LanguageNegotiationContentEntity::getLanguageSwitchLinks() do not set a language key in the links.

This can lead to incorrect switch links in the following situation (among others):
1. Add a language, so that you have at least two, let's say language A (let's say that's the default one) and language B (let's say with language code bb).
2. Change language negotiation to be session-based (and disable URL negotiation).
3. Enable the language switcher block.
4. Create an alias for a path in language A, say /pathA.
5. Create an alias for the same path in language B, say /pathB.
6. Visit /pathA.

At this point the language switcher should link to /pathB?language=bb, but it instead links to /pathA?language=bb

Proposed resolution

Add the language to the switch links.

Instead of copy-pasting even more code into the already ~80% copy-pasted methods this patch provides a trait for code re-use. As you can see from this and other previous bugs in this area it is very hard to get this stuff right, so this is not for some theoretical purpose but it is to prevent future bugs in core and contrib.

Remaining tasks

<!-- See https://drupal.org/core-mentoring/novice-tasks for tips on identifying novice tasks. Delete or add "Novice" from the Novice? column in the table below as appropriate. Uncomment tasks as the issue advances. Update the Complete? column to indicate when they are done, and maybe reference the comment number where they were done. -->

User interface changes

None.

API changes

Due to the minor refactoring to improve future maintenance and stability this breaks contrib and custom language negotiation plugins if they extend LanguageNegotiationContentEntity, LanguageNegotiationSession or LanguageNegotiationUrl and one of the following is true:
1. They provide a private method called getLanguageManager() or processLanguageSwitchLink()
2. They provide a public or protected method called getLanguageManager() that does not return an object implementing \Drupal\Core\Language\LanguageManagerInterface
3. They provide a public or protected method called processLanguageSwitchLink() that takes different arguments from the ones introduced here.
3. They use a trait that has a method called getLanguageSwitchLinks() or processLanguageSwitchLink().
If this is considered a BC break, then this could be avoided as well, by simplifying the patch at the cost of future maintenance and stability. We could also considering doing the improved version for 8.1 and the extra-safe version for 8.0.

Data model changes

None.

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Language system 

Last updated about 7 hours ago

  • Maintained by
  • 🇩🇪Germany @sun
Created by

🇩🇪Germany tstoeckler Essen, Germany

Live updates comments and jobs are added and updated live.
  • D8MI

    (Drupal 8 Multilingual Initiative) is the tag used by the multilingual initiative to mark core issues (and some contributed module issues). For versions other than Drupal 8, use the i18n (Internationalization) tag on issues which involve or affect multilingual / multinational support. That is preferred over Translation.

  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024