I have used the code found here http://drupal.org/node/313814. This code returns a themed link to the translation of the current path.
But this makes theming difficult sometimes - I'm not a CSS expert and I have a hard time when things line up properly in one browser but not in others. In many cases the designers I work with like to display the language switcher as part of a menu. I've messed around with absolute positions for the language link so it sits next to the other menu items, but it always ends up a pixel or two off in one browser compared to another.
I'd like to get the translation link to be part of the menu and I've made some headway to achieve this.
Unfortunately I hit a problem which I can't seem to resolve.
Here is the implementation of hook_menu(), using only a wildcard for the path. Please note that at this point my solution would only work for a site that implements no more than two languages. Looping through all implemented languages to create an individual menu item for each would solve this, and that's on my todo list. But I'm in a bit of a hurry to get this site out (no surprise there!) and I know it won't implement more than two languages.
<?php
function langswitch_menu() {
$items['%langswitch_pathmaker'] = array(
'title' => 'title',
'title callback' = langswitch_get_translation_language(),
'page callback' => 'langswitch_houston',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
?>The page callback is set to a dummy function, since it seems mandatory.
The title callback returns the name of the other implemented language (the one that is not current language).
The menu path, set to a wilcard '%langswitch_pathmaker' creates a dynamic path using a function named langswitch_pathmaker_to_arg().
Here is that function:
<?php
function langswitch_pathmaker_to_arg($arg) {
// this is copy&paste from locale_block in locale.module
$languages = language_list('enabled');
$current = i18n_get_lang();
$links = array();
foreach ($languages[1] as $language) {
if ($language->language != $current) {
$links[$language->language] = array(
'href' => $_GET['q'],
'title' => $language->native,
'language' => $language,
'attributes' => array('class' => 'language-link'),
);
}
}
// this adds the real paths, i.e. if we are on a german page,
// the british flag will point to en/english_alias instead of
// en/node_with_german_content
translation_translation_link_alter($links, $_GET['q']);
// In a real module some looping needs to happen to implement more than two languages.
unset ($languages[1][$current]);
$language_object = array_pop($languages[1]);
return $links[$language_object->language]['href'];
}
?>This almost works except for one big problem. The language prefix to the path is the current language, and should be the other implemented language.
The link will point to the translation once, which will show the translation in the current language context. After that all fails.
For example, if I'm at fr/node/12 and the english translation for this path is node/13, the menu item's path will be fr/node/13. I need it to be en/node/13.
I have not been able to figure this one out. Any idea how to resolve this?
Thanks for any help!
I've also posted this as a support request to i18n here http://drupal.org/node/547284

Comments
Attached menu
I've attached module files that implement this code in my issue at i18n. This is the link http://drupal.org/files/issues/langswitch.zip
Hi... just a question (after
Hi... just a question (after more then one year).
Do you solve your problem? Does a module exist?
I need the same: a menu item for language switching... :(
Thank you
Not really I don't think.
Not really I don't think. You can roll your own from the code above, but I have come to the conclusion that it is smarter to improve the design instead. You can make it look as part of a menu by putting the language links last and styling the block markup appropriately.