I have created a drop-down language switcher. I automatically switches languages on selecting a new option from the drop-down.

  <?php
    $query = drupal_query_string_encode($_GET, array('q'));
		$path = $_GET['q'];
		$lang = translation_get_links($path, empty($query) ? NULL : $query);
		$current_lang = i18n_get_lang(); // Look up current language with a call to this i18n function, setup link array elements.
		$active_lang = i18n_languages('active'); // loop up al enabled languages
		$names = i18n_languages('native'); //look up alll native names
?>
	<form action="">
	<select name="language" onchange="window.location.href='/'+this.options[this.selectedIndex].value;">
<?php
	foreach (array_keys($active_lang) as $lang){
    $url = translation_url($path, $lang);
		$output = '<option ';
		if ($lang == $current_lang) { 
			$output .= 'selected '; 
		}
		$output .= 'value="';
		$output .= i18n_path($url.'?'.$query , $lang);
		$output .= '">';
		$output .= $names[$lang];
		$output .= '</option>';
		print $output;
  }
	?></select>
	</form>

Comments

fletchgqc’s picture

Here's what I shoved into the page template on www.cai.org (Drupal 6):

<?php
<div id="language-select-form">
  <form action="" method="post">
    <select id="language-select-list" onchange="document.location.href=this.options[this.selectedIndex].value;">
      <? $translations = translation_path_get_translations('node/' . $node->nid);
      if (empty($translations)) { ?>
        <option value=""><?php print $language->native ?></option>
      <?php } else {
        foreach ($translations as $lang=>$drupal_path) {
          if ($lang === "en") {
            $path = "/" . drupal_get_path_alias($drupal_path, $lang);
          } else {
            $path = '/' . $lang . '/' . drupal_get_path_alias($drupal_path, $lang);
          }
          $language_list = language_list();
          $language_name = $language_list[$lang]->native; ?>
          <option value="<?php print $path ?>" <?php if ($lang === $language->language) print 'selected="selected"' ?>><?php print $language_name ?></option>
        <?php }
      } ?>
    </select>
  </form>
  <img id="current-lang-flag" src="/sites/all/modules/i18n/flags/<?php print $language->language?>.png"/>
</div>
?>

I used CSS to put the language flag image next to the select list, but you can cut that bit out if you like. I doubt it's the most efficient or best-written code so improvements are welcome. However it works at least!

seutje’s picture

the spanish flag on ur front page links to the root, without es/

figured u might wanna change that ;)

and I changed the img to be something like this:

<img id="current-lang-flag" src="<?php print base_path(); ?>sites/default/modules/i18n/flags/<?php print i18n_get_lang(); ?>.png" />

coz I use a lotta subfolders n shit for multiple drupal installs on the same host, and the current language variable u used didn't return anything for me, so I used the i18n function

not sure if this also works for D6 though, I'm too scared to try :p

thx for the drop-down menu stuffs, saving me at least an hour \o/

if ur website isn't on the root of ur host (e.g. http://www.example.com) but instead it's located in a subfolder (e.g. http://www.example.com/website/) u might wanna change

<select name="language" onchange="window.location.href='/'+this.options[this.selectedIndex].value;">

into

<select name="language" onchange="window.location.href=<?php print base_path(); ?>+this.options[this.selectedIndex].value;">
momo18’s picture

I developed a Drupal 6.2 site which switches between three languages via a drop-down menu. (See www.itwrite.com)

The default site language is English, and the other two languages are Dutch and Hebrew. The site uses no "en" site name extension for English, but "nl" and "he" extensions for Dutch and Hebrew. The drupal_get_path_alias($drupal_path, $lang); function to access the language extension for a particular language didn't work for me. And so, I bypassed the function and hard-coded language selection via the select element. (I didn't mind this as I know which languages I'll be using).

I used the following section of code:

<form action="" method="post">
<p id="langformat">
<select id="language-select-list" onchange="document.location.href=this.options[this.selectedIndex].value;">
<?php 
$translations = array(
    "en" => "node/",
    "nl" => "node/nl",
    "he" => "node/he"
);

if (empty($translations)) { ?>
  <option value=""><?php print $language->native ?></option>
   <?php } else {
   foreach ($translations as $lang=>$drupal_path) {
	if ($lang === "en") {
            $path = "/";
          } else if ($lang === "nl") {
            $path = '/' ."nl" . '/';
          } else if ($lang === "he") {
            $path = '/' ."he" . '/';
          }          
          $language_list = language_list();
          $language_name = $language_list[$lang]->native; ?>
<option value="<?php print $path ?>" <?php if ($lang === $language->language) print 'selected="selected"' ?>><?php print $language_name ?></option>
        <?php }
      } ?>
</select>
</p>
</form>

Everything works fine and languages switch OK on English or other language enabled browsers in both IE and Firefox browsers. However, on a Hebrew enabled XP machine when I select English via the drop-down menu (on both IE and Firefox browsers) the language always reverts to Hebrew only if English is selected. (This does not happen with Dutch.) So I'm unable to access the English based section of the site through any Hebrew enabled browsers.

My guess is that the language negotiation mechanism somehow detects the browser's primary language (i.e. Hebrew), and since the browser language is given a "higher priority" over English - the language defaults to the browser language instead of applying the user's selected language.

Is there any way of disabling this language fallback mechanism? Is there something I'm missing here? Can it be explained? I don't mind putting an "en" extension to the site for English, if that will do the trick? How do I do that? Maybe there are better ways.

Appreciate any assistance.

Regards,

Moses

=====

Sorry, figured it out. Setting language preference to "Path prefix only", instead of "Path prefix with language fallback" fixed it, and now it works fine. Hope this helps someone else.

Regards,
Moses

sti_drupal’s picture

fletchgqc

displaying the block

 $translations = translation_path_get_translations('node/' . $node->nid);
print_r($translations);
  

returns an empty array. Array ( ).

P.s I have Alias URL active and I tried viewing on a node translated.

fletchgqc’s picture

Maybe this will help... I updated our code as follows, to ensure the languages are ordered correctly in the drop-down list. Try this code out.

<?php
      <div id="language-select-form">
        <form action="" method="post">
          <div>
            <select id="language-select-list" onchange="document.location.href=this.options[this.selectedIndex].value;">
              <?php // Code adapted from translation.module.  Search for "language_list" in that file to find it.
                if (($node->tnid) && $translations = translation_node_get_translations($node->tnid)) {
                $languages = language_list();
                foreach ($languages as $langcode => $language) {
                  if (isset($translations[$langcode])) {
                    if ($langcode === "en") {
                      $path = '/' . drupal_get_path_alias('node/' . $translations[$langcode]->nid, $langcode);
                    } else {
                      $path = "/$langcode/" .  drupal_get_path_alias('node/' . $translations[$langcode]->nid, $langcode);
                    }
                    ?><option value="<?php print $path ?>"<?php if ($node->language === $langcode) print ' selected="selected"'?>><?php print $language->native ?></option>
                  <?php }
                }
              } else { ?>
                <option value=""><?php print $language->native ?></option>
              <?php } ?>
            </select>
          </div>
        </form>
        <img id="current-lang-flag" src="/<?php print $directory ?>/images/language-flags/<?php print $node->language ?>.gif" alt="Flag representing active language"/>
      </div>
?>
prosiktuno’s picture

Hi,

Could you advice how I can use it if I don't have translation.module?
I use i18n+languageicons and when I put your code I have only one language in drop-down menu (current), but I have much more languages.

Thanks!

zeal’s picture

Hello fletchgqc,

Can you tell me where to put this code?

Thanks in advance.

joergenaj’s picture

Just what I need, but where do I put the code?

NickGee’s picture

Seemingly random nodes populate this dropdown if the node being viewed does not have a translation.

The patch and the explanation of why are here: http://drupal.org/node/289502

I spent the better part of a few hours trying to figure this thing out.
That made me register and post this comment so hopefully you don't have to do the same!

RobertoGuzman’s picture

i want to show the translation only 2 language of 4 language enable

jary’s picture

Hi this is working great. thanks for this. But I noticed that when going to the page like "contact us" the drop down only shows "english" language. Can you help me fix this. Thanks

michal.k’s picture

<div id="language_switcher_dropdown">
	<div style="color:#8f9cc1; font-family:verdana, tahoma, helvetica; float:left;">language:&nbsp;</div>
	<div id="language-select-form" style="float:left;">
        <form action="" method="post">
          <div>
            <select id="language-select-list" onchange="document.location.href=this.options[this.selectedIndex].value;">
              <?php // Code adapted from translation.module.  Search for "language_list" in that file to find it.
                if (($node->tnid) && $translations = translation_node_get_translations($node->tnid)) {
                $languages = language_list();
                foreach ($languages as $langcode => $language) {
                  if (isset($translations[$langcode]) && $language->enabled) {
                    
                      $path = "/$langcode/" .  drupal_get_path_alias('node/' . $translations[$langcode]->nid, $langcode);
                    
                    ?><option value="<?php print $path ?>"<?php if ($node->language === $langcode) print ' selected="selected"'?>><?php print strtoupper($langcode) ?></option>
                  <?php }
                }
              } else { 
									global $language; $current_langcode=$language->language;
									$languages = language_list();
									foreach ($languages as $langcode => $language) {
										if($language->enabled){
											$path = "/$langcode/" .  $_GET['q'];
							?>
								<option value="<?php print $path ?>"<?php if ($current_langcode === $langcode) print ' selected="selected"'?>><?php print strtoupper($langcode) ?></option>
              <?php }}} ?>
            </select>
          </div>
        </form>
	</div>
</div>
Mohammed J. Razem’s picture

This ends the pain for D6
http://drupal.org/project/lang_dropdown


Mohammed J. Razem
http://www.vardot.com
Vardot

afagioli’s picture

looks like lang_dropdown only switches interface, not content.... digging this