Problem/Motivation

PathautoGenerator::createEntityAlias() only generates an alias for the entity object received. However, if in the same operation more than one translation is affected (for example when you create by code an entity that has different values for some of the translations), those will be ignored and the alias will not be created.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork pathauto-2973478

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

marcoscano created an issue. See original summary.

marcoscano’s picture

StatusFileSize
new924 bytes

And the test-only patch.

damienmckenna’s picture

Component: Code » I18n stuff
seanb’s picture

Status: Active » Needs review
StatusFileSize
new2.61 KB
new1.68 KB

Changed pathauto_entity_insert() and pathauto_entity_update() to update aliases for all translations of an entity. I thought about doing this only for new translations in hook_entity_translation_insert(), but then when you programmatically change data in more than 1 translation (which could mean the alias changes) the alias is also not automatically updated.

An example of this would be media where you can queue the fetching of remote metadata. When the queue is processed, the metadata could contain an updated title for the media item, which would lead to a new alias.

Even though this could have an impact on performance, especially when doing large bulk operations, I think this is the right thing to do.

berdir’s picture

Thanks for starting this. I would expect that we can use \Drupal\Core\Entity\TranslatableRevisionableInterface::isRevisionTranslationAffected() so that we can optimize this a bit.

Otherwise the performance overhead could be huge on sites that have 10 or so languages.

berdir’s picture

Status: Needs review » Needs work
mbovan’s picture

We had this issue popping up again in combination with Replicate module.

I tried to update the patch and use \Drupal\Core\Entity\TranslatableRevisionableInterface::isRevisionTranslationAffected() from #5 but didn't get it working as I would expect.
I think it was related to the fact that translations were not changed but the URL patterns were translation specific.

I can confirm patch #4 works good - except for the performance impact...

devkinetic’s picture

Running #4 as well here.

reszli’s picture

I also ended up using patch from #4 for having aliases generated when merging nodes using the Merge Translations module

bohus ulrych’s picture

Hi all,
thank you for patch #4, it works for me and is doing what was described in Problem/Motivation - it creates alias for other existing translations. (If you want to create aliases also for non-created translations, this is discussed here: Pathauto not working for untranslated nodes? #2982091)
Also note that this patch doesn't work when you will try to trigger Action "Update URL aliases" on the Content page as no hook_entity_insert() or hook_entity_update() are used.

devkinetic’s picture

Good find, this will need to be added.

damienmckenna’s picture

Status: Needs work » Needs review
StatusFileSize
new2.65 KB
new1.21 KB

@Berdir: Do you mean something like this?

damienmckenna’s picture

Status: Needs review » Needs work

The change in #12 breaks the logic, so scrap that.

thijsv’s picture

Patch in #4 works! Thank you.

radelson’s picture

The comments here are mentioning multiple times that this issue applies to nodes manipulated programmaticaly, I wanted to add that it's also an issue when using the backoffice. When a field marked as untranslatable is used as a token in a pattern applicable to a translation, all the aliases should be regenerated.

1) Create a path alias pattern for a node bundle using for example the title of the node as a token
2) Make the title field untranslatable and the path alias translatable for this node bundle
3) Create a node and check its alias
4) Translate the node, you won't be able to change the title and the alias will be the same as the untranslated node
5) Edit the original/untranslated node title
=> the original node alias is updated but the translation alias is not updated (the old title is still used in the translated alias even though it should have changed)

kmani’s picture

I think this will help someone. this will create the original language url alias

/**
 * 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);
      }
    }
  }
}
bbu23’s picture

Thank you! #4 works for me as well :)

bceyssens’s picture

#4 seems to do the trick for us!

squinternata’s picture

Great solution!! #4 works really well!!
Thanks
A

Anonymous’s picture

Hello, I've been testing the patch from #4 and I can confirm that it resolves the problem specified in the issue summary.

I can also confirm that this is reproducible from both the usage of GUI and usage of the programmatic method.

igork96’s picture

Status: Needs work » Reviewed & tested by the community

I have tested the patch from #4 and can confirm that is working. Marking this as RTC.

louis-cuny’s picture

#4 Worked for me too !

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

urvashi_vora’s picture

Patch #4 works great for me as well. RTBC ++

Thanks for the work.

kburakozdemir’s picture

Thanks for the work.

Patch #4 works great for me as well.

millerrs’s picture

Can also confirm that #4 works.

kriboogh’s picture

This is a 5 year old patch that multiple people have mentioned works.
What is holding it back to get it in the next release ?

p4trizio’s picture

Patch #4 works great

berdir’s picture

Re #12:

It would need to be within the loop, but as commented by others, there are cases where aliases still need to be updated even if the translation didn't change, so I suppose not much can be done about that.

#28: The performance concerns, mostly.

This might hurt sites with a lot of languages quite a bit. There are now 3 places with this loop, the first one is in bulk generate. Also, we have issues like #2946354: Alias not using language undefined when alias is not translatable with the goal of supporting language-neutral aliases. This change is going to make that more complicated because then we'd call it multiple times but really will always create/update the same alias. So this loop should possibly be within updateEntityAlias(), after checking the language setting of the field and depending on that once the other issue lands.

randalv’s picture

Thanks for the patch/MR.
I've applied the MR diff to one of our sites, and the issue has been resolved.

Hopefully this finds its way into a release 🙏

baikho’s picture

Changes in the MR work fine. Tested on:
Drupal core 11.2.2
Pathauto 8.x-1.13

berdir’s picture

Status: Reviewed & tested by the community » Needs work

This needs to updated for OOP hooks.

tcrawford’s picture

I had this patch installed and it worked for me on a site where I was programatically saving the translation only. However, I has issues where saving a translation in the UI updated the alias of the base entity incorrectly. I confirmed it was correctly configured to be translatable. I removed the patch and this is resolved. I believe somewhere a token used in the alias was resolving with the wrong language context. I did not debug further as the code that required the patch was also removed.

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

tobiasb’s picture

Status: Needs work » Reviewed & tested by the community

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

mably’s picture

Assigned: Unassigned » berdir
mably’s picture

Updated the test to include a scenario similar to the one described in #15.