URL language detection with empty path prefix not working

Created on 16 March 2018, over 6 years ago
Updated 21 May 2024, 7 months ago

Problem/Motivation

The URL language detection using an empty path prefix for the default language does not work properly and leads to sites being displayed in the incorrect language.

This is because empty prefixes are not taking into consideration, when identifying the language via URL prefix. And the second language negotiation in line is taken into account (e.g. browser language

Steps to reproduce

Configure multiple languages and import translations:
- en (default language)
- fr
- de
- nl (default fallback in selected language detection)

Configure URL language detection:
- en (/en)
- fr (/fr)
- de (/de)
- nl (leave empty)

Configure Selected language detection:
- nl

Expected result would be that visiting the site without a path prefix (e.g. http://localhost/) would turn up in Dutch. Unfortunately it turns up in English.

http://localhost/en shows up in English
http://localhost/fr shows up in French
http://localhost/de shows up in German
http://localhost/ shows up in English <= this is an issue.

Note: One could argue that it's a bad practice to have an empty prefix:
- it's not so clear for the user as you can have content at the same level as language codes;
- may complicate future migrations or url cleanups as you need 2 different rules instead of one;

Proposed resolution

Fix the LanguageNegotiationUrl class "getLangcode()" method, to consider empty prefixes.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
Language systemΒ  β†’

Last updated 2 days ago

  • Maintained by
  • πŸ‡©πŸ‡ͺGermany @sun
Created by

πŸ‡§πŸ‡ͺBelgium mpp

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

Merge Requests

Comments & Activities

Not all content is available!

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

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Yes this will require tests

    Also issue summary update for proposed solution.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Well it looks like this even got worse or I never noticed it that bad before! That's why I'm raising priority and I'm going to work on this, especially tests, together with @Grevil in the next days.

    I just found out that language detection behaves inconsistently based on the page you're on. While the frontpage for example shows all menu links in the current, correct language, other path's show wrong URLs losing the current language from URL.
    This only happens when using a setup with an empty language path prefix for one language.

    I was able to reproduce this quite simple on a vanilla Drupal installation.

    As written above, I think it's still a regression or sth. left over from #2411343: Only allowing to have empty language path prefix for the default language is inappropriate β†’
    Being able to reproduce this shows that existing tests are not sufficient.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Update: Testing the MR and clearing caches for that, I saw that now after clearing caches the situation changed, so this might alternatively or additionally be a caching issue in menus.

    We'll try to find out more next week! Does anyone else here have further information already? Are you still using the patch from DieterHolvoet's MR actively?

  • First commit to issue fork.
  • Status changed to RTBC 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Alright, I added a test and did a quick phpcs fix-up!

    I originally intended to also provide a "testEmptyLanguagePrefixForNonDefaultLanguage()" test, but you can't even leave the non default/fallback language empty:

    The prefix may only be left blank for the selected detection fallback language.

    Unfortunately, I don't have the permission to change the MR target to Drupal 11, nor reset this fork to current drupal-dev.

    Locally the test will fail with the following errors WITHOUT the patch:

    Current response header "X-Drupal-Cache" is "", but "MISS" expected.

    At line 146.
    Temporarily changing line 146 to $this->assertSession()->responseHeaderDoesNotExist('X-Drupal-Cache'); (to let the test throw the error message we are expecting) will make the test fail later on with the expected error message:

    Current response header "Content-Language" is "fr", but "en" expected.

    With the patch applied, the test becomes green! πŸ™‚

    Locally tested using:

    • Drupal 10.2.6
    • PHP 8.3.6
    • PHPUnit 9.6.19

    RTBC!

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Great work @Grevil, RTBC+1 as I can confirm this fixes the issue. Test shows that.

    This should please also be committed to 10.3.x to fix it there.

    Happy to see this fixed finally. It would be great to also have confirmation by the other participating users here, especially @DieterHolvoet. Thanks!

  • πŸ‡©πŸ‡ͺGermany Grevil

    Updated issue summary.

  • Status changed to Needs work 7 months ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Test coverage looks great, nice job.

    Careful when testing with $this->rootUser, as it may no longer be an admin. See πŸ“Œ [Meta] Fix all tests that rely on UID1's super user behavior Active for a meta issue where we're removing all use of that in child issues. Setting to NW for that.

  • πŸ‡©πŸ‡ͺGermany Grevil

    @kristiaanvandeneynde, thanks for the info! Didn't know that. :)

  • Status changed to Needs review 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Adjusted the tests accordingly!

  • Status changed to RTBC 7 months ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Looks better. Might get a merge conflict with the effort in core, though. So setting back to RTBC, but ideally this needs to be targeted vs 11.x and have the latest changes from 11.x merged in (or be rebased onto it)

  • πŸ‡©πŸ‡ͺGermany Grevil

    Agreed. I'll give it a shot.

  • Pipeline finished with Canceled
    7 months ago
    Total: 146s
    #174417
  • πŸ‡©πŸ‡ͺGermany Grevil

    Ok, no chance on properly rebasing or merging the branch on 11.x, I dirtily "rebased" it through commits, somebody should target the MR on 11.x, and then we can see if the changes are still there πŸ˜… (They should in theory).

    Hopefully we won't get any merge conflicts 😬.

  • Pipeline finished with Failed
    7 months ago
    Total: 356s
    #174425
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Perhaps ask in #contribute on Slack for some help

  • Status changed to Needs work 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Accidentally added changes twice after "rebase".

  • Status changed to RTBC 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Alright, that should do the trick! Back to RTBC!

  • Pipeline finished with Failed
    7 months ago
    Total: 207s
    #174980
  • Pipeline finished with Failed
    7 months ago
    Total: 726s
    #174976
  • Status changed to Needs work 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Spellchecking failed: https://git.drupalcode.org/issue/drupal-2953640/-/pipelines/174980/failures anyone got an idea? The error looks quite weird.

  • πŸ‡ΈπŸ‡°Slovakia hideaway

    @Grevil something went wrong with your MR. First of all it broke our builds as latest version does not apply to latest D10. And secondly, if you try to access patch file via url https://git.drupalcode.org/project/drupal/-/merge_requests/2807.patch you'll see its file size is 105MB:

    $ wget https://git.drupalcode.org/project/drupal/-/merge_requests/2807.patch -O /tmp/2807.patch
    $ ls -lash /tmp/2807.patch 
    105M -rw-rw-r-- 1 hideaway hideaway 105M May 20 11:21 /tmp/2807.patch
    
  • πŸ‡©πŸ‡ͺGermany Grevil

    Yea, thought so. I rebased the branch through applying the diff between 9.5.x and current 11.x, as I had a thousand rebase / merge conflicts, when rebasing / merging normally.

    Just going to reverse it for now and let somebody else with more knowledge of rebasing branches do the honor.

  • πŸ‡©πŸ‡ͺGermany Grevil

    Branch is back to the original 9.5.x state, when this issues fork was created (https://git.drupalcode.org/project/drupal/-/commit/56683561dc7499326d3cf...)

  • Status changed to Needs review 7 months ago
  • πŸ‡©πŸ‡ͺGermany Grevil

    Alright, branch is back on track with 11.x + issue related changes.

  • Pipeline finished with Failed
    7 months ago
    Total: 191s
    #178138
  • πŸ‡©πŸ‡ͺGermany Grevil

    @hideaway

    First of all it broke our builds as latest version does not apply to latest D10

    I am sorry for that, but stuff like this can always happen. I generally wouldn't recommend to use branch diffs as patches for composer (because of their dynamic nature). Instead, always make sure, that a static patch is provided!

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Yeah right. Let's please provide a static patch copy. And we'll create one before such heavy rebases in the future.

    Hopefully we'll get this fixed soon!

    #51 is correct, it's also risky in terms of security. Others could inject risky code into the dynamic patch files.

  • Pipeline finished with Failed
    7 months ago
    Total: 552s
    #178151
  • Pipeline finished with Canceled
    7 months ago
    Total: 2360s
    #178233
  • Pipeline finished with Failed
    7 months ago
    Total: 557s
    #178276
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Static patch against 11.x attached!

  • last update 7 months ago
    29,678 pass, 6 fail
  • Status changed to Needs work 7 months ago
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Tests are failing (also some strange ones)

Production build 0.71.5 2024