Problem/Motivation

Onmultilingual sites, nodes created with language 'not specified' appear on the Content page in the default language instead of the user interface language.

I added a simple patch, but I'm not sure about consequences outside the described use-case.
The $entity->toURL() method adds the entities current language as an URL option to the link generator. The provided patch applies the current language as a prefix base if the nodes language is "not specified".

Steps to reproduce

  • Install Umami. This uses URL negotiation and configure path prefixes
  • Create new node using "not specified" as language
  • Go to es/admin/content

What behavior were you expecting?

The main link to the entity inside the content table should link to /es/node/N (the current user interface language based on the url es/admin/content).

What happened instead?

The main link to the entity inside the content table links to /node/N, which changes the site language (based on language path prefix) back to english.

Proposed resolution

Update the language negotiation URL plugin to ensure that if language is not defined for the current content, adopt the default language from the URL.

Remaining tasks

Review

User interface changes

N/A
No visible UI changes, as content links will be pointing to the current language.

API changes

N/A

Data model changes

N/A

Release notes snippet

Issue fork drupal-2883450

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Patrick Bauer created an issue. See original summary.

Patrick Bauer’s picture

Title: Language neutral content missing url prefix » Missing url prefix on language neutral content
Patrick Bauer’s picture

Issue summary: View changes
cilefen’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, language_negotioation_undefined.patch, failed testing.

andypost’s picture

+++ modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -130,7 +130,7 @@
-    if (!isset($options['language'])) {
+    if (!isset($options['language']) || $options['language']->getID() === 'und') {

Any reason to change url language to url one if it was defined already?

Patrick Bauer’s picture

I don't really understand your question, could you elaborate? My code change should only fire if the content is language neutral.

Patrick Bauer’s picture

StatusFileSize
new630 bytes

Had the wrong paths in my first patch. Updated to new paths.

Patrick Bauer’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 8: language_negotioation_undefined_8_4.patch, failed testing. View results

Patrick Bauer’s picture

Status: Needs work » Needs review
StatusFileSize
new961 bytes

Fixed patch format.

TBI’s picture

Below are the following steps:

1. Install Content Translation module.
2. Add the Language in Configuration -> Regional and language -> Languages.
3. Click on the Detection and Selection tab next to the List tab on the languages page
4. Enable the Browser detection method and save the settings.
5. Select Enable Translation and Show language selector on create and edit pages under Language settings on edit page of content type.
6. Add translated content for the node on click the Translate option under operations for the node.
7. After add the content, on change the site in another language when click on node title it goes to node detail page with prefix url of that language.

Patrick Bauer’s picture

Thats right, but that doesn't work for nodes which are not translated but instead are language neutral (Language = not-specified).
We have content thats not translated, but valid for every language thats available on the page.

TBI’s picture

The patch in #11 is working perfect. If we choose "-not-specified" option in Language field while creating node. On change the language of the site. The node opens with that language prefix.

dinesh18’s picture

It seems when we select (Language = not-specified), it will take the default path prefix code which is English in your case.
I don't think we really require a patch for (Language = not-specified). If suppose there are more than 2 languages then what should be the path prefix ?

Patrick Bauer’s picture

You're right, it uses the default path prefix (english in this case). But if I'm an italian user and click on a teaser for a language neutral content, I will automatically be redirected to the english interface language version of the site. The current implementation forbids to ever view language neutral content with a non-default language user interface.

If suppose there are more than 2 languages then what should be the path prefix ?

Like the patch and my issue description states: use the path prefix of the currently used language. A german user will get /de/node/123, an italian user /it/node/123 and the english user will get /node/123. That way the content can be viewed while still using the users interface language.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

svdhout’s picture

@Patrick Bauer Good catch

I can confirm that the patch in #11 fixes the problem with language neutral content being linked to without path prefix.

The patch doesn't do anything when the language is set to not applicable, so the same buggy behaviour occurs.

This issue causes a lot of other problems with links to language neutral entities, such as media items etc:
https://www.drupal.org/node/2670144
https://www.drupal.org/project/drupal/issues/2798977
https://www.drupal.org/project/drupal/issues/2645922
https://www.drupal.org/project/drupal/issues/2889892
https://www.drupal.org/project/drupal/issues/2798977

I think this is a way better solution then adding the language inside each formatter.
I'll point the other tickets to this one, so it can be tested further.

Patrick Bauer’s picture

Thank you, please do!
Do you think there may be more edge cases which could make problems? Adding "not applicable" to the exceptions would be a simple addition.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

borisson_’s picture

We'll probably need to add tests for this.

borisson_’s picture

I tried writing a test to fix this, but I can't find a good way to do this. I'm not sure what test-class or module this should go in. Should this be in a new test?

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

gngn’s picture

#11 fixes the problem for me

blacksnipe’s picture

Fix in #11 works here too.
Thanks Patrick.

gngn’s picture

So what do we do about "not applicable"?

Wouldb be something like

 ... || $options['language']->getID() === LanguageInterface::LANGCODE_NOT_APPLICABLE

but I am not sure if we need it.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nuez’s picture

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

enrocean167’s picture

The attached patch adds support for content with language set to not applicable.

philkay’s picture

Fix provided in #11 works for me on Drupal 8.8.1

vdsh’s picture

Fix in #31 worked for me (however, probably not linked to this patch, but I realized that the url was not taking the alias defined by pathauto, so I had to resort to hook_preprocess_node to rewrite the URL).

semiaddict’s picture

Thank you @patrick-bauer and @corneboele.
Patch #31 is working great for me.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

madhu_h’s picture

Verified and tested the Merge request !
https://www.drupal.org/files/issues/2019-12-09/drupal-language-prefix-ne...

Testing Steps:
* Install a new Drupal instance
* Add an additional language (e.g. italian)
* Use URL negotiation and configure path prefixes (e.g. /en for english and /it for italian)
* Enable the language selector for content type
* Create new node using "not specified" as language
* Go to /it/admin/content
* The main link to the entity inside the content table should link to /it/node/1 (the current user interface language based on the url /it/admin/content).

Test Results:
Verified that after applying patch language neutral content is taking appropriate URL aliases on switching languages

Refer SS
https://www.drupal.org/files/issues/2021-09-28/Screenshot%202021-09-28%2...
https://www.drupal.org/files/issues/2021-09-28/Screenshot%202021-09-28%2...

Can be moved to RTBC
Test Status: PASS

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

anybody’s picture

Priority: Normal » Major

Confirming #31 works fine and fixes the issue on Drupal 9.3.x! So RTBC+1 but still needs tests.

Setting the priority to major as this is broken "basic" functionality. The sibling issue, which I first thought was the cause: https://www.drupal.org/project/drupal/issues/2862511 is also set to major.

Where to put the tests? And which tests are expected here?

vistree’s picture

I tested #31 with current 9.3.9 - and it works as expected!!

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Version: 9.5.x-dev » 10.0.x-dev
Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative, +Needs issue summary update, +Novice

I have read the IS and skimmed the issue. I tried to test on Drupal 10, standard install, and found that the steps to reproduce was missing an item to enable translation on content. There are also points in #16 that should be in the Issue Summary. Adding tag for an Issue Summary update. See Write an issue summary for an existing issue for guidance.

Updating the Issue Summary on this issue is a suitable first time issue, adding novice tag.

akashkumar07’s picture

StatusFileSize
new1.07 KB

Rerolled the patch #31 for 10.0.x-dev.

aarti zikre’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new200.05 KB
new199.42 KB
new199.77 KB
new200.76 KB
new183.05 KB

Verified and tested the patch provided by #44 for 10.x dev version.
https://www.drupal.org/files/issues/2022-06-10/2883450-44.patch

Tested both the cases "Not Specified" and "Not Applicable"

Testing Steps For Not specified:

  1. Install a new Drupal instance
  2. Add an additional language (e.g. italian)
  3. Use URL negotiation and configure path prefixes (e.g. /en for english and /it for italian)
  4. Enable the language selector for the content type using this path : /admin/config/regional/content-language
  5. Create new node using "not specified" as language
  6. Go to /it/admin/content
  7. The main link to the entity inside the content table should link to /it/node/1 (the current user interface language based on the url /it/admin/content).

Testing Steps For Not Applicable:

  1. Install a new Drupal instance
  2. Add an additional language (e.g. italian)
  3. Use URL negotiation and configure path prefixes (e.g. /en for english and /it for italian)
  4. Enable the language selector for the content type using this path : /admin/config/regional/content-language
  5. Create new node using "not Applicable" as language
  6. Go to /it/admin/content
  7. The main link to the entity inside the content table should link to /it/node/1 (the current user interface language based on the url /it/admin/content).

Screen Shorts:

Before
/2022-07-08/2883450 Notspecied.png
/2022-07-08/2883450 Before_patch_NotApplicable.png

After
After Applying #44 patch for not specified content/2022-07-08/2883450After_patch_not specified.png

After Applying #44 patch for not applicable content /2022-07-08/2883450After_patch_not applicable.png

After Applying #44 patch not selecting any language in URL prefix (shows default language) 2022-07-08/2883450 After_patch_no_language_prefix.png

Test Results:
Verified that after applying patch language neutral content is taking appropriate URL aliases on switching languages

FYI #31 and #44 both the patches are same.

Can be moved to RTBC
Test Status: PASS

catch’s picture

Status: Reviewed & tested by the community » Needs work

This could still use some automated test coverage, moving to needs work for that.

reenaraghavan’s picture

Assigned: Unassigned » reenaraghavan
reenaraghavan’s picture

Assigned: reenaraghavan » Unassigned
quietone’s picture

Issue summary: View changes

#2670144: Node title links to default language when language not specified was a bugsmash triage target today. I have closed it as a duplicate of this one. I have updated the Issue Summary on the suggestion made by mstrelan in Slack.

quietone’s picture

Issue summary: View changes
mohit_aghera’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new2.27 KB
new1.19 KB
new1.04 KB

Adding test cases and test-only patches.

mohit_aghera’s picture

StatusFileSize
new2.26 KB
new1.13 KB

Oops, fixing phpcs issues and queuing again for bot.

The last submitted patch, 51: test-only-2883450-51.patch, failed testing. View results

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Confirmed the issue in D10
Standard install
Enabled a 2nd language (german in my case)
Allow for content translation of basic page content type
Create a node selecting "not specified"
URL is node/1
Go to de/admin/content
URL of NodeA is /node/1
Applied patch
cleared cache
URL of NoadeA is de/node/1

Moving to NW for the issue summary update that was requested in #43

mohit_aghera’s picture

Issue summary: View changes

Thanks for the review @smustgrave
I've tried to attempt issue summary update. Can you please have a look at it once.

Keeping the issue tag for now, feel free to remove it after verification.

mohit_aghera’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs issue summary update

Thanks! @mohit_aghera

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 52: 2883450-52.patch, failed testing. View results

mohit_aghera’s picture

Status: Needs work » Reviewed & tested by the community

Looks like random failures related to CKEditor5.
Triggering for re-test and moving it to RTBC again.

lauriii’s picture

Version: 10.0.x-dev » 10.1.x-dev
StatusFileSize
new2.46 KB
new1.49 KB

Made some minor changes to the test case.

  • lauriii committed 6f247305 on 10.1.x
    Issue #2883450 by mohit_aghera, Patrick Bauer, lauriii, corneboele,...
lauriii’s picture

Status: Reviewed & tested by the community » Fixed

Committed 6f24730 and pushed to 10.1.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

drupalfan2’s picture

Thank you.
Patch #60 seems to work in Drupal 9.

dunebl’s picture

I confirm #60 apply for D9.5

kala4ek’s picture

StatusFileSize
new120.53 KB

That issue was breaks links that must be always neutral, like links inside sitemap.xml (if there are a lot of links the additional sitemaps are generated) and most probalby some more such cases.
Because the code was relied on "not applicable" language, but now the language applied anyway...
example of regression

arnalyse’s picture

We're running into an issue similar to the one kala4ek described.

The OpenID Connect module generated its redirect URIs like https://default/openid-connect/generic, but now includes the language, e.g. https://default/en/openid-connect/generic

This is a huge problem for us, as it breaks the SSO login for our users when upgrading to D10.1
An issue for this hals already been created: https://www.drupal.org/project/openid_connect/issues/3383036

The OpenID Connect module generates its links as follows:

return Url::fromRoute('openid_connect.redirect_controller_redirect', $route_parameters, [
  'absolute' => TRUE,
  'language' => $this->languageManager->getLanguage(LanguageInterface::LANGCODE_NOT_APPLICABLE),
])->toString();

I'm not sure that LANGCODE_NOT_APPLICABLE should get a language as the definition of LANGCODE_NOT_APPLICABLE reads as follows:

/**
 * The language code used when the marked object has no linguistic content.
 *
 * Should be used when we explicitly know that the data referred has no
 * linguistic content.
 *
 * See http://www.w3.org/International/questions/qa-no-language#nonlinguistic.
*/
const LANGCODE_NOT_APPLICABLE = 'zxx';

I'd like to help resolve this, so if anyone knows what the correct way to generate a url without a langcode should be from now on, please let me know, so I can generate a patch for the OpenID Connect module.

anybody’s picture

Thanks for the reports. Still I think it was correct to *fix* this and I think this is a new side-effect and issue we have to discuss. Perhaps in a separate issue linking this one to understand the history?

Just an idea: Perhaps the right way would be to also provide a language neutral URL for such contents?
And eventually need a flag to determine which kind of link we need?

I think we can clearly see we can have both cases... this is a really complicated and very general task. Needs heavy discussion, I think.

sboden’s picture

In my mind it's clear that the current fix for LANG_CODE_NOT_APPLICABLE is wrong.

In the case of LANG_CODE_NOT_APPLICABLE no language prefix should be generated. No language prefix was generated before, it should not after since it will break a lot of stuff around the world. If you use LANG_CODE_NOT_APPLICABLE, you specifically don't want langcode, why would langcode be added?

See also https://www.drupal.org/project/drupal/issues/3385550, I spent an hour trying to figure out why openid_connect breaks. I will include a patch in the latter issue.

anybody’s picture

@sboden not really sure it's a safe thing, but if it is, we need a follow up which doesn't only implement that but also adds proper documentation to inform users about the important differences (propably below the selection), I think that's the most important difference then.

But let's wait for core maintainers feedback here, I think?

sboden’s picture

So what I see as a "problem" is for following code (it's a small piece from an openid_connect library):

    $language_none = \Drupal::languageManager()
      ->getLanguage(LanguageInterface::LANGCODE_NOT_APPLICABLE);

    $redirect_uri = Url::fromRoute(
      'openid_connect.redirect_controller_redirect',
      [
        'openid_connect_client' => $this->getPluginId(),
      ],
      [
        'absolute' => TRUE,
        'language' => $language_none,
      ]
    )->toString(TRUE);

Assume you don't know anything about the APIs being called and you just see this piece of code.

Do you expect "/nl" (in my case) to be added to the URL or not? That's the question and the problem I'm having. In the code above I set language explicitly to "not applicable" so I expect the "/nl" language prefix will not be added.

It did not add a language prefix before the fix, but it does now.

I also have no other easy way to get rid of the language prefix (unless we make a LANGCODE_ABSOLUTELY_NOT_APPLICABLE case, just kidding... don't do it). In my case above the generated URL is used for openid_connect and the "other side" just can't handle a language prefix.