How to: Language Switcher Menu Item

For many bilingual websites, the standard Language Switcher block that comes with the locale module (shows both language links in one block)  will suffice. However, for Canadian Federal Government sites, the more typical method is to have a menu item in the top nav which shows only the single flip language.

I have come across a few implementations of this all which are implemented in templete.php. Since this is not the correct way to do this (since this is not a theme function) I thought I would document how we do this at LiquidCMS.

The following code is for D7 but almost identical to what is used for D6.

in a module (where it belongs) add the following 2 hooks:

function yourmodule_menu_link_alter(&$item) {
  if (
$item['link_title'] == 'Français' || $item['link_title'] == 'English') {
$item['options']['alter'] = true;

yourmodule_translated_menu_link_alter(&$item, $map) {
  if (
$item['link_title'] == 'Français' || $item['link_title'] == 'English') {
$languages = language_list('enabled');
$path = drupal_is_front_page() ? '<front>' : $_GET['q'];
$links = language_negotiation_get_switch_links('language', $path);
$pick['en'] = 'fr';
$pick['fr'] = 'en';

$item['href'] = $links->links[$pick[$language->language]]['href'];
// add on rest of GETs to path
$gets = $_GET;
$gets['q']);  // remove q
if (count($gets)) $item['localized_options']['query'] = $gets;
$item['localized_options']['langcode'] = $pick[$language->language]; 
$item['localized_options']['attributes']['class'][] = 'language-link';     
$item['localized_options']['attributes']['lang'] = $pick[$language->language];
$item['localized_options']['attributes']['xml:lang'] = $pick[$language->language];
$item['localized_options']['language'] = new stdClass();
$item['localized_options']['language']->prefix = $languages[1][$pick[$language->language]]->prefix;   
$item['localized_options']['language']->language = $pick[$language->language];

The first function is simply to set the items in the menu_link table to have 'alter' = true. This allows the 2nd hook to be hit which does the actual work.

After adding the code in place; simply add 2 menu links to whatever menu block you need them. A french one with the menu title as "English" and an english one with the menu title as "Français". It doesn't matter what you set the path to for these as our hook code will alter the href of the link to what were need it to be for each page. So go ahead and simply set them both to 'node'.

That's it.


Drupal Version: