Home » Documentation » Getting started guide » Language Setup » Custom language switcher

Custom language switcher

WPML comes with its own language switcher, implemented as a drop down list of languages. It’s pretty flexible, but not always enough.

You can build your own custom language switchers and insert them in the theme. I’ll show how to add a list of available languages to posts and a list of languages for the footer.

Getting the list of (other) languages

Use icl_get_languages() to get a list of translations for any page. Usage:

icl_get_languages('skip_missing=N')

* N=0/1

The skip_missing parameter tells the function how to treat languages with no translations. We’ll get to it in a minute.

The function returns an array with entries per language. For example, for a WordPress site running English, French and Italian, it will return this:

Array
(
 [0] => Array
  (
   [active] => 1
   [native_name] => English
   [translated_name] => English
   [language_code] => en
   [country_flag_url] => http://yourdomain/wpmlpath/res/flags/en.png
   [url] => http://yourdomain/about
  )

 [1] => Array
  (
   [active] => 0
   [native_name] => Français
   [translated_name] => French
   [language_code] => fr
   [country_flag_url] => http://yourdomain/wpmlpath/res/flags/fr.png
   [url] => http://yourdomain/fr/a-propos
  )

 [2] => Array
  (
   [active] => 0
   [native_name] => Italiano
   [translated_name] => Italian
   [language_code] => it
   [country_flag_url] => http://yourdomain/wpmlpath/res/flags/it.png
   [url] => http://yourdomain/it/circa
  )
)

Each language has its own array of parameters, which your theme function can use to build any language selector.

  • active: This is the currently active language (exactly one language is active)
  • native_name: The native name of the language (never translated)
  • translated_name: The name of the language translated to the currently active language
  • country_flag_url: The URL to a PNG image with the country flag
  • url: The link to the translation in that language

Handling missing translations

Some pages may not be translated to all languages. You can tell icl_get_languages what to return for languages with no translations.

If ’skip_missing=1′, these languages will not appear in the output. If ’skip_missing=0′, all the languages will appear and languages with missing translations will link back to the home page in that language.

How to use in your theme functions

You can build your own language switchers in whatever way you choose. Here, we’ll show two popular uses.

The example PHP functions we’re showing here should go in to your functions.php file (in the theme folder) – not added to the plugin.

This post is also available in…

Supposing you want to add a line, at the bottom (or top) of each post, saying in which other languages it’s available. This function should only return existing translated posts and if no translation is available, it shouldn’t output anything.

function icl_post_languages(){
  $languages = icl_get_languages('skip_missing=1');
  if(1 < count($languages)){
    echo __('This post is also available in: ');
    foreach($languages as $l){
      if(!$l['active']) $langs[] = '<a href="'.$l['url'].'">'.$l['translated_name'].'</a>';
    }
    echo join(', ', $langs);
  }
}

What this function does is:

  1. Get the list of languages from WPML – $languages = icl_get_languages(’skip_missing=1′);
  2. Check that there’s more than one language for this post – if(1 < count($languages))
  3. Create the output, skipping the currently displayed language – if(!$l['active'])

Notes:

  1. The message goes through gettext. This is very important, so that this message, which you’ll append to posts in different languages will appear in the correct language:  __(‘This post is also available in: ‘);
  2. The language names used are the translated language names. This would guarantee that the entire sentence is written in the correct language: $l['translated_name']

The result is this:

Message about post available in other languages

Message about post available in other languages

To include this message in posts, add a call to icl_post_languages() from single.php.

List of language names and flags for the footer

Even if you have a language selector at the top of the page, it’s a good idea to add a list of language names and flags to the footer. Many people immediately scroll down the the bottom of the page, to get a better idea of what’s ahead, so placing a prominent language switcher there is likely to help your foreign visitors.

function languages_list_footer(){
    $languages = icl_get_languages('skip_missing=0');
    if(!empty($languages)){
        echo '<div id="footer_language_list"><ul>';
        foreach($languages as $l){
            echo '<li>';
            if($l['country_flag_url']){
                if(!$l['active']) echo '<a href="'.$l['url'].'">';
                echo '<img src="'.$l['country_flag_url'].'" height="12" alt="'.$l['language_code'].'" width="18" />';
                if(!$l['active']) echo '</a>';
            }
            if(!$l['active']) echo '<a href="'.$l['url'].'">';
            echo icl_disp_language($l['native_name'], $l['translated_name']);
            if(!$l['active']) echo '</a>';
            echo '</li>';
        }
        echo '</ul></div>';
    }
}

This function does the following:

  1. If there’s any translation language, creates a DIV and starts an unordered list: if(!empty($languages)){ echo ‘<div id=”footer_language_list”><ul>’;
  2. Goes through each of the languages and adds it as a list item.
  3. If it’s not the active language, also link to that page in that language: if(!$l['active']) echo ‘<a href=”‘.$l['url'].’”>’;
  4. Adds the language flag: <img src=”‘.$l['country_flag_url'].’” alt=”‘.$l['language_code'].’” width=”18″ height=”12″ />
  5. Add both native and translated language names, if they’re different: echo icl_disp_language($l['native_name'], $l['translated_name']);

The icl_disp_language() function is created by WPML. What it does is check if the two arguments (native_language_name, translated_language_name) are different. If so, it returns them both, otherwise, it returns them just once.

We should also add some CSS to style this languages list. This CSS will center the languages list in your footer and format it a bit:

#footer_language_list{
  margin-bottom: 25px;
  text-align: center;
}

#footer_language_list ul{
  list-style: none;
  margin:0;
  padding:0;
}

#footer_language_list ul li img{
  margin-right:5px;
}

#footer_language_list ul li{
  display:inline;
  margin:0 5px 0 5px;
  padding:0;
}

#footer_language_list ul li a, #footer_language_list ul li a:visited{
  color: #fff;
  text-decoration:underline;
}

#footer_language_list ul li a:hover, #footer_language_list ul li a:active{
  color: #fff;
}

Here is the language switcher:

Language footer

Language footer

To add it to your theme, add the call to languages_list_footer to the footer.php file.

* Note: you can easily change turn this horizontal language switcher into a vertical language switcher. Just remove the display: inline statement from the CSS.

Replacing the country flags

To replace the country flags with your own, you will need to edit WPML’s flags table in the database. You can find instructions for that in WPML’s table structure.

35 Responses to “Custom language switcher”

  1. Paul says:

    Grrrrrrr!
    Still not working.
    I’ve put my problem at the forums:
    http://forum.wpml.org/topic.php?id=112&replies=1#post-414

    Srry for making a mess over here :(

  2. Nishad Kaippally says:

    Hi
    I am using the WPML plugin to display wordpress content in four languages. So far everything seems okay. I am able to show Posts with multiple languages using the icl_post_languages() function. Is there also a function to Show the Pages in a similar way.

    Thanks in advance

  3. Sean says:

    I can’t follow this documentation because I don’t already understand PHP (e.g. “add the call to languages_list_footer” (add the what??)). It would be helpful to include the exact code that can be copied and pasted and indicate which parts should be changed if necessary.

    • amir says:

      I strongly suggest that you let a PHP programmer do this for you. It’s very easy to do things wrong and then get all sorts of ‘weird’ problems.

      • Sean says:

        Nah, it’s okay. I still don’t fully understand it, but I’ve got everything functioning now. I just think it would be more useful to say “add to the footer.php file” or “add the call to languages_list_footer () to the footer.php file.”

        I figure it’s fustrating for you to deal with programming newbs when you can write this stuff in your sleep but I’m doing this for my student association and I’m the most tech-savvy person available :S In any case, thanks for the great plug-in. Our website rocks thanks to your work! :D

        • Sean says:

          The php was stripped from my post – it should have read:
          Nah, it’s okay. I still don’t fully understand it, but I’ve got everything functioning now. I just think it would be more useful to say “add to the footer.php file” or “add the call to languages_list_footer () to the footer.php file.”

  4. isabelle says:

    Working perfectly for me!
    Thanks,

  5. anabella says:

    Hi,

    when i use my theme has fatal error and says :

    Fatal error: Call to undefined function wpml_languages_list()

    i have 3 languages enabled, i copied wpml-integration.php at my theme folder.

    any idea?

    thanks

  6. anabella says:

    my mistake was that i did not include wpml-integration.php at functions.php
    now everything is working

    thanks

  7. meow says:

    To include this message in posts, add a call to icl_post_languages() from single.php.

    Japanese got mistakes about this …please check.thanks.

  8. Elena says:

    Hi
    My theme (sort of very simple vcard theme) doesn’t have a functions.php…should I create it? If so, what’s the code I should grab & paste in that file?

    (+ putting the wpml-integration.php at that theme’s folder, I assume)

    Thanks a lot.

    • amir says:

      Yes, you can create a functions.php file and put in in the theme folder. Just copy wpml-integration.php into the theme folder and rename it to functions.php.

  9. Joseph says:

    Hi, I was wondering if it is possible to change the flags to custom button images? What I did was replaced the flags png with my custom buttons, it works but not idea, as I lost my flaga in the admin area.

    This is a great multilingual plugin! Thanks for your support!

  10. Barry says:

    Thank you Amir for your great plugin !

    Just one thing is that the drop down menu doesn’t talk that much to readers.
    It would be more obvious to have the possibility to display 3 or 4 flags side by side.
    Instead of the drop down menu on top, just need to have the flags one after the other horizontally or vertically.

    Could you pls think about that option for the next version?
    I know I could play with the code, etc…but I don’t know PHP and I guess a good majority of WP users are not developers too and chose your plugin to simplify their life :-)

    Thanks again and keep on the good work !

    • amir says:

      We’ll see about that. For now, we’re planning something a bit different. Instead of offering an endless number of customizations via the GUI, we’re going to supply nice multilingual packages for themes.

  11. Thank you for the best plugin and excellent plugin page.

    Is there a way to reorder the languages in the dropdown menu selector?

    Thanks again for this useful plugin. Kudos!

    • amir says:

      We’ve been asked to provide this, but don’t currently have a ‘built in’ solution for reordering the languages.

      If you build your own custom language switcher, you can easily sort the languages array before you create the language switcher HTML.

  12. noltha says:

    Hi there,

    I’m trying to recreate the div “footer_language_list” below.

    What is the code for that? I tried with this tutorial but I couldn’t make it work.

    Thank you

    • amir says:

      I suggest that you open a thread about this in the forum. Include the code you’ve tried and what you want to get. I’m sure that folks will be able to help you there.

  13. Mara Celani says:

    Hi! I would very much like to add the foreign language switcher in the header’s menu bar. My theme is Freshy2, with a Customize plug-in, wich is supposed to do everything, but infact I can’t find the option. Can you help me, (if it is worth wasting time on that)?
    Thank you so much.
    Mara

  14. [...] want to change this as explained in this forum postreimplement automatic language detectionset up a custom language switcher that looks more like “Français | English” somewhere at the top right of the [...]

  15. npc says:

    How manual create sort list, en | ru | de , and when active “de” list be the same en|ru|de, not de|en|ru

  16. P says:

    What exactly CSS should I edit to remove display: inline?

  17. [...] I didn’t want to use the default Language Selector and made the list of languages as you can see on this site. A useful reference is here. [...]

  18. [...] People familiar with wpml styling may recognize the css and php code I’ve used here. I slightly adjusted some php found here on wpml.org, custom language switcher. [...]

  19. paul says:

    List of language names and flags for the footer..

    looks incomplete to me.. isn’t this supposed to be surrounded by <?php etc

    Where is this code placed?

    • amir says:

      Of course, PHP statements need to be wrapped in that. You need to place it in your theme according to where it should display in the site.

  20. Fransnico says:

    I’m using the Language List in the footer, and the code works great.. but there’s one slight issue that bothering me.. I’m trying to remove the native name from the list, so it only displaying the translated name but with no bracket.
    for example :
    English | Francais (French) | Italiano (Italian)
    I would like to turn it into something like this..
    English | French | Italian

    Would you please give me a hint?

  21. K says:

    FYI: If the url of the link doesn’t point to the translated version of the same page (goes to the main page no matter what) make sure you included wp_head(); in your header.

Leave a Reply

Please leave here comments about this page only.
For technical support and feature suggestions, head to our forum. We are waiting there!

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">