If the default language switcher bar is giving you trouble, this might help you out.

This snippet suits you if:

  • You have a site with all language modules configured
  • Test prefix-language switching by doing the following:
  • You have nodes with language-specific content (haven't tested it with language-neutral content, but don't anticipate any problems)
  • You want your users to be able to switch to the same page in a different language, but the language switcher block isn't working

In my case, languages worked perfectly if you added their prefix, but the language switcher just didn't work. So I made a simple custom block to emulate its functionality.

The following have been tested on Drupal core 6.17, using modules: Locale and Content Translation from core, and Internationalization from contribs.

It's really nothing fancy, but if you have improvements or find it useful, let me know:

Add a custom block via /admin/build/block/add
Use PHP filter for the body ( you need to enable the PHP filter module if you cannot see this )
Paste in the following code:


// Switch to FALSE to get an english-only menu
$use_native = TRUE; 

//*************************************
// DON'T EDIT BELOW THIS LINE
global $language;
$languages  = language_list();
$active     = "";


// Must remove this from URL before passing to l()
$active_langs = array_keys($languages);       // Get an array of lang objects
$prefix       = "/".$language->language."/";  // Build the active lang prefix
$path         = request_uri();                // Get the current URL

if ( strpos($path, $prefix) !== FALSE ) {
  // Active path carries a language prefix, remove it
  $path = substr($path, strlen($prefix));
} else {
  // Even with no prefix, must remove starting '/' to allow Drupal
  // to recognise the path as internal
  $path = substr($path, 1); 
}

// At this point you have the clear relative path to the current page, 
//  eg "content/my-cool-story"

print '<ul class="language-switcher">';
foreach ( $languages as $lang) {
  // Add an aditional class to apply CSS to active language
  if ( $language->language == $lang->language ) { 
    $active = " active"; 
  } else {
    $active = "";
  }
  // Choose language label
  if ( $use_native ) { 
    $label = $lang->native;
  } else {
    $label = $lang->name;
  }
  
  print 
    '<li class="language-option'.$active.'">'.
      l($label, $path, array('language'=>$lang)).
    '</li>';
}
print "</ul>";

Save and you're done.

A couple of notes:

  • You can change the variable $use_native to FALSE if you prefer an all-english menu, like "English Greek Italian" instead of "English Ελληνικά Italiano"
  • The code adds some CSS classes to your block:
    • language-switcher to the entire ul
    • language-option to each language list item
    • active to the active language item

Enjoy :)

Comments

primobruno’s picture

Hello there:

Could you help me to substitute the language names by flags ?
i have the flags working with i18n.
Much appreciated.

primobruno’s picture

I have finally "converted" this block to use the flags from the "language-icons-flags module".
Added $image variable and set html=true because if it's set to false the <> becomes & l t ; and & g t ;
Thanks again for sharing.



// Switch to FALSE to get an english-only menu
$use_native = TRUE;

//*************************************
// DON'T EDIT BELOW THIS LINE
global $language;
$languages  = language_list();
$active     = "";


// Must remove this from URL before passing to l()
$active_langs = array_keys($languages);       // Get an array of lang objects
$prefix       = "/".$language->language."/";  // Build the active lang prefix
$path         = drupal_get_path_alias($_GET["q"]);                // Get the current URL

if ( strpos($path, $prefix) !== FALSE ) {
  // Active path carries a language prefix, remove it
  $path = substr($path, strlen($prefix));
} else {
  // Even with no prefix, must remove starting '/' to allow Drupal
  // to recognise the path as internal
  $path = substr($path, 0);
}

// At this point you have the clear relative path to the current page,
//  eg "content/my-cool-story"

print '<ul class="language-switcher">';
foreach ( $languages as $lang) {
  // Add an aditional class to apply CSS to active language
  if ( $language->language == $lang->language ) {
    $active = " active";
  } else {
    $active = "";
  }
  // Choose language label
  if ( $use_native ) {
    $label = $lang->native;
  } else {
    $label = $lang->name;
  }
  // Replace 'sites/all/modules/languageicons/flags/' for the actual path of the flag images
$image      = '<img src="' . base_path() . 'sites/all/modules/languageicons/flags/' . $lang->language . '.png"/>';

  print
      '<li class="language-option'.$active.' '.$label.'">'.
      l($image, $path, array('language'=>$lang, 'html' => 'true')).
    '</li>';
}
print "</ul>";
fanton’s picture

Work fine in Drupal 7.12.

Show only enabled languages, change:

$languages = language_list();

for:

$languages = language_list('enabled');
$languages = $languages[1];

In Drupal 7.

randa.elayan’s picture

Thank you. But how to get the alias of the translation, for the inner pages too?

marty.true’s picture

Yes, my questions as well... This works great to change the language domain but the alias is not translated in the switched URL.