Problem/Motivation

If you don't want to translate your URL alias, the original URL alias won't work with your translations.

Steps to reproduce:
Per #171

1. Enable content translation and language detection based on URL and add the Spanish language.
2. Enable all the article translation options except URL.
3. Enable Pathauto with the default path for articles.
4. Create an English article with the title of Hello and the automatic path of example.com/hello
5. Translate the English article to Spanish with a title of Hola. Do not change the path.

The Spanish article should have a path of example.com/es/hello

In fact, the Spanish article will have a path of example.com/es/hola thus translating the path even though URL is supposed to be untranslated.

to work around this, the editor can manually set the url on the spanish translation back to /hello thus setting the URL back to example.com/es/hello. But, if the automatic URL is used, the url is translated based on the spanish title rather than using the untranslated english path.

Also, before an article is translated, untranslated nodes loaded in Spanish can get a path example.com/es/node/1 instead of example.com/es/hello

  1. Install with standard
  2. Enable Language and Content Translation modules.
  3. Add a language (e.g. Spanish)
    • /admin/config/regional/language
  4. Edit Article content type, Language settings > Enable translation
    • /admin/structure/types/manage/article
  5. Go to content translation settings and check Content. Within Article, uncheck the URL alias field.
    • /admin/config/regional/content-language
  6. Create an Article, assign an URL alias in the form (e.g. /my-alias)
  7. Translate the node. The URL alias is prepopulated with your source alias (e.g. /my-alias).
  8. Submit the form.

Current outcome:
In the alias list (/admin/config/search/path), you have (/my-alias, EN).
Going to /es/my-alias gives a 404.

Expected outcome:
In the alias list, you should have (/my-alias, UND).
Going to /es/my-alias gives a 200 and displays the Spanish translation.

Proposed resolution

  • If the entity OR the path field are not translatable, save the path alias with the langcode 'und'.
  • If the entity AND the path field are translatable, save the path alias with the langcode of the entity (or translation).

Remaining tasks

  • Agree on proposed resolution
  • Review

User interface changes

None.

API changes

None.

Data model changes

None.

CommentFileSizeAuthor
#188 2689459-188.patch22.1 KBvistree
#161 2689459-161.patch21.59 KBion.macaria
#149 Screenshot 2022-02-11 at 3.00.06 PM.png21.53 KBjoshua1234511
#147 interdiff_145-147.txt717 bytespostyly
#147 2689459-147.patch21.61 KBpostyly
#145 interdiff-127-145.txt5.84 KBcharginghawk
#145 2689459-145.patch21.36 KBcharginghawk
#143 2689459-143.patch21.27 KBcharginghawk
#133 content language.png389.28 KBazinck
#129 Screen Shot 2020-01-29 at 12.05.07.png135.48 KBultrabob
#127 2689459-127.patch21.27 KBKrzysztof Domański
#127 interdiff-125-127.txt1.86 KBKrzysztof Domański
#126 interdiff-123-125.txt1.74 KBKrzysztof Domański
#125 2689459-125.patch21.78 KBrrrob
#124 reroll_diff_112-123.txt13.8 KBPiotr Pakulski
#123 2689459-123.patch21.43 KBPiotr Pakulski
#120 2689459-120.patch20.96 KBPiotr Pakulski
#119 2689459-119.patch20.49 KBPiotr Pakulski
#112 interdiff-110-112.txt1.76 KBbadrange
#112 interdiff-106-112.txt14.43 KBbadrange
#112 2689459-112.patch21.57 KBbadrange
#111 interdiff-106-110.txt13.95 KBbadrange
#111 2689459-110.patch21.57 KBbadrange
#107 interdiff-2689459-96-106.txt4.25 KBcharginghawk
#106 interdiff_96_106.txt0 bytescharginghawk
#106 2689459-106.patch18.83 KBcharginghawk
#105 2689459-105_8.7.1.patch19.09 KBmike.vindicate
#104 2689459-104.patch5.37 KByogeshmpawar
#101 2689459-101.patch5.38 KBguaneagler
#100 2689459-99.patch5.38 KBguaneagler
#96 interdiff-94-96.txt903 byteszaporylie
#96 2689459-96.patch18.84 KBzaporylie
#94 interdiff-89-94.txt832 byteszaporylie
#94 2689459-94.patch17.96 KBzaporylie
#89 2689459-88.patch17.14 KBzaporylie
#83 2689459-83.patch13.3 KBsavkaviktor16@gmail.com
#80 2689459-79_with-post-update.patch15.12 KBmqanneh
#79 2689459-74_with-post-update.patch14.5 KBmqanneh
#74 interdiff-2689459_with-post-update-72-74.txt2.17 KBr.nabiullin
#74 interdiff-2689459-72-74.txt2.17 KBr.nabiullin
#74 2689459-74_with-post-update.patch14.5 KBr.nabiullin
#74 2689459-74.patch11.99 KBr.nabiullin
#72 2689459-72_with-post-update.patch13.43 KBr.nabiullin
#72 2689459-72.patch10.91 KBr.nabiullin
#67 delete-url-alias-of-source-entity.patch1.65 KBFlutterStack
#64 2689459-64-fix_language_neutral_translation_paths.patch9.97 KBptmkenny
#61 2689459-61.patch11.74 KBvprocessor
#60 2689459-60.patch11.82 KBvprocessor
#57 interdiff-2689459-48-57.txt1.41 KBAlex Bukach
#57 2689459-57.patch12.14 KBAlex Bukach
#48 interdiff-46-48.txt1.33 KBmaxocub
#48 2689459-48.patch11.65 KBmaxocub
#46 interdiff-32-46.txt2.32 KBmaxocub
#46 2689459-46.patch11.62 KBmaxocub
#33 Screen Shot 2016-06-15 at 11.26.13 PM.png164.93 KBKristen Pol
#32 2689459-32.patch9.29 KBmaxocub
#32 interdiff-29-32.txt1.23 KBmaxocub
#29 2689459-29.patch9.33 KBmaxocub
#29 interdiff-23-29.txt7.32 KBmaxocub
#23 2689459-23.patch11.62 KBmaxocub
#23 2689459-23-test-only.patch8.25 KBmaxocub
#21 2689459-21.patch3.37 KBmaxocub
#9 interdiff-2689459-8-9.txt1.44 KBheykarthikwithu
#9 2689459-9.patch1.87 KBheykarthikwithu
#8 interdiff-7-8.txt1.25 KBmaxocub
#8 2689459-8.patch1.67 KBmaxocub
#7 interdiff-5-7.txt2 KBmaxocub
#7 2689459-7.patch1.65 KBmaxocub
#5 2689459-5.patch1.62 KBmaxocub

Issue fork drupal-2689459

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:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

penyaskito created an issue. See original summary.

penyaskito’s picture

Issue summary: View changes
maxocub’s picture

I was able to reproduce.

We could also set the URL alias language as 'none' instead of 'English' if it's not translatable. If you set it to 'none' in the UI, then the alias works in the two languages.

maxocub’s picture

I tried this:

function content_translation_entity_translation_insert(\Drupal\Core\Entity\EntityInterface $translation) {
  if (!$translation->getFieldDefinition('path')->isTranslatable()) {
    $langcode = $translation->language()->getId();
    $path = $translation->get('path')->first()->getValue();
    \Drupal::service('path.alias_storage')->save($path['source'], $path['alias'], $langcode);
  }
}

It works when adding a new translation, but if we update the original path alias, the one in the second language isn't updated.

maxocub’s picture

Status: Active » Needs review
Issue tags: +Needs tests
FileSize
1.62 KB

Is that a good start?

Status: Needs review » Needs work

The last submitted patch, 5: 2689459-5.patch, failed testing.

maxocub’s picture

Status: Needs work » Needs review
FileSize
1.65 KB
2 KB

Let's give it another try.

maxocub’s picture

FileSize
1.67 KB
1.25 KB

Nitpicking

heykarthikwithu’s picture

updated the patch with changes,

Status: Needs review » Needs work

The last submitted patch, 9: 2689459-9.patch, failed testing.

The last submitted patch, 9: 2689459-9.patch, failed testing.

anthony.bouch’s picture

Just ran into the exact same problem, and the code in your patch rescued us. In our case we've implemented this as a module so that we don't have to patch core.

Also in the latest patch 2689459-9.patch - I think you'll need to guard against translation deletions - since hook_entity_update() is called then, but the EntityInterface $entity won't have a path on it.

Something like this....

function content_translation_entity_update(EntityInterface $entity) {
  if ($entity instanceof FieldableEntityInterface && !$entity->getFieldDefinition('path')->isTranslatable()) {
    $path = $entity->get('path')->first();
    if(isset($path)) {
      $path = $path->getValue();
      $alias_storage = \Drupal::service('path.alias_storage');
      $language_manager = \Drupal::service('language_manager');
      foreach ($language_manager->getLanguages() as $langcode => $language) {
        if ($path['langcode'] != $langcode) {
          if ($translation_path = $alias_storage->load([
            'source' => $path['source'],
            'langcode' => $langcode
          ])
          ) {
            $alias_storage->save($path['source'], $path['alias'], $langcode, $translation_path['pid']);
          }
        }
      }
    }
  }
}
anthony.bouch’s picture

Also not exactly sure why this was necessary, but while deleting a translation removed the url alias from url_alias table, if you delete the source entity (default language), the url aliases are not removed. I had implement hook_entity_delete() as...

function servir_language_entity_delete(EntityInterface $entity) {
  if ($entity instanceof FieldableEntityInterface && $entity->getFieldDefinition('path') && !$entity->getFieldDefinition('path')->isTranslatable()) {
    $alias_storage = \Drupal::service('path.alias_storage');
    $language_manager = \Drupal::service('language_manager');
    $source = '/node/' . $entity->id();
    foreach ($language_manager->getLanguages() as $langcode => $language) {
      if ($translation_path = $alias_storage->load(['source' => $source, 'langcode' => $langcode])) {
        $alias_storage->delete(['source' => $source, 'langcode' => $langcode]);
      }
    }
  }
}
anthony.bouch’s picture

I may be miles off, but there's a bit more to this than meets the eye.

Here's the approach I've taken - https://gist.github.com/58bits/81125d4dcbc646c4a1f8

I'm not sure that content_translation_entity_translation_insert is required, because entity update is called on any translation insert.

I also wrestled to discover the rules for when a path object will have language, source, and alias elements populated and if not, build the source and alias variables manually.

Deletions also need to be taken into account.

In this end, this is a 'brute force' approach. It simply guarantees that the source / default language alias will be used for all available languages, whether or not an actual translation has been created (and given that URL Aliases will be configured as non-translatable' - under Administration > Configuration > Regional and language)

Hope this helps....

maxocub’s picture

@blue_waters: Thanks for your help! About the deletion of the alias not happening when we delete the source entity, there's already an issue for that: #2539634: PathItem::delete() never runs because the path field type is a computed field in disguise

anthony.bouch’s picture

@maxocub - thanks for the issue link.

maxocub’s picture

Does someone know if it would be possible (and preferable) to write a test for this using KernelTestBase? Or should WebTestBase be used?

Gábor Hojtsy’s picture

Looking at the patch it should be possible to write tests for the patch with a KernelTestBase if all the services used exist as stubs, but there are definitely several.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

smithworx’s picture

We've been working on this issue (at DrupalCon New Orleans) and believe that when the path alias is set to not be translatable that we should consolidate all translations to use the same path by setting the langcode to a language code that represents ALL languages (e.g., LANGCODE_NOT_SPECIFIED, LANGCODE_NOT_APPLICABLE).

When we have set the code to LANGCODE_NOT_SPECIFIED the view display of the entity works as expected for all languages. However, the edit entity page shows the path as being blank as it is looking up the path for the specific language (e.g., English, French) rather than a code representing ALL languages.

maxocub’s picture

Status: Needs work » Needs review
FileSize
3.37 KB

Following the discussion with @smithworx & @tstoeckler at DrupalCon, here's a new patch with a different approach:

  • If the entity and the path field are translatable, we use the entity's langcode for the alias.
  • If the entity or the path field are not translatable, we use 'und' langcode for the alias.

I will try to update the issue summary soon and add some tests, but first I want to see it breaks any tests, and maybe get some feedback.

pp’s picture

Status: Needs review » Needs work

I tested it with steps in issues description. The patch works fine, but I think tests are needed. Put it back Needs Work.

maxocub’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
8.25 KB
11.62 KB

Here's some tests!

The last submitted patch, 23: 2689459-23-test-only.patch, failed testing.

maxocub’s picture

Issue summary: View changes
Kristen Pol’s picture

Great work! Some nitpicks:

  1. +++ b/core/modules/path/src/Tests/PathTranslationTest.php
    @@ -0,0 +1,228 @@
    +  protected function setUp() {
    

    Needs doc block?

  2. +++ b/core/modules/path/src/Tests/PathTranslationTest.php
    @@ -0,0 +1,228 @@
    +    // Enable URL language detection and selection.
    +    $edit = [
    +      'language_interface[enabled][language-url]' => 1,
    +    ];
    +    $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
    

    URL detection and selection is enabled by default so I don't understand this part.


  3. testAliasTranslatableNode and testAliasUntranslatablePath are almost the same so a helper function could be used if that makes sense. If so, the differences are:
    6c6
    < +      'settings[node][page][fields][path]' => 1,
    ---
    > +      'settings[node][page][fields][path]' => FALSE,
    30c30
    < +      'path[0][alias]' => '/' . $this->randomMachineName(),
    ---
    > +      'path[0][alias]' => '/' . $english_alias,
    53c53
    < +    // Tests that the English alias was saved with the 'en' langcode.
    ---
    > +    // Tests that both aliases were saved with the 'und' langcode.
    59c59
    < +    $this->assertEqual($path_en['langcode'], 'en');
    ---
    > +    $this->assertEqual($path_en['langcode'], LanguageInterface::LANGCODE_NOT_SPECIFIED);
    61d60
    < +    // Tests that the French alias was saved with the 'fr' langcode.
    67c66
    < +    $this->assertEqual($path_fr['langcode'], 'fr');
    ---
    > +    $this->assertEqual($path_fr['langcode'], LanguageInterface::LANGCODE_NOT_SPECIFIED);
    
vasi’s picture

I'm not 100% sure, but I think this is a duplicate of https://www.drupal.org/node/2650962

maxocub’s picture

Yes, it is a duplicate. I guess we should close #2650962: Path alias for entities only work for one language when it's selected to not be translatable since here we have a patch and tests.

maxocub’s picture

Version: 8.1.x-dev » 8.2.x-dev
Component: content_translation.module » path.module
Issue tags: +path
FileSize
7.32 KB
9.33 KB

Here's an updated patch addressing the comments from #26, thanks @Kristen Pol for the review!

maxocub’s picture

Kristen Pol’s picture

Nice work! Here are some nitpicks:

  1. +++ b/core/modules/path/src/Tests/PathTranslationTest.php
    @@ -0,0 +1,169 @@
    +    // Tests the langcode for translatable path, it should be set to the node's langcode.
    

    More than 80 chars.

    Should be 2 sentences or reworded.

  2. +++ b/core/modules/path/src/Tests/PathTranslationTest.php
    @@ -0,0 +1,169 @@
    +    // Tests the langcode for untranslatable path, it should be set to not specified.
    

    More than 80 chars.

    Should be 2 sentences or reworded.

  3. +++ b/core/modules/path/src/Tests/PathTranslationTest.php
    @@ -0,0 +1,169 @@
    +    $french_alias = $this->randomMachineName();
    +    $not_specified = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    +    $this->doTestAliasLangcode(FALSE, $english_alias, $english_alias, $not_specified, $not_specified);
    

    $french_alias is set but then not used since $english_alias is used twice in function.

maxocub’s picture

Kristen Pol’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
FileSize
164.93 KB

Thanks. The changes look good. I have tested the patch using the steps in the issue summary and it works as expected. Here is a screenshot of after translating the node into Spanish.

Marking RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I think we going to need a upgrade path for existing sites here. The fix looks good but we need a post update (doesn't need to be a hook_update_N) to ensure that multilingual sites where the path field is not translatable have aliases with a language of UND and not another language.

Kristen Pol’s picture

Thanks for the review. What is a "post update" that is not a hook_update_N?

tstoeckler’s picture

@Kristen Pol:

While hook_update_N() update functions are used when database schema or config structure changes, in D8 we have introduced "Post updates" that are used to just update data/values without any schema changes. That way, we can use the complete Drupal API in post update functions which is problematic in hook_update_N(). See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension...

Kristen Pol’s picture

Oh! Thanks for the explanation. :)

maxocub’s picture

Issue tags: +DrupalNorth2016

Should we also think of something to do if someone change the translation settings on a site where there's content already? Like if someone decide to translate the path alias on a content type, should we automatically update the langcode of existing path aliases of that content type?

penyaskito’s picture

@alexpott #34: How can we prevent that those aliases were not created by hand? I'm not sure if we can assume that we want to generate those in every case.

@maxocub: I think that if we update the translatability settings of a patch in a given content entity, we need to ensure that the alias is changed to the original source language of the entity, and that we generate the same alias for any existing translation, so external links still work. The user would then be responsible of translating them if needed and adding redirects if they want to.

maxocub’s picture

I did some tests with the title field to see how it works when we change it's translability.

If the title field is not translatable, and you create a French translation of an English node, there will be two entries in the databases with the same title value but with different langcodes. The behavior is the same if the title field is translatable. So when the translatability changes, we don't need to update the values, because they are already there. The only thing that changes is the logic to get the value.

I think we should do the same here with the path aliases, that is to duplicate them for each translations even the field is not translatable. In fact, that was penyaskito's original suggestion.

That would take care of translatability changes on a site with content. Still, we will have to find a way to do a post update. But instead of having to change the langcodes of existing aliases, we would only have to add new ones for the translations.

Any thoughts?

Gábor Hojtsy’s picture

But then you always need to maintain all the copies when creating/changing aliases, when adding a new language, etc?

maxocub’s picture

Yes, that's true. But to be clear, we would only have to maintain all duplicated aliases when we are changing the original. The alias is only duplicated when we translate the original content. So when we add a new language, we don't have to do anything with existing alias.

On the other hand, if we use the 'und' langcode solution, we would have to duplicate the alias for all current translation if we turn the translatability on for the path alias, and change it to 'und' (or add a new alias with 'und') if we turn it off.

You think we should stick with the current 'und' solution?

Gábor Hojtsy’s picture

If you maintain multiple synced URL aliases in languages, you need to create the new ones when a language is edited and take care of aliases edited on the URL alias admin pages as well as the API. Sounds like sizable overhead :/

maxocub’s picture

Assigned: Unassigned » maxocub

Based on the comments above, here is what I understand is to be done:

  • Keep the solution as it is, with the 'und' langcode for aliases that are not translatable.
  • Add a hook_post_update_NAME in which we:
    • loop over all node types and taxonomy vocabularies (the two entity types that have path aliases, I think)
    • if the entity type or the path alias field are not translatable, loop over all nodes (or terms) of that type
    • load the path alias and change it's langcode to 'und'

Now what about when we change the translatability of the entity type or the path alias field, do we update again the path alias langcode?

Gábor Hojtsy’s picture

Now what about when we change the translatability of the entity type or the path alias field, do we update again the path alias langcode?

That is the sad part I think, we don't do anything like that now on translatability change, we made sure not to have a batch job on translatability changes if at all possible :/

maxocub’s picture

Status: Needs work » Needs review
FileSize
11.62 KB
2.32 KB

I added a hook_post_update_NAME() as requested in #34. It's the first time I do that so I'm not sure it's OK. Comments would be appreciated.

Status: Needs review » Needs work

The last submitted patch, 46: 2689459-46.patch, failed testing.

maxocub’s picture

Status: Needs work » Needs review
FileSize
11.65 KB
1.33 KB
maxocub’s picture

I think it's worth noting that if this gets in, it will affect how #2539634: PathItem::delete() never runs because the path field type is a computed field in disguise will be resolved, because of the langcode change to 'und',

Berdir’s picture

Interesting approach to this problem. I like it, but we might need to document the implications somehow better I think. If possible right on the page where you configure translatability. We're trying that for paragraphs in #2760341: Let the user be aware that Paragraphs fields are not supported for translation.

See also #2511968: Path field should fall back to language neutral aliases (also makes this happen for the form widget!) and #2484411: Manual path aliases are not the same as aliases on the node form on single-language sites for related issues.

And last, I assume pathauto would have to respect this as well then. See #2728725: Special characters like tab or spaces in pattern can break alias generation and #2728663: multilanguage usage for related issues there.

Berdir’s picture

Ah, another thing. I'm not sure about the post update function. you assume that everyone wants it to behave like this, but maybe they accidently didn't enable translation for the path field and because it worked for them, never bothered to change that?

Might be safer to leave out the update function or make it a manual step? As proposed in #2511968: Path field should fall back to language neutral aliases (also makes this happen for the form widget!), we might need to make the widget fall back to either version to make it backwards compatible with existing aliases?

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Berdir’s picture

#2511968: Path field should fall back to language neutral aliases (also makes this happen for the form widget!) now contains a patch that falls back to unspecified for the alias language and saves it in the correct language. After that landed, this issue should IMHO be as easy as respecting the translatable setting for the default langcode.

catch’s picture

I'd leave the update function out - the existing aliases are valid, they're just not how we think they should be, but we don't know if a site is relying on the current behaviour or not. Could always post a drush script that does the same as the update and link from the change record.

Anonymous’s picture

After applying this patch, the URL aliases function for all translated languages and work with path pattern matches - for example: site.com/en-us/somepath. But, after applying this patch the URL alias field on the edit node page is blank unless that node is translated. So, for nodes that are not translated, the URL alias field when you are edited the node is completely blank even though that clean path has been generated and works correctly. Are the paths being stored in a different table that that field is not referencing?

maxocub’s picture

Assigned: maxocub » Unassigned
Alex Bukach’s picture

It make sense to inherit default value for the alias from the original node, doesn't it?

Status: Needs review » Needs work

The last submitted patch, 57: 2689459-57.patch, failed testing.

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

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

vprocessor’s picture

FileSize
11.82 KB

rerolled #48, for 8.3.x

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.

ptmkenny’s picture

ptmkenny’s picture

FlutterStack’s picture

I tried patch from #61 in drupal 8.3.x php 7.0. Expected outcome, Proposed resolution works fine. But on delete of entity url aliases are not getting deleted, In database url_alias table url aliases are created with language code 'und' but delete function passing language code of an entity.

Please try delete-url-alias-of-source-entity.patch along with #61 patch.

Please consider deleting url alias scenario while creating patch to drupal - 8.5.x.

Thank you.

ptmkenny’s picture

@suresh kumara: Patches need to be re-rolled against the latest version of core (now 8.5-x), not old versions like 8.3.

FlutterStack’s picture

Please try delete-url-alias-of-source-entity.patch along with #61 patch.

ptmkenny’s picture

@suresh kumara: The patch in #61 is for 8.3. This issue now needs to be fixed in 8.5.x, the current working version, not 8.3, which is no longer being patched.

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.

bgronek’s picture

Priority: Normal » Major

Because this issue causes most real-world partial translation efforts to fail (who isn't using aliased paths?), I propose escalating this issues's priority to Major.

I will work on re-rolling the aforementioned patch for 8.5 in the coming days.

Thanks!

Zulljin’s picture

r.nabiullin’s picture

Status: Needs review » Needs work

The last submitted patch, 72: 2689459-72_with-post-update.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 74: 2689459-74.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 74: 2689459-74_with-post-update.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

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.

Anonymous’s picture

Hi guys.
I don't know if this helps, but this is what I did and fixed my problem.
I made a custom function that creates aliases of the current node for all the installed languages on node save.

/**
 * Implements hook_entity_presave().
  */
function module_name_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {

  if($entity->getEntityTypeId() === 'node') {
    $langs = \Drupal::languageManager()->getLanguages();
    $nid = \Drupal::routeMatch()->getRawParameter('node');
    foreach (array_keys($langs) as $lang) {
      $path = '/node/' . (int)$nid;
      $path_alias = \Drupal::service('path.alias_manager')->getAliasByPath($path, $lang);
      if ($lang === 'en') {
        $new_path = $path_alias;
      }
      if (substr($path_alias, 0, 6) === '/node/') {
        $result_alias = \Drupal::service('path.alias_storage')->save('/node/' . $nid, $new_path, $lang);
      }
    }
  }
}

I hope it helps someone.
Please let me know your thoughts.

mqanneh’s picture

re-roll patch for latest 8.6.x

mqanneh’s picture

re-roll patch for latest 8.6.x

zaporylie’s picture

Status: Needs work » Postponed

As of @Berdir's comment in #53 and by comparing patches in #80 and #2511968-42: Path field should fall back to language neutral aliases (also makes this happen for the form widget!) I mark this issue as postponed by #2511968: Path field should fall back to language neutral aliases (also makes this happen for the form widget!). The scope for both issues overlaps considerably, hence best to get 2511968 done before we continue to work here.

zaporylie’s picture

savkaviktor16@gmail.com’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
13.3 KB

Re-rolled

Status: Needs review » Needs work

The last submitted patch, 83: 2689459-83.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Berdir’s picture

Yeah, I understand what you mean.

> My point here is that right now showing a Path widget when the field is non-translatable is a bug.

And my point is that technically, the field is currently never really non-translatable, because it will always store an alias per translation. So fixing this would be kinda wrong until the other issue happened :)

zaporylie’s picture

@Berdir, I think you commented on the wrong issue :) #3017157: "Hide non translatable fields on translation forms" option doesn't affect url alias field

But following the thread (which actually more applies more here than there):

> will always store an alias per translation

This is not true. If path is set as non-translatable aliases are created with translation source's langcode. If path field is translatable aliases are created with translation's langcode.

Berdir’s picture

Yeah, indeed, that should be in the other issue.

And good point about the source language, just forget that comment alltogether ;)

zaporylie’s picture

Status: Needs work » Needs review

An attempt to fix tests.

I also added a test that originates in #3017157-7: "Hide non translatable fields on translation forms" option doesn't affect url alias field (and fails there).

zaporylie’s picture

...and, for some reason, missing patch file.

The last submitted patch, 79: 2689459-74_with-post-update.patch, failed testing. View results

The last submitted patch, 79: 2689459-74_with-post-update.patch, failed testing. View results

The last submitted patch, 80: 2689459-79_with-post-update.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 89: 2689459-88.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

zaporylie’s picture

Status: Needs work » Needs review
Issue tags: +API-First Initiative
FileSize
17.96 KB
832 bytes

An attempt to solve rest-related failures - due to changes in default Path behaviors expected langcode changes from en to und. Tagging "API-First Initiative" to notify people this change may concern.

Status: Needs review » Needs work

The last submitted patch, 94: 2689459-94.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

zaporylie’s picture

Status: Needs work » Needs review
FileSize
18.84 KB
903 bytes

Next chunk of progress.

Status: Needs review » Needs work

The last submitted patch, 96: 2689459-96.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

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.

guaneagler’s picture

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

Patch for language none

guaneagler’s picture

guaneagler’s picture

ptmkenny’s picture

Version: 8.5.x-dev » 8.8.x-dev
yogeshmpawar’s picture

Assigned: Unassigned » yogeshmpawar
yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned
Status: Needs work » Needs review
FileSize
5.37 KB

Re-rolled the patch against 8.8.x branch.

mike.vindicate’s picture

Added patch that applies to drupal 8.7.1

charginghawk’s picture

Rerolling the #105 patch to restore the toUrl work from #3019834: Add @trigger_error() to deprecated url/link EntityInterface methods . Note that patch and #105 are rerolls of the #96 patch. It isn't clear to me what's going on in the #101 patch - it removes the tests and doesn't have an interdiff.

Please remember to add interdiffs, explain the work you're doing, and if you're skipping any other patches, to explain the reasoning there. Thanks!

charginghawk’s picture

And of course I flub the interdiff.

Status: Needs review » Needs work

The last submitted patch, 106: 2689459-106.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Pasqualle’s picture

There is another issue (which this patch does not solve):
If you are on /es/my-alias page, and {{ url }} is used in the node twig template, then the url will point to /my-alias. It always links to page without the language prefix. Same problem with entity reference fields.
I did not find any issue about it.

charginghawk’s picture

@Pasquelle That's an unrelated issue, but FYI I noticed it too for some content types that were programatically generated. The url variable is the canonical URL, and under certain circumstances it doesn't correctly use the active language's prefix. The patch on this issue fixed it for me:

https://www.drupal.org/project/drupal/issues/3061761

badrange’s picture

Status: Needs work » Needs review
FileSize
21.57 KB
13.95 KB

Here is an attempt to move this issue further, let's see which tests fail. To me it seems like this patch exposes a nice little drupal gotcha: The tests (for example Kernel/PathItemTest.php) are run on a different configuration from what you get when you go to content translation settings and enable article translations.

1. Remove path.post_update.php as requested by Berdir in #51
2. Consistently use LanguageInterface::LANGCODE_NOT_SPECIFIED instead of Language::LANGCODE_NOT_SPECIFIED
3. Add some pieces of code from guaneagler's patch in #101
4. Resolve some deprecation notices added by this patch

Remaining: I think it is wise to add some tests where we set the entity and/or path fields as translatable to match the presumably most common use case. I just want to get some feedback from the community before I spend more time on this.

I thought this was going to be easy to fix the test failures in this patch, instead my beard has grown several new gray hairs.

badrange’s picture

FileSize
21.57 KB
14.43 KB
1.76 KB

Code standard fixes before anybody starts nitpicking. Nitpicks are welcome!

johnpicozzi’s picture

Can confirm I was having this issue with Drupal 8.7.7 and the patch in #112 resolved the issue. RTBC +1

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.

gloomcheng’s picture

Patch #112 could work on Drupal 8.7.8 and really resolved the issue. RTBC + 1

badrange’s picture

Status: Needs review » Reviewed & tested by the community

Setting RTBC due to two comments confirming that #112 works

amateescu’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -path

The patch needs to be rerolled for all the recent path alias improvements from Drupal 8.8.

alexpott’s picture

  1. +++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
    @@ -19,21 +19,31 @@ class PathFieldItemList extends FieldItemList {
    +        // This may not be needed with the additions from #2689459 above.
             if ($this->getLangcode() !== LanguageInterface::LANGCODE_NOT_SPECIFIED) {
               $conditions['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
               $alias = \Drupal::service('path.alias_storage')->load($conditions);
    

    This probably should be discovered if it is true or not before commit.

  2. +++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
    @@ -64,10 +74,27 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N
    +    // If neither the path field nor entity being deleted is translatable,
    +    // delete alias with LANGCODE_NOT_SPECIFIED.
    +    if (!$entity->isTranslatable() || !$this->getFieldDefinition()->isTranslatable()) {
    +      $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    +    } else {
    +      $langcode = $entity->language()->getId();
    +    }
    +
         $conditions = [
           'source' => '/' . $entity->toUrl()->getInternalPath(),
    -      'langcode' => $entity->language()->getId(),
    +      'langcode' => $langcode,
         ];
    +
    +    $entity_langcode = $entity->language()->getId();
    +    $original_entity_langcode = $entity->getUntranslated()->language()->getId();
    +    // If the entity being deleted is not translated, delete the path alias
    +    // with the langcode LANGCODE_NOT_SPECIFIED.
    +    if ($entity_langcode == $original_entity_langcode) {
    +      $conditions['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    +    }
    

    This looks like this can be simplified if the $conditions assignment took place last.

  3. What about updates? I would have expected existing entities to need to be updated for this change. If we don't update them how are the conditions going to be correct when we do a delete? So we decided to leave out updates - see #54 BUT I still think that that means we need to really think hard about how this works:
    +++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
    @@ -64,10 +74,27 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N
       public function delete() {
         // Delete all aliases associated with this entity in the current language.
         $entity = $this->getEntity();
    +
    +    // If neither the path field nor entity being deleted is translatable,
    +    // delete alias with LANGCODE_NOT_SPECIFIED.
    +    if (!$entity->isTranslatable() || !$this->getFieldDefinition()->isTranslatable()) {
    +      $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    +    } else {
    +      $langcode = $entity->language()->getId();
    +    }
    +
         $conditions = [
           'source' => '/' . $entity->toUrl()->getInternalPath(),
    -      'langcode' => $entity->language()->getId(),
    +      'langcode' => $langcode,
         ];
    +
    +    $entity_langcode = $entity->language()->getId();
    +    $original_entity_langcode = $entity->getUntranslated()->language()->getId();
    +    // If the entity being deleted is not translated, delete the path alias
    +    // with the langcode LANGCODE_NOT_SPECIFIED.
    +    if ($entity_langcode == $original_entity_langcode) {
    +      $conditions['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    +    }
         \Drupal::service('path.alias_storage')->delete($conditions);
       }
    

    In the case where you have aliases created with a langcode but now they'd be created with UND. Also isn't the behaviour going to change for new aliases on the site so a site over time will get in an interesting situation? I'd be happy to be wrong about all this.

Piotr Pakulski’s picture

Trying to roll to 8.8.1

Piotr Pakulski’s picture

Next round of the rerolling, trying to pass the tests.

Piotr Pakulski’s picture

FileSize
21.43 KB

Reroll, trying to pass the tests. This time disabling the patch for workspace module since 8.8.1 there is new PathWorkspacesTest which I can no longer work on to pass it. My scenario does not need to use workspaces. Keep this in mind while using this version of the patch.

Piotr Pakulski’s picture

Piotr Pakulski’s picture

Piotr Pakulski’s picture

FileSize
13.8 KB
rrrob’s picture

Clean up computeValue.

Krzysztof Domański’s picture

Added interdiff.

Krzysztof Domański’s picture

I modified it.

--- a/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Field\FieldItemList;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\ComputedItemListTrait;
 
@@ -20,8 +21,6 @@ class PathFieldItemList extends FieldItemList {
   protected function computeValue() {
     // Default the langcode to the current language if this is a new entity or
     // there is no alias for an existent entity.
-    // @todo Set the langcode to not specified for untranslatable fields
-    //   in https://www.drupal.org/node/2689459.
     $value = ['langcode' => $this->getLangcode()];
 
     $entity = $this->getEntity();
@@ -35,6 +34,11 @@ protected function computeValue() {
           'pid' => $path_alias['id'],
           'langcode' => $path_alias['langcode'],
         ];
+
+        // Set the langcode to not specified for untranslatable fields.
+        if (!$entity->isTranslatable() || !$this->getFieldDefinition()->isTranslatable()) {
+          $value['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
+        }
       }
     }
ultrabob’s picture

I looked at the code, and applied #127 to 8.8.1. It applied fine, and fixed the issue I had, in which the initial url alias I set on a node would be language specific, and any translations created would have no alias created. Now the first node gets LANGCODE_NOT_SPECIFIED, which means the translation works as expected. I don't really know enough about the inner workings of the code to review that part, but the patch works for my issue.

ultrabob’s picture

Following on from the testing above, I found what seems like it may be unexpected behavior, this is not on a clean install, so it is possible another patch or something is causing the issue. I'm doing my testing on Basic Page. See the attached screenshot for the translation settings for that content type.

URL Alias is not set as a translatable field, but it shows up on both the initial node creation form and the translation creation form. If I change the URL alias in the translation, the new translation with LANGCODE_NOT_SPECIFIED replaces the old one. Given the settings shown, I would have expected that the field not show up in the translation form.

jatinkumar1989’s picture

HI, #127 not working for me.

Let me explain what my issue is:
Have a node (e.g nid 123) in EN whose path is : "/en/abcde"

now if change my language to german "DE" (not having the transalted node, just changed the path in browser)
node path currently: "/de/node/123"

Expected out :
if Node is not translated:
DE Node URL : "/DE/abcde" (not translated the node, just chnaged the path in browser)
EN Node URL : "/EN/abcde" (orignal Node)

Any help please

Thanks in Advance.

jatinkumar1989’s picture

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.

azinck’s picture

FileSize
389.28 KB

I have a question that's related to this, but not identical: can anyone clarify why URL Alias translation is required at all if I don't have the Content Translation module enabled? In 8.9.1, on a completely clean standard install, by merely enabling the Language module (and NOT any other translation modules) the Content Language interface exists, URL alias is checked, and *cannot be un-checked*. See my attached screenshot.

This 1) is baffling and 2) makes the pain points outlined in this thread much more common for people who might not even want to translate content or aliases but still use some localization functionality or just translate the admin interface.

Can anyone shed light on why this behaves this way?

azinck’s picture

Can someone clarify what this patch is meant to accomplish right now? I'm not able to see the effect I had hoped to see. After applying this patch I'm still getting aliases created with a langcode set to my site's default language. I'd expected to see them set to und.

azinck’s picture

Ok, I found what appears to be a workaround for my particular use-case: I have enabled custom language settings for the content entity and set the language to "not specified" for every content type. This seems like it should be the default approach taken by core when no language has been specified, but alas, apparently it is not. By so doing, I'm able to create content with no language specified and the subsequent aliases that are auto-created also have no language specified. I was able to do this without the patches in this thread. I'm still not too clear on what the patches here actually do.

Coufu’s picture

I originally wanted the same as OP and as described in #130, but ended up going a different route and not using any patches in this issue.

Few notes and learnings:

  • Patches didn't work for me.
  • Setting all my path aliases to "und" didn't work for me either because that meant all languages for all content would show in english, even if that content wasn't translated (we want untranslated content to return 404 on their respective language paths)
  • My solution was to set all "URL Alias" on "/admin/config/regional/content-language" to be translatable and that made new path aliases per language. I just have to communicate to my team not to change the path since we want to use english path for all languages (at least for now).
Kristen Pol’s picture

Status: Needs review » Needs work

Based on #136 ("Patches didn't work for me"), moving back to "Needs work".

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.

Giuseppe87’s picture

I confirm #127 doesn't apply on 9.1.3, while the workaround explained in #136 is working.

ThirstySix’s picture

I tried with #136. but it's not working for mine.

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.

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.

charginghawk’s picture

Status: Needs work » Needs review
FileSize
21.27 KB

Rerolling #127, just rejiggering line numbers so patch applies.

Status: Needs review » Needs work

The last submitted patch, 143: 2689459-143.patch, failed testing. View results

charginghawk’s picture

Status: Needs work » Needs review
FileSize
21.36 KB
5.84 KB

The test fails were due to deprecations, here they're cleaned up.

charginghawk’s picture

Issue summary: View changes
Status: Needs review » Needs work

A lot of the comments since #127 have to do with the intention of the patch, and admittedly the testing steps on the ticket are unclear, so I'm adding more specific steps to describe and reproduce the issue. Reminder that you can use the excellent simplytest.me to spin up an environment and reproduce the issue yourself (and also select the patch to confirm the issue is fixed).

As for the code itself, basically it's just adding `isTranslatable()` checks to path fields (Drupal\path\Plugin\Field\FieldWidget\PathWidget, Drupal\path\Plugin\Field\FieldType\PathItem, Drupal\path\Plugin\Field\FieldType\PathFieldItemList) and if not translatable setting the field's langcode to LANGCODE_NOT_SPECIFIED.

I don't think anyone's addressed the feedback in #118 so that's the next todo.

postyly’s picture

Kristen Pol’s picture

Issue tags: +Needs manual testing

Tagging for manual testing based on issue summary steps.

joshua1234511’s picture

Manually tested the patch provided in #147 with the steps from issue summary.
In the alias list, there is only (/my-test, UND).

Both links work
/my-test
/es/my-test

Can be marked as RTBC, After final patch code review.

Kristen Pol’s picture

I looked through the code and found a couple nitpicks below. Also, since the code for deleting the node has been updated, it might be good to manually test that.

+++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
@@ -71,6 +72,15 @@ public function postSave($update) {
+      // If either entity or the path field is non-translatable, use 'und'.

This comment uses 'und' while the rest of the comments use LANGCODE_NOT_SPECIFIED.

+++ b/core/modules/path/tests/src/Functional/PathTranslationTest.php
@@ -0,0 +1,200 @@
+    $this->assertSession()->responseContains($node->body->value);
+
+    // Tests that the alias was saved with 'und' langcode.

Same as above.

jacktonkin’s picture

Per #146 and #150 this is still needs work for #118.2 and #118.3 (#118.1 has been addressed as the changes to the method are much simpler now and the comment has gone away).

For #118.2 and #118.3, I think the logic for deleting path aliases could be:

  1. For a (non-default) translation: just delete aliases for the translation language (the current behavior).
  2. For the default translation (i.e. when the entity is deleted): delete all remaining aliases.

So we can just do:

$path_alias_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
$conditions = [
     'path' => '/' . $entity->toUrl()->getInternalPath(),
];

if (!$entity->isDefaultTranslation()) {
    $conditions['langcode'] = $entity->language()->getId();
}

$entities = $path_alias_storage->loadByProperties($conditions);
$path_alias_storage->delete($entities);

Or is it a problem to delete manually created aliases for translations that don't exist?

jacktonkin’s picture

Kristen Pol’s picture

Issue tags: +Bug Smash Initiative

Tagging for bugsmash.

Rob230’s picture

I tested #147 on Drupal 9.3 and it didn't do anything. I create a new page, it has an English alias. But visiting the URL for the page in the other language is a 404.

proweb.ua’s picture

#145 #147 Drupal 9.3.12 and 9.3.x-dev
not works

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.

ksenzee’s picture

FWIW #147 works perfectly for me on 9.3.12. We're using subdomains for language detection, with translatable content types and untranslatable URL alias fields. We were forcing URL aliases to language-neutral using hook_path_alias_presave, and any time we added a translation we got a new duplicate path alias set to 'und'. With this patch, we no longer get duplicate aliases.

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

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Greg Boggs’s picture

Patch #147 does not work for me. I followed the directions as best I could, and when I save "test node" in spanish as "spanish test node", I still get the spanish URL of es/spanish-test-node rather than es/test-node

Greg Boggs’s picture

In my case, the reason this did not work as expected is because my path auto alias in Pathauto was set to [node:title].

I set my path auto alias to [node:original:title], and I get this feature with no need for a core patch at all because it's Pathauto generating the translated paths.

ion.macaria’s picture

Re-roll #147 patch created for 9.5.x.

Greg Boggs’s picture

In Drupal 9, with, or without this patch, translated URLs only work if you use an automatically generated URL in English.

If you create an english node, give it a manual URL and then translate the node, the translated node has a url of example.com/node/

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

jedihe’s picture

@Greg Boggs: I could not reproduce the issue you report. Used a clean 9.5.9 install on simplytest.me and tried both Drupal core alone, as well as with pathauto (different instances).

Testing results:

Drupal core 9.5.9

  1. Install: language, content translation
  2. Add 'de' language
  3. Enable translation for Article bundle and url alias field
  4. Create article, en langcode, manual alias: article loads using alias
  5. Added 'de' translation, keep manual alias unchanged, save: article loads using lang-prefixed alias.

Drupal core 9.5.9 + pathauto

  1. Install: language, content translation, pathauto
  2. Add 'de' language
  3. Create pathauto pattern for 'article' bundle
  4. Enable translation for Article bundle and url alias field
  5. Create article, en langcode, manual alias: article loads using alias
  6. Added 'de' translation, keep manual alias unchanged, save: article loads using lang-prefixed alias.
Greg Boggs’s picture

The goal is to not enable url translation so URLs should be:

Article Title English: Hello
Article Title Spanish: Hola

Article URL English:
example.com/hello

Article URL Spanish:
example.com/es/hello

It sounds like to me you got:

Article Title English: Hello
Article Title Spanish: Hola

Article URL English:
example.com/hello

Article URL Spanish:
example.com/es/hola

Greg Boggs’s picture

I can get it all to work as long as an editor always manually enters the URL and doesn't use the checkbox. But, as soon as the default automatically generated alias is used, I cannot. Perhaps it's a configuration difference between our test sites.

yash.rode’s picture

I was trying to reproduce the problem from steps to reproduce, can someone confirm if they can do step 5: Within Article, uncheck the URL alias field for Drupal 11.x? I am not able to do so because once we enable translation for article it gets enabled for all the fields and if we try to save admin/config/regional/content-language with URL alias for article unchecked it does not get saved.

yash.rode’s picture

Status: Needs work » Needs review

Need some help with #167

smustgrave’s picture

Status: Needs review » Needs work

Can the steps be updated please.

Followed them but going to es/my-alias took me to the Spanish translation. So I didn't have the issue.

lauriii’s picture

Status: Needs work » Postponed (maintainer needs more info)

I also cannot reproduce this anymore. I think there's a good chance that this was fixed by #2336597: Convert path aliases to full featured entities (or at least improved). If there's a set of customizations required to trigger this, it would be great if the steps in the issue summary would be updated with those.

Greg Boggs’s picture

I have not tested this in two months.

Steps to reproduce:

1. Enable content translation and language detection based on URL and add the Spanish language.
2. Enable all the article translation options except URL.
3. Enable Pathauto with the default path for articles.
4. Create an English article with the title of Hello and the automatic path of example.com/hello
5. Translate the English article to Spanish with a title of Hola. Do not change the path.

The Spanish article should have a path of example.com/es/hello

In fact, the Spanish article will have a path of example.com/es/hola thus translating the path even though URL is supposed to be untranslated.

to work around this, the editor can manually set the url on the spanish translation back to /hello thus setting the URL back to example.com/es/hello. But, if the automatic URL is used, the url is translated based on the spanish title rather than using the untranslated english path.

Also, before an article is translated, untranslated nodes loaded in Spanish can get a path example.com/es/node/1 instead of example.com/es/hello

lauriii’s picture

Status: Postponed (maintainer needs more info) » Needs work

I was able to reproduce this with the steps in #171. The key step is to not enable translation for URL alias field when enabling translation for the content type. 👍

narendraR made their first commit to this issue’s fork.

narendraR’s picture

Status: Needs work » Needs review

After applying patch #161 for 11.x in MR, url alias(admin/config/search/path) with Language None is created.

smustgrave’s picture

Issue summary: View changes
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Updated issue summary after also confirming the issue following steps in 171

Applying the MR does resolve the issue for me.

Berdir’s picture

Status: Reviewed & tested by the community » Needs work

Some thoughts on this, I didn't look at everything in depth, but posted a few comments on the test as well, pretty sure that's not quite ready and needs some cleanup, it's obvious that parts of it are very old.

* We need to be careful about existing sites here, as this changes the behavior for them suddenly. Until now, the translation setting on this field didn't really do anything and there are two possible cases to consider here:
** Sites that accidentally have this configured but don't actually want this behavior. There's not much we can do about that, but we should have a change record and probably also a release snippet to tell users to review their alias field translation setting and enable it if they want to have per-language aliases.
** Sites that would like to have this behavior, tried it, are not using this patch but kept it as that. That's fine, it will start to work for them now. We do however need to make sure that existing aliases continue to work. Specifically, that means the alias lookup should be the language or UND, not either or (exclusive OR) the other depending on the setting. Maybe that's already covered in tests, but we should do a manual test as well. Either by creating content first then applying the patch, or changing the translation setting.
* There is a very strange and unfortunate module exists check that was added in #121 and was never talked about again later. Hardcoded module exists checks are really not nice. If it's needed, then other modules might need it too and won't be able to add the same workaround. Or it's not needed and we should instead fix some tests like many other tests were adjusted as well. Can we remove that snippet and see what exactly ails and look into that?
* Not a problem, just a note. There's a similar but different use case of alias fallbacks: #3091336: Allow altering of the language fallback for path aliases. The difference is that you can *optionally* have translated aliases if your content is translated, but if it's not then you want it to fall back to the alias of whatever language does exist. This is typically useful in combination with language fallbacks and regional/sub-languages, where not all content is expected to be translated. I think they are completely parallel and should not interfere, but make sure that your use case isn't actually that issue.
* This feature has also been asked for in the pathauto issue queue and I've pushed back/ignored it for now until core is consistent, now/once this actually happened, pathauto will need to be updated as well to correctly respect this setting as well.

Internetter’s picture

Hi,

we also actually use the patch, but with the module language_neutral_aliases.
We test a lot of variants, but it seems that only the module really works.

With the patch from #161 alone it is not really working. We have
* Languages DE and EN
* Content is translatable, but url alias field is not translatable
* url alias pattern is set for all languages

But in result for new created content the path alias is set in database for DE language only. Not for "UND" (language neutral). So with no translation the path alias won't work with the second language.

If the path alias field is not translatable, the path alias should always be set to langcode UND, what the patch in our case did not do. Should it work like this?

With the module language_neutral_aliases the path aliases would be created as UND-aliases, so you can call it with other languages and get the default language not translated content. And of course the path alias stays always the same. (we use a alias pattern with node:source:title) so it is using always the original language title.

Bye
Martin

Berdir’s picture

This issue will only work with manual aliases, not pathauto, that will need to be adressed separately in that module

yash.rode’s picture

Status: Needs work » Needs review

Hi, I am bit confused between #171 and #180. #171 says we need to enable pathauto to reproduce this issue and #180 says we shouldn't.

What are the steps to reproduce without using pathauto for this issue, as suggested by @Berdir?

tim.plunkett’s picture

The STR include enabling Pathauto, but as @berdir points out in #180, this should be reproducible in vanilla core.
Can someone update the IS to explain how to reproduce this without Pathauto?

Greg Boggs’s picture

heh, that's my fault. Y'all are correct. I didn't realize drupal core generates aliases without pathauto because I've never seen a Drupal site without Pathauto. After looking at core without Pathauto We'll need a separate ticket in Pathauto for the Pathauto part.

smustgrave’s picture

So are the steps in #171 accurate minus the pathauto module?

smustgrave’s picture

Status: Needs review » Needs work

Tried following #171 without pathauto and the steps aren't super clear. Do we need to manually set the alias now?

Berdir’s picture

> Do we need to manually set the alias now?

Yes.

DenisVS’s picture

I have this issue in my D10 site — unable to use language-neutral alias on second+ language.
Which patch do I have to apply?

vistree’s picture

I updated the patch from #161 to work with Drupal 10.2.3. Only one small change within core/modules/jsonapi/tests/src/Functional/NodeTest.php