We have a great feature to allow different paths per language.
Main issue I have with that when you create English content, there is no French path. This means when viewing the site in French, that piece of English content has an old node/x path, not a French path. In some cases it even leads to a 404 page, because a specific path does not exist in French.

This is a problem for mixed content sites, where the Drupal interface may be switched languages, but the mixed language content and its paths should be accessible everywhere.

So this is the issue:
- create an english language node
- pathauto generates the english path
- problem: the french path is not generated.

This piece of content only gets an english path, not both.

In my case the solution seems to be changing all paths to 'und', which means they are available for All. my paths include the [nid] token aways, so I dont get duplicate paths anyway.

So in pathauto.inc before

    // Save the path array.
    path_save($path);

I added an extra line

$path['language'] = LANGUAGE_NONE;

To force neutral-language paths for whatever mixed language content. The idea is that a path should always be available in every site-language, regardless of the content language.

Comments

morningtime’s picture

So perhaps that should be a pathauto setting, "Force neutral paths: yes/no".

catrina’s picture

Just implemented this...hoping that it works! Thank you for the suggestion. -catrina

Dave Reid’s picture

Status:Active» Fixed

See also #1289550: Alias for all languages. This is not likely to be an option in Pathauto any time soon.

akamaus’s picture

Status:Fixed» Active

@Dave Reid

This is not likely to be an option in Pathauto any time soon.

Why so? Do you mean it goes against your vision of Pathauto or you just don't have a time to implement it?

morningtime’s picture

Never mind

clashar’s picture

Visard’s picture

I support morningtimes idea - It works !

It must be simple to put a "yes/no" - for now it works, but can overwritten by a update...

Gr3fweN’s picture

subscribe

akamaus’s picture

It must be simple to put a "yes/no" - for now it works, but can overwritten by a update...

Visard, do you have the code? If so, could you please share it?

clashar’s picture

morningtime, thank you! your solution works like a charm.
Would be nice too see the option in pathauto interface.

marvil07’s picture

Status:Active» Fixed

Why so? Do you mean it goes against your vision of Pathauto or you just don't have a time to implement it?

I guess this is because it's now possible to do it using hook_pathauto_alias_alter(), that hook is well documented and it actually includes the code for doing this.

To be completely specific, the needed hook should look like this:

<?php
function yourcustommodule_pathauto_alias_alter(&$alias, array &$context) {
 
// Force all aliases to be saved as language neutral.
 
$context['language'] = LANGUAGE_NONE;
}
?>

So, since this is a support request, I guess it's safe to mark it fixed.

clashar’s picture

what about interface option? otherwise we should be obliged to patch every time after any upgrade.

akamaus’s picture

In case someone is interested, I've created a tiny sandbox module for this. Upon enabling it resets all the existing paths to be language neutral and alters new ones as they're created.

http://drupal.org/sandbox/akamaus/1420990

Status:Fixed» Closed (fixed)

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

skyredwang’s picture

Category:support» feature
Status:Closed (fixed)» Active

I don't why we wouldn't add this in as a new feature? Sounds very useful to me.

One thing I am concerning is that if we have one alias for all language, and another alias for (e.g.) English. So, when the UI is in English, pathauto should try to use English alias first. But, the current code doesn't

skyredwang’s picture

Another direction is that we don't throw 404 when the alias language doesn't match UI language (or make this an option)?

liquidcms’s picture

Category:feature» bug

not sure i exactly understand this but is this the same bug i am seeing?

i have a fr/en site but specific node type is not set to be translated. as a result i have only the one entry in pathauto patterns for this node type. this is all correct.

when i create a new node, the language for the entry in url_alias is EN. pretty sure this is wrong. it should be UND. but it sort of sounds like this fix described here is making ALL url_aliases UND; which can't be correct as some will be EN and some FR and some will be UND. if this is the same issue as reported here this is obviously a bug; so changing to bug; if my issue is something else; please let me know and flip back to feature request.

liquidcms’s picture

one test i did:

- node type is translatable nodes
- node/103 | en-test | en
- node/104 | fr-test | fr

- when i go to node/103, url is correct
- when i hover over my custom language switcher to switch site to FR, the url is also correct (fra/fr-test)

if i now change both these entries to und, everything still works as it should

perhaps the language selector is more for nodes with translated fields. where there would be this:

- node/103 | en-test | en
- node/103 | fr-test | fr

that makes sense.

so what i am reporting is still a bug. non-translatable nodes should get und. plus i am also seeing another bug in pathauto (should make sep issue) is that i see entries for the same non-translatable node with one as EN and the other as UND. possibly node type switched from translatable to non? but when node was updated it should do a replace of the url alias entry; not add a new one (i.e. should never have UND and a language for same node).

liquidcms’s picture

ok, after debugging this a little i see issue is from somewhere other than pathauto; perhaps i18n? the language of the non-translatable node is passed to pathauto with $node->language = 'en'; which is incorrect as it should be 'und'.

although as i think about this my guess would be this is more likely a core bug in how Drupal handles language in general. I am sure if i set the node type to be translatable and set the language specifically as lang neutral; then it will pass und (next test); but as Drupal bases everything by default in EN; my guess is if not explicitly set to neutral (which i can't do for this node type as it is not translatable) then it gets EN by default (which is wrong).

liquidcms’s picture

and sure enough that works. so setting the node as translatable and saving the node as neutral lets pathauto do the right thing.. so my issue (which is maybe different than being discussed here) is likely more with i18n and/or core. ughhh!!

liquidcms’s picture

just to close off on this; and extending from what marvil07 posted above; i think this is better:

function mycustommodule_pathauto_alias_alter(&$alias, array &$context) {
  if (!i18n_node_type_enabled($context['data']['node']->type)) {
    $context['language'] = LANGUAGE_NONE;
  }
}

although i still think a bug in core; but from what i heard at Drupalcon i think D8 will no longer have concept of a base language; so this is likely already fixed there.

Madrugada’s picture

akamas' solution @ 13 worked for me.

I'd enabled a content type with the ability to post in different languages, but without translation capabilities enabled.
When I posted the content as 'English' the URL generated by pathauto worked correctly (mysite.com/stories/madrugada/my-story)
When I posted the content as 'Portuguese, Brazil' the URL no longer showed with the correct alias (becoming mysite.com/node/321 instead)

After installing the module @ 13, nodes I posted in the language 'Portuguese, Brazil' were accessible from the desired pathauto-generated url as well. This was great because some content was available was in English, some was in Portuguese and it didn't seem right that Portuguese nodes were not given aliases.

TimeFor’s picture

Wow, this has been a problem for years. I remember this issue back in D6. #13 actually works and its so simple. Its not perfect for everyone, but if you don't require translated paths its an easy solution. I just never wanted to see those node/nid paths anywhere.

-Time

facal’s picture

+1 for #21, I have now been using it for months

Carlos Miranda Levy’s picture

Module neutral_paths on #13 by akamaus provides the behaviour most of us running dynamic multi-language sites require. It converts all existing paths to neutral language and makes sure new paths generated are neutral as well so that they work on every language.

The automatic behaviour of pathauto with content translation (or Internationalization) only matches the need of sites where you have total translation of all content and only language specific content is shown according to the language selected, so that if you choose Spanish, only Spanish content is visible to you, if you choose English, only English nodes are shown to you, etc.

This is OK and perfect for brochure, institutional and informative websites, but does not match the needs of most multi-language sites with dynamic, user-generated or multiple user contributed content. As it is designed today, it creates a path only for the language that matches the language of the node being aliased. This means that if I have Spanish selected as interface and click on an option to open an English document, I will get "node/xxx" because there is no alias for the node in English when visualizing it with Spanish language selected.

You can of course always go the list of Aliases, and manually switch each generated alias to "All languages". But you would have to do this every time a new content is generated, which is unrealistic for collaborative sites and tiresome for sites where you will be adding plenty of content, requiring 3 additional steps for each content added (go to URL Aliases, click on Edit alias, switch to All Languages and then submit).

Module neutral_paths on #13 by akamaus solves this as it converts all existing paths to neutral language and makes sure new paths generated are neutral as well so that they work on every language.

For those who still don't get what the problem is, it is very basic: On a multilingual site, say English and Spanish, content on both languages should be visible to the user regardless of the interface or personal language choice the user makes. So if you are reading an article in Spanish and see the link at the bottom to see its English version, clicking on it should open the path alias of the English version (not node/xx) regardless of the interface language or user language of choice.

For example (real life example), on a website for a public figure, there is a page with her bio in Spanish with the alias "info/biografia". We have translated the node to English and assigned it the alias "info/biography". Yes, they are visible as es/info/biografia and en/info/biography. But the most likely scenario is that someone reading the document or arriving to it from Google, clicks on the English link. Normal behaviour takes the user to the English translation without switching languages and opening node/xx because normal pathauto behaviour only creates a path for the language selected for the node and no path for the node in other languages.

This feature is a must have, a basic need to every site that allows switching the language of a content or navigating to its translation and does not rely exclusively on the block for switching languages.

brulain’s picture

Subscribing !

zanndoth’s picture

Version:7.x-1.x-dev» 7.x-1.2

Many thanks for the fix.

Formerly on the website I'm working on, when the 2nd language is selected, hovering over "About Us' menu would point to 'node/02'. But now, it's pointing to "about-us/", as it should be. However, I noticed another peculiar problem with this fix.

If delete all the aliases and do a "Bulk Update", it points to "about-us-0/" instead of "about-us/". Similarly, if I add a new translation to an existing page, the same issue can be seen. I've tested on both 7.x-1.2 & 7.x-1.x-dev.

Anyone facing this issue as well? Any ideas?

Regards,

Zann H

Edit: I didn't manage to solve this issue but I manage to fix my problem. I gave Entity Translation a whirl, and it works just how I wanted. Single menu, and multi-lingual content. And no issue with Pathauto. =)

liquidcms’s picture

my code in #21 is not valid for the case where the node type is using Entity Translation (i.e. translatable fields).

it should likely be this to cover both methods:

<?php
function mymodule_pathauto_alias_alter(&$alias, array &$context) {
  if (
i18n_node_type_enabled($context['data']['node']->type) || entity_translation_node_supported_type($context['data']['node']->type)) {
    return;
  }
 
$context['language'] = LANGUAGE_NONE;
}
?>

and likely wouldn't be a bad idea to wrap a couple module_exists() in there for checking if i18n/et are enabled

MXT’s picture

Carlos Miranda Levy’s picture

This issue remains.
I recently encountered the same problem on a community site where people can choose to switch the interface to their preferred language, but content translation is not enabled. So you would not expect to have problems. This is a literary community where most people post in Spanish, but you are welcome to post in other languages, including Catalan and Portuguese. New content was being saved as Spanish and aliases not working unless the user had selected Spanish as it language.

Again, an alias should work regardless of the language selected by the user. It is pretty counter intuitive and bad practice to have url addresses only work for some users and not for others. For example, alias /blog/mi-historia should be visible to anyone, regardless of language, because that is where it is posted. You should not get an error if you choose your language to be English and try to visit /blog/mi-historia.

Again the Neutral Paths module fixed this.

I just wanted to point out that the problem exists even if you don't enable content translation.

nellngun’s picture

Hi, can somebody explain my what did u do that is working? My nodes now are good i mean en/node/id, es/node/id but there are stil 'node' without a name of content, fallowing your post, this is my .inc

EDIt: all paths are added now in path.module and autopath.module but for me wasnt working still.
Fixed. I did like in the topic post:

pathaut.inc

looks like this:

$path['pid'] = $existing_alias['pid'];
          break;
      }
    }
$path['language'] = LANGUAGE_NONE;
    // Save the path array.
    path_save($path);

Works perfectly for me. I changed also detection options on:
urweb/admin/config/regional/language/configure

Enabled
* Session
* User
* Default

OnkelTem’s picture

Version:7.x-1.2» 7.x-1.x-dev

The option to use or not use translatable paths should be in the module UI.

tafkey’s picture

+1

rolfo85’s picture

Hi,

I have a problem. I work with Entity Translation and Neutral_paths Module.
For default setting i have checked the language fallback.
I have a new contents for default language in italian and the alias work correctly because are the same of italian language (also in the other languages, english for example).

Example:

"Chi siamo" (new contents created in italian language and not translated in other languages)
alias: "chi-siamo" (the alias is the same in all languages) Perfect !

The problem

If i translate the node "Chi siamo" in english for example, the result will be "About us" and the alias will be "about-us" good ! BUT.... if i switch to the italian languages, the node "Chi siamo" will have the alias "about-us" not "chi-siamo" .

Every translation of node that will be editing, will have the same alias shared in 2 languages. This things is correctly only if i don't have translations.

Can you help me ?

Talkless’s picture

So... there is not going to be "official" settings for this matter?

Talkless’s picture

Issue summary:View changes

typo

suffering drupal’s picture

Issue summary:View changes

This thread is very confusing...
In the first place, I have struggled through D4, D5 and D6 for years, with always tear shedding problems with Drupal as a whole and many, many modules EXCEPT precisely multilanguage and pathauto. So I ended up with several crooked, hardly functional websites but they have always worked well in at least 4 languages, with their corresponding aliases and having the content in that specific language, without any trouble to jump to another language if someone wants to: my personal site, www.independencyproject.org, www.on-map.net, www.globalopinion.eu. just like indicated in #25

sites where you have total translation of all content and only language specific content is shown according to the language selected

Of course! I frankly don't see any sense in understanding internet in any other way.

So, I how come this suddenly is a problem in D7 and apparently still unsolved after several years???

Anyway... I don't understand the given solution(s?).
I understand the initial proposal DOES produce aliases, but then does not differentiate in language, is that correct? So if you are NL, you are still receiving either EN, ES or IT, for example?
#11 What does it do? What should one do with it? Where do I put it? Why is that enough to consider "fixed"?
#13 Sandbox... yeah, so I go there, but no link for downloading and trying.
#21 Extending #11? Interesting, but the questions stay the same...
#31 Works? So how come nobody reacted to that? (unfortunately can't try for myself at this moment, but at least it is an understandable option.)

I am not even sure if the given solutions/workarounds are one and the same or different, nor what result to expect. Does it mean D7 simply does not have a working option for (again)

sites where you have total translation of all content and only language specific content is shown according to the language selected

preferibly with corresponding language aliases?

mccrodp’s picture

A slight update to #21, hope I've got the module names right, I think so. As I am not using them on this site, we need module_exists checks.

<?php
/**
Implements hook_pathauto_alias_alter.

Set the language of our alias to neutral so that the alias is generated for all languages.
We do not force language neutral if we have a node type being managed by other
translation modules so we return early.
*/
function mymodule_pathauto_alias_alter(&$alias, array &$context) {
  if ((
module_exists('i18n_node')
    &&
i18n_node_type_enabled($context['data']['node']->type))
    || (
module_exists('entity_translation')
    &&
entity_translation_node_supported_type($context['data']['node']->type))) {
    return;
  }
 
$context['language'] = LANGUAGE_NONE;
}
?>

This is a hook provided by the pathauto module. In the code snippet above it is added to our custom module called 'mymodule'.

joelpittet’s picture

@mccrodp Thanks that was helpful and solved my issue!

Some node types were just miss behaving it seemed, webform node type was my litmus test for that hook in #37

Eugene Fidelin’s picture

Code in #37 solves the issue for newly created nodes/taxonomy/users in case path is not specified manually.
If you want url aliases to be language neutral even if path alias is entered manually, you can use following code:

<?php
/**
 * Implements hook_path_insert().
 */
function MYMODULE_path_insert($path) {
 
_MYMODULE_path_language_fix($path['pid']);
}

/**
 * Implements hook_path_update().
 */
function MYMODULE_path_update($path) {
 
_MYMODULE_path_language_fix($path['pid']);
}

/**
 * Fixing a given path id.
 */
function _MYMODULE_path_language_fix($pid) {
 
db_update('url_alias')
    ->
fields(array('language' => LANGUAGE_NONE))
    ->
condition('pid', $pid)
    ->
execute();
}
?>

If you already have lot of existing content with wrong language - then this module will help you https://www.drupal.org/sandbox/akamaus/1420990

Or you can run once the following code:

<?php
function _neutral_paths_set_all_to_neutral($type) {
 
$num_updated = db_update('url_alias')
    ->
fields(array('language' => LANGUAGE_NONE))
    ->
condition('language', LANGUAGE_NONE, '!=')
    ->
condition('source', $type . '/%', 'LIKE')
    ->
execute();
  if (
$num_updated > 0) {
   
drupal_set_message(t('@num aliases were reset to language neutral', array('@num' => $num_updated)));
  }
  else {
   
drupal_set_message(t('No aliases were updated.') . $type);
  }
}

_neutral_paths_set_all_to_neutral('node');
?>