There is a snippet that can be used for language switching instead of the standard language switching block (see an example of page template code appended) - the point is (1) being more compact (e.g. you can insert the switcher into the page header next to the site name, slogan, or search box), and (2) hiding the current language (see http://drupal.org/node/226959).
It works fine for Drupal 5 + i18n - however, it does not work for Drupal 6 + i18n because of i18n v.6 functions being different. Does anybody know how to change this snippet to make it work for D6+i18n?
Thank you!

<div id="langswitch" style="float: right">
        -&gt; |<?php foreach (excl_translation_get_links($_GET['q']) as $link): ?>
<?php print $link?> |
<?php endforeach; ?>
<?php
// modified function
function excl_translation_get_links($path = '', $query = NULL, $names = NULL) {
  $current = i18n_get_lang();
  $names = $names ? $names : i18n_languages('native');
  foreach (array_keys(i18n_supported_languages()) as $lang){
  if ($lang != $current) {
    $url = translation_url($path, $lang);
    $links[]= theme('i18n_link', $names[$lang], i18n_path($url, $lang) , $lang, $query);
  }}
  return $links;
}
?>
</div><!-- /end langswitch -->

Comments

Anonymous’s picture

Would be interested in that, too. I tried to dig through the module, but it seems the according stuff has changed completely so I failed :-(

Anonymous’s picture

Ok, I got it working. The following is a mix of code snippets from locale.module and i18n languageicons.module. Someone with better php and i18n knowledge should review that to see if I'm doing nasty things here.

There is one problem with the drupal_alter call, see comments in the code, but I could work around this.

I hope this helps!



    // We don't need to check if we have more than one language because with removing 
   // the current, we end up with an empty list if only one language, and thus, show nothing
    $current = i18n_get_lang();
    $languages = language_list('enabled');

    $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'),
        );
    
       // use the i18n function to set language name and/or flag according to the i18n settings:
       languageicons_link_add($links[$language->language]);
        
       // Or do your own stuff, e.g. set the flags and no lang names,
       // no matter what the i18n icon settings say.
       //if ($icon = theme('languageicons_icon', $language, NULL)) {
       //   $links[$language->language]['title'] = theme('languageicons_place', $link['title'], $icon);
       //   $links[$language->language]['html'] = TRUE;           
       //}
      }
    }    

   // Instead of calling languageicons_link_add above, we should be able to call
   //drupal_alter('translation_link', $links, $_GET['q']);
   // to add the flags or remove the lang names, according to the icon settings.
   // Didn't work for me, I got *all* languages shown again and even two flags for the 
   // current one. Somehow interfers with the automatic adding of the language
   // flags in nodes bodies, because it works on a language neutral page

   // now format as you like. E.g. 
   echo theme('links', $links, array());


GN’s picture

Thanks a lot Frank - it seems to work!

(If flag icons are disabled, the
languageicons_link_add($links[$language->language]);
line should be removed as the function is not defined).

Anonymous’s picture

Ah, ok, that should be possible to check with

if (function_exists('languageicons_link_add'))...

GN’s picture

Hmmmm...
I'm afraid it actually does not do what the regular i18n language switcher block does.
The i18n language switching block switches the site from /lang1/node/n1 to /lang2/node/n2, where node/n2 is the translation of node/n1 from lang1 to lang2 - while this snippet just switches it from /lang1/node/n1 to /lang2/node/n1.
It's OK for the front page, but it does not work well for content nodes.

Anonymous’s picture

You are right, I was missing a piece. Here's a new version that should run fine. I just goes through the hole link_alter chain step by step.

 
  // this is copy&paste from locale_block in locale.module
  $languages = language_list('enabled');
  $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']);

  // This one adds extended languages, i.e. those that are not enabled.
  // Disable if you want only flags for enabled languages.
  i18n_translation_link_alter($links, $_GET['q']);
  
  // now add or replace text links by flags, according to your i18n settings.
  if (function_exists('languageicons_translation_link_alter'))
    languageicons_translation_link_alter($links, $_GET['q']);  

  // Or do your own stuff, e.g. set the flags and no lang names,
  // no matter what the i18n icon settings say.
  //if ($icon = theme('languageicons_icon', $language, NULL)) {
  //   $links[$language->language]['title'] = theme('languageicons_place', $link['title'], $icon);
  //   $links[$language->language]['html'] = TRUE;           
  //}

  // remove the current language again. We cannot do that
  // earlier because i18n_translation_link_alter would add it
  // again, thinking it was an extendeg language because it
  // was not yet contained in $links. If you don't use 
  // i18n_translation_link_alter, you can also make a case distinction
  // in the foreach loop
  $current = i18n_get_lang();
  unset($links[$current]);

  // format as you like, e.g.
  echo theme('links', $links, array());
Anonymous’s picture

For those who are interested: At http://drupal.org/node/250124 you can find a little extension that tries to solve the problem with klicking the language switcher on a non-language-neutral page that has no translation.

BenK2’s picture

Frank,

I have seen your many posts on Internationaisation. I am a Newbie struggling with a presentation problem - how to turn the Language Switcher Block into a drop down list which, preferably, can be added to a menu or , remain as a block. I'm fairly sure your code snippets here provide the answer ! .. but although although I've figured out the basis of theme CSS in v6 and how to make changes, I cannot see what to do with / or where to put the code snippet ! I have been searching and searching .... could I trouble you to provide a quick explanation please...

Thanks

(by way of background I am running the latest release, have chosen 'path prefix with language fallback' for negotiation, will not be using language icons, expect to have 3 languages to begin and more later ..)

15/05
Just to add my thanks, to GN as well, for the posts below in response to my query.

Anonymous’s picture

Just put it in a page or block body. On my site I've created a new block with input format "php". In the body of the block just insert the snippet and save the block. Then make sure that on the block configuration page you put the block somewhere (in the top or the right column) and there you go. No need to work with css or theming etc.

GN’s picture

Thanks a lot Frank, this version seems to work fine indeed!

GN’s picture

BenK2,

Usually I try to make the language switcher as compact as possible. Instead of creating a separate block for it in a sidebar area, I'm placing it at the same level as site name and slogan (if any) - e.g. right-justified under the search box - by inserting it in the page.tpl.php after the search box:
<div id="langswitch" style="float: right">(Frank's snippet code goes here)</div>
Then, I add to the theme's style.css file a "langswitch" section and format it as I like - usually I start from copying there the format settings from the CSS section describing page elements looking more or less like I want the language switcher to look.
So, if you have in your theme a css-based drop-down menu, you can copy its formatting to the "langswitch" css section.
(Also, you can see some examples of css for drop-down menus e.g. on http://www.cssplay.co.uk/menus/).

Anonymous’s picture

Status: Active » Fixed
Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

userid’s picture

Just the ticket, thanks very much. May I point out that the php filter module must be enabled so as to permit the php input format for blocks.

Hm, for some reason it still shows the language name after language is switched?

fletchgqc’s picture

jose reyero’s picture

Added to the handbook, http://drupal.org/node/313813

RussianManFromMoscow’s picture

Priority: Normal » Critical
Status: Closed (fixed) » Active

How do I get in the choice of language through block "switch language" URL type "http://example.com/ru/node/" looks like "http://example.com/ru/"?

aaronwang’s picture

thanks!you did it

jose reyero’s picture

Status: Active » Closed (fixed)

That's a different question.

ThePrince’s picture

The only issue I have with this is that when on the front page, it links to the url of the page I'm using for the front.

For example, I created a page called "home" and that's the one I put into the /admin/settings/site-information "Default front page".

The problem is that when I'm at the roo of my site i.e. example.com or example.com/fr the switcher links to example.com/home and example.com/fr/home and not just example.com and example.com/fr as it is when I click on the logo for example.

Can anyone help?

Thanks!

ThePrince’s picture

Resolved my problem with global redirect module.

momper’s picture

the same situation like theprince: is it possible to solve this without "global redirect"?

thanks and greetings momper

prosiktuno’s picture

I have a same task that BenK2.
I need to make language switcher as drop-down menu.
I totally new in site construction. I'm spent more one week to learn HTML, CSS, and now I start to learn PHP. But I still don't know how to get it.
I tried Frank code with CSS modification as told GN. No good success.
I tried code from here - http://drupal.org/node/261059#comment-1032902 and still don't have what I want.

Could anybody advice me how to get language switcher as drop-down menu on D6?

Thanks.

rout’s picture

Status: Closed (fixed) » Active

I would also find it very useful if this were made into a drop-down menu.

Can anyone advise how this could be made into a dropdown menu?

mafioso’s picture

based on http://drupal.org/node/261059#comment-1032902 snippet, i made some changes, and put following code into page.tpl.php:

        <div id="language-select-form">
        <form  action="" method="post">
        <select id="language-select-list" onchange="document.location.href=this.options[this.selectedIndex].value;">
        <?php
             $languages = language_list('enabled');
             $current = i18n_get_lang();
             $path = drupal_get_normal_path($_GET['q']);
             $paths = array();
             $paths = translation_path_get_translations($path);
             foreach ($languages[1] as $language) {
                 if (preg_match('/^node/',drupal_get_normal_path($_GET['q']))) {
                    $path = drupal_get_path_alias($paths[$language->language], $language->language);
                  }
              $path = "/" . $language->language . "/" . $path;
        ?>
        <option value="<?php print $path ?>"<?php if ($language->language === $current) print ' selected="selected"'?>><?php print $language->native ?></option>
        <?php } ?>
        </select>
        </form>
        </div>

rgds,

Bilmar’s picture

subscribing

mafioso’s picture

So sorry folks, my snippets from #25 didn't handle non-node pages (e.g. views page) well.
With my limited php knowledge, i modified the code as below:

        <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
                $languages = language_list('enabled');                        //get enabled languages
                $current = i18n_get_lang();                                   //get current language
                $path1 = drupal_get_normal_path($_GET['q']);                  //get normal path from q
                $paths = array();
                $path1 = preg_replace('/^' . $current . '/', "", $path1);      //delete language suffix if any, e.g.: /en/xxx/yyy -> xxx/yyy 
                $paths = translation_path_get_translations($path1);            //get translation paths
                foreach ($languages[1] as $language) {
                        if (preg_match('/^node/', $path1)) {
                          $path = drupal_get_path_alias($paths[$language->language], $language->language); //get path alias for transl. path
                        } else {
                          $path = $path1;                                      //for non-node pages
                        }
                $path = "/" . $language->language . "/" . $path;
        ?>
        <option value="<?php print $path ?>"<?php if ($language->language === $current) print ' selected="selected"'?>><?php print $language->native ?></option>
        <?php } ?>
        </select>
        </div>
        </form>
        </div>

rgds,

Josie_h’s picture

I'll start by apologising, but could someone please help.

I have chased this issue from thread to thread for many hours. I have also looked in all my CSS files to try to figure it myself, but I'm totally lost and due to my own admitted inabilities I'm completely stumped on something I assume is simple. Any help VERY much appreciated.

I have created a block and the snippet is working for me, now all I need to do is change the flag icons from vertical to horizontal alignment and get rid of the bullets. I think that I am supposed to put something (is it a 'class'?) between the middle brackets after the 'array' in the last line... 'echo theme('links', $links, array(?));'

If it isn't too much trouble or a silly question, could someone please explain (simply) where/what I need to change or add to my existing CSS file(s), or do I need to create a new CSS file and in either case what is the code I need to add/modify/create and then what I would actually put between the array brackets?

If relevant, I'm using the latest D6 with the Simply Modern theme and I'm putting the flag icons in either the header or a sidebar.

Many thanks for any help.

Josie_h’s picture

Very many thanks and credit to forum member Bruce Pearson who resolved this problem for me.

rburgundy’s picture

@Josie_h - can you please share what you had to do to resolve the problem? Many thanks

brucepearson’s picture

If you want the flag icons to be shown horizontally then change:

echo theme('links', $links, array());

to:

echo theme('links', $links, array('class' => 'links inline'));

jaochoo’s picture

How can I output standard links like "Your Settings" or "Logout" correctly in my theme? E.g.:
- When on English language: Output: "Your Settings", Links to: /user/id/edit
- When on German language: Output: "Deine Einstellungen", Links to: /de/user/id/edit

My current code is as follows, but a) it does not translate "Your Settings" into the correct language (same for "Logout" and other standard links) and b) it always redirects to /user/id/edit, instead of /language-code/user/id/edit:

  // this is copy&paste from locale_block in locale.module
  $languages = language_list('enabled');
  $current = i18n_get_lang();
  $links = array();
...
  array_push($links, array(
        'href'       => 'user/'.$user->uid.'/edit',
		'title'      => t('Your Settings'),
        'language'   => $current,
      ), array(
	    'href'       => 'logout',
		'title'      => t('Logout'),
        'language'   => $current,
      ));
adrianmak’s picture

where should I put the code posted on #6 ?
Directly on page.tpl.php ? or paste in a new block and assign to a region. ?

jose reyero’s picture

Project: Internationalization » Internationalization UI
Priority: Critical » Normal

An alternate language switcher block would be welcomed for this module.

anton99’s picture

Title: Compact language switcher - how to modify D5 snippet for D6 » Do not show a link to the current language D6

Hello! I bought theme and can not solve the problem simply CSS rule display: none for a.active, although Garland theme that works. Been looking on the internet solution to this problem and as a result I found this snippet (# 6). Good for me, that does not show link (box) for the current language, but not when switching to the current language, it would be better to show a link to the language before, and, accordingly, when it is clicked a link was inversely proportional to the current language. I'm not good at PHP, but a little versed in it and looking at the code seen that somewhere near the truth, but could not find her. If anyone knows how to change this snippet (# 6) I would be very grateful if he would rather brash to share ideas. Always waiting for an answer, because It is very important to get an answer as soon as possible. Thank you very much.