Manually Creating Path Translations in Drupal

Creating a multilingual Drupal site includes tranlsating not only content and interface strings, but also things as basic as paths. This can be a challenge when working with modules like Views, which only accepts one version of the path for a given page display.

Translating Paths with URL Aliases

There are a few solutions to this problem. If you want to use the same Views configuration in every language, you can use a URL Alias to translate the path of the View, while keeping all the filters and fields the same.

Just go to Site Building > URL Aliases > Add Alias. Here, you can create an alias for the view in a new language, by choosing the language, entering the existing alias and then adding an alias in the the new language.

Translating Paths with a Custom Module

If the configuration of the view is language dependent, you can create a separate Views page display for each language. Then, you'll be adding a different path for each page display, in the correct language. In order to associate these paths together, you'll have to call hook_alter_translation_link() in order for the language switcher to send users to the correct translation of these paths.

For example, you might want to create two page displays for a View displaying news items, the English page at the path '/news' and the French display at the path '/nouvelles'.

You can add this code to your custom module and replace the languages with those you need. I've filled in English and French.

<?php
/**
 * Implementation of hook_alter_translation_link().
 *
 * Replaces links with pointers to translated versions of the content.
 */
function mymodule_translation_link_alter(&$links$path) {

  

$path_translations variable_get('ew_path_translations', array());

  foreach(

$path_translations as $pair) {
    
$translations[$pair[0]] = array('fr' => $pair[1]);
    
$translations[$pair[1]] = array('en' => $pair[0]);
  }

  if (

$paths $translations[$path] ) {
    foreach (
$links as $langcode => $link) {
      if (isset(
$paths[$langcode])) {
        
// Translation in a different node.
        
$links[$langcode]['href'] = $paths[$langcode];
      }
      else {
        
// No translation in this language, or no permission to view.
        
unset($links[$langcode]);
      }
    }
  }

?>

This will allow you to map paths together in your settings.php file. You just need to add the following snippet to your settings.php file and fill in your own paths. Remember to use the same order of languages as you did in mymodule.module (above).

<?php
$conf
['mymodule_path_translations'] = array(
    array(
'news''nouvelles'),
    array(
'products''produits'),
);
?>

Views with Arguments

If you're creating a view with arguments, and your arguments are strings, the techniques above won't translate the arguments appearing in the path. We've written some custom code to address this problem, and are hoping to release this as a module, or at least write a follow-up post explaining that technique, in the near future.

Comments

Thanks, very useful bits of code. I used that for both Views and Panels.
I still am quite surprised one has to implement this to get that result, and that it is not managed by either i18n, Panels, Views...

I have one question though: when I create a path translation as described above, my "Français" link in the language switcher does get the correct, newly defined path.
But then when I click "Français", my "English" link disappears. Is there a condition that is not fulfilled in the language switcher module?

thanks for your help,

Very helpful!

It would seems that $path_translations = variable_get('ew_path_translations', array());

should be $path_translations = variable_get('mymodule_path_translations', array());