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&orderby=KEY&order=DIR&link_empty_to=str')
* N=0/1
* KEY=id/code/name (name -> translated_name), (defaut: id)
* DIR=asc/desc (defaut: asc)
* link_empty_to = str (default: empty, works in conjunction with skip_missing=0 and allows using custom links for the languages that do not have translations for the current element. {$lang} can be used as placeholder for the language code)
Notes:
- The skip_missing parameter tells the function how to treat languages with no translations.
- The combination of orderby and order allows creating the drop-down language switcher or language switchers where languages always display in the same position.
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 ( [id] => 1 [active] => 1 [native_name] => English [missing] => 0 [translated_name] => English [language_code] => en [country_flag_url] => http://yourdomain/wpmlpath/res/flags/en.png [url] => http://yourdomain/about ) [1] => Array ( [id] => 4 [active] => 0 [native_name] => Français [missing] => 0 [translated_name] => French [language_code] => fr [country_flag_url] => http://yourdomain/wpmlpath/res/flags/fr.png [url] => http://yourdomain/fr/a-propos ) [2] => Array ( [id] => 27 [active] => 0 [native_name] => Italiano [missing] => 0 [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.
- id: Internal reference id
- 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
- missing: 1 if the translation for that element is missing, 0 if it it exists.
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:
- Get the list of languages from WPML – $languages = icl_get_languages(‘skip_missing=1′);
- Check that there’s more than one language for this post – if(1 < count($languages))
- Create the output, skipping the currently displayed language – if(!$l['active'])
Notes:
- 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: ‘);
- 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
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&orderby=code');
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:
- If there’s any translation language, creates a DIV and starts an unordered list: if(!empty($languages)){ echo ‘<div id=”footer_language_list”><ul>’;
- Goes through each of the languages and adds it as a list item.
- If it’s not the active language, also link to that page in that language: if(!$l['active']) echo ‘<a href=”‘.$l['url'].’”>’;
- Adds the language flag: <img src=”‘.$l['country_flag_url'].’” alt=”‘.$l['language_code'].’” width=”18″ height=”12″ />
- 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
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.
Language selector with flags only
Simple function for displaying flags linked to the translations of the current page.
function language_selector_flags(){
$languages = icl_get_languages('skip_missing=0&orderby=code');
if(!empty($languages)){
foreach($languages as $l){
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>';
}
}
}
The output of this function needs to be styled separately. For instance placing the function into a div block and defining custom styles for the img tags.
<div id="flags_language_selector"><?php language_selector_flags(); ?></div >
The CSS:
#flags_language_selector img{
margin:1px;
border:1px solid #333;
}
Flags language selector
Replacing the country flags and changing language names
WPML includes a GUI for editing language information. Go to WPML->Languages and click on Edit languages. You will be able to change the language names, edit their locale values and choose different flags.
'skip_missing=0&orderby=name'
Fatal error: Call to undefined function language_selector_flags() in D:\wamp\www\milestone\wp-content\themes\milestones\header.php on line 80
y this happend i have just include the required file in the function.php and in the header i call the function///………………………..
yes i have solved it by myself
Hi there!
I would like to put the language switcher in the header of my site, instead of the footer where it is hard to find. How can I do this?
Thanks!
You can use the filter, described in this page above, to add a custom language switcher anywhere in your theme.
I’ve added a the Language Selector as a horizontal list to the footer of our site. The only question I have now is if it is possible to hide the hidden languages as set in the admin panel. I’ve hidden all languages except English (main), and still the other languages which are not ready yet show up.
Website: http://www.spiderlogisticseurope.com
It’s all possible when you create a custom language switcher. Please use our forum, so that you can paste full PHP and we’ll help you with it.
Very great post. I simply stumbled upon your weblog and wanted to mention that I have truly loved surfing around your weblog posts. In any case I will be subscribing for your rss feed and I’m hoping you write once more very soon!
Hello Amir, your plugin works well but the only problem is I always get natve language in lowercase characters and it looks strange (polski (polish), English). Can you please explain where the pluggin takes langague names from? Thank you and Happy New Year!
pterodaktyl
You can edit the language names. Go to WPML->Languages and click on the Edit languages link. This is where the language names come from.
Great! Thank you very much!
If you don’t need flags and just want to just display the text versions of your languages in a list format in the header, use this code:
in functions.php
function languages_list_footer(){
$languages = icl_get_languages('skip_missing=0&orderby=code');
if(!empty($languages)){
echo '';
foreach($languages as $l){
echo '';
if($l['active']) echo ''.$l['translated_name'].'';
if(!$l['active']) echo ''.$l['translated_name'].'';
echo '';
}
echo '';
}
}
and in header.php:
No – display only flags, without text and background
what in header.php?
It’s a file that is usually part of your theme.
I think what Sascha means is that the the code to include in header.php is not visible above.
In any case it should be
Sorry, but comments cannot contain HTML or PHP. If you want to post technical information, the best place for that is in our forum.
What to do if i want only flag without background?
Please open a thread about this in our forum and our support folks will help you get it right.
Hi ,
I want to display one language link at a time . For eg:- my site is in french and english and i want to display french translation link when site is in english and english translation link when site is in french .
Please provide me a way to do that .
I don’t want dropdown or both the links at the same time
Please help!
Thanks alot
I have problems with the switch on my installation. Works on every page but on pages show archiv categories it makes the php crash:
Catchable fatal error: Object of class stdClass could not be converted to string in /kunden/249193_01099/webseiten/stage/wp-content/plugins/sitepress-multilingual-cms/sitepress.class.php on line 4626
I need this fixed as soon as possible…Anybody figured out how to solve this bug? Some hint from the support maybe?
Can you please open a thread about this in our support forum?
So did I: thread can be found here: http://wpml.org/forums/topic/language-switch-causes-php-error-on-archiv-category-pages/
I am building a multi-lingual site in English and Arabic. I have simple press forum installed along with WPML. I have translated Simple Press using .mo files. Now all I need is a way to switch the language attributes so they are set to dir=rtl and lang=ar when I choose Arabic. Simple Press outputs the forum on a single page. Creating a translation using WPML is not the way to go.
I think my best bet is using the icl_get_languages function. How do I use it so that I can select Arabic, which changes the lang attributes correctly but the browser stays on the forum main page http://www.nrcuae.com/forum/ and does not go to the main language page http://www.nrcuae.com/ar/
Please advise!
Kind Regards,
Nitin
I think that the best place to get this sort of help is in our forum. Please describe what you’re doing there and what you’re seeing. Links would be nice.
hi there!
Theres any possibility to provide a language selector without flags, only using text… but the code of each idiom?
i.e.: UK | FR | PT
Thanks a lot!
hello, since i am not much familiar with the php codes, i would like to know if this is possible:
i have two languages x and y.
i use the “Display the language switcher in the WP Menu ” option and that renders links perfectly. on the same wp menu, using the switcher as a dropdown is not what i want to see. i would like to see only the Y link on the menu, when i am on X language and, X link when on the Y language. not as a dropdown but only one item in the wp main menu.. is that possible? if so;
how should i alter the code? and on which files? thank you..
This is possible, but would require some extra PHP on your side. WPML’s GUI doesn’t support this more right now. We will consider it for a future version, but for now, you’ll have to build something like this in PHP.
hi amir
Why wpml doesn’t allow me to put flage together horizontally on the top of the page? I tick the bo but its only for side bar. No option to do it for the main/top page.
Thanks