Originally written
一月 21, 2013
Updated
十二月 30, 2019

开发人员可以使用来自WPML的icl_get_languages API调用来创建他们自己的自定义语言切换器。 在本教程中,您会找到icl_get_languages的完整详情,以及用它构建自定义语言切换器的示例。

快速概览:

  1. 调用icl_get_languages获取当前显示页面的翻译列表
  2. 编写自己的PHP函数来呈现语言切换器
  3. 将您的语言切换器置于主题中

获取(其他)语言的列表

使用icl_get_languages()可以获得任何页面的翻译列表。 如果您在使用WPML 3.2或更高版本,则应考虑使用类似的钩子过滤器wpml_active_languages

用法:

icl_get_languages('skip_missing=N&orderby=KEY&order=DIR&link_empty_to=str')

* N=0/1
* KEY=id/code/name/custom (name -> translated_name), (default: id)
* DIR=asc/desc (default: asc)
* link_empty_to = str (默认:空,与 skip_missing=0 一起使用,允许对当前元素没有翻译的语言使用自定义链接。{%lang} 可以用作语言代码的占位符)

注意:

  • skip_missing参数可表示该函数如何处理没有翻译的语言。
  • orderbyorder结合允许创建下拉式语言切换器,语言总是显示在相同的位置。
  • 自定义顺序可以定义在WPML»语言»语言切换选项下的WordPress管理中

该函数返回各语言条目的数组。 例如,对于以英语、法语和意大利语运行的 WordPress 网站,它将返回此结果:

Array
(
 [en] =>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
 )

 [fr] => 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
 )

 [it] => 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
 )
)

每种语言都有其自己的参数数组,您的主题函数可用它来构建任何语言选择器。

  • id: 内部参考编号
  • active: 这是当前使用的语言(准确地说,一种语言在使用)
  • native_name: 语言的原始名称(从不翻译出来)
  • translated_name: 以当前使用语言显示的语言名称
  • country_flag_url: PNG 格式的国旗图像的 URL 链接
  • url: 转至该语言翻译的链接
  • missing:如果该元素缺少翻译,则为 1,如果存在翻译,则为 0。

处理缺失的翻译

一些页面可能没有被翻译为所有语言。 您可以告知 icl_get_languages 对于没有翻译的语言应当返回什么。

如果 『skip_missing=1』,则这些语言将不会在结果中显示。 如果 『skip_missing=0』,则将显示所有语言,其中缺失翻译的语言将链接回到该语言的首页。

在主题函数中的使用方法

您可以任意方式构建自己的语言切换器。 在这里,我们将演示两个流行的用法。

我们在此演示的示例 PHP 函数将进入您的 functions.php 文件(在主题文件夹中),而不会添加到插件中。

此文章还提供以下语言版本…

假设您想在每个文章的底部(或顶部)增加一行,显示此文章还提供其他什么语言版本。 以下函数应当仅返回当前已翻译的文章,如果没有可用的翻译,则不应输出任何结果。

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);
 }
}

此函数的作用是:

  1. 从 WPML 获得语言列表 – $languages = icl_get_languages(『skip_missing=1』);
  2. 检查此文章是否有多个语言版本 – if(1 < count($languages))
  3. 创建输出结果,跳过当前显示的语言 – if(!$l[『active』])

注意:

  1. 此消息可顺利使用 gettext。 这点非常重要,那样您以不同语言附加到文章的这条消息将以正确的语言显示:__(『此文章还提供以下语言版本: 『);
  2. 使用的语言名称是翻译后的语言名称。 这将保证整个句子是以正确的语言显示的:$l[『translated_name』]

结果如下:

关于文章有其他语言版本的消息
关于文章有其他语言版本的消息

要在文章中包含此消息,从single.php 添加一个icl_post_languages()调用。

在页脚添加一个语言名称和国旗列表

虽然您在页面顶部有语言选择器,但在页脚添加一个语言名称和国旗列表也是个不错的主意。 许多人立即滚动到页面底部以更好地了解后面的内容,因此放置一个显著的语言切换器有可能为您的外国访客提供帮助。

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>';
 }
}

此函数有以下作用:

  1. 如果有任何翻译语言,则创建一个 DIV 并开始一个没有排序的列表:if(!empty($languages)){ echo 『<div id=」footer_language_list」><ul>』;
  2. 搜索每个语言并将其添加为列表项目。
  3. 如果不是当前使用的语言,则还以该语言链接至该页面:if(!$l[『active』]) echo 『<a href=」『.$l[『url』].'」>』;
  4. 添加语言国旗:<img src=」『.$l[『country_flag_url』].'」 alt=」『.$l[『language_code』].'」 width=」18″ height=」12″ />
  5. 添加原始语言名称和翻译后的语言名称(如果它们不同的话):echo icl_disp_language($l[『native_name』], $l[『translated_name』]);

icl_disp_language() 函数由 WPML 创建。 其作用是检查 (native_language_name, translated_language_name) 这两个参数是否不同。 如果不同,则返回两者,否则只返回一个。

我们还应当添加一些 CSS 以使这个语言列表风格化。 以下 CSS 将使语言列表在页面底部居中显示并进行一些格式调整:

#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;
}

以下就是语言切换器:

页脚语言
页脚语言

要将其添加至您的主题,请将 languages_list_footer 调用添加至 footer.php 文件。

* 注意:您可以方便地将这个水平的语言切换器转变为垂直的语言切换器。 只需从 CSS 中删除 display: inline 语句。

仅带国旗的语言选择器

以下简单函数用于显示链接到当前页面翻译的国旗。

Language selector with flags only
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 class="wpml-ls-item" href="'.$l['url'].'">';
            echo '<img src="'.$l['country_flag_url'].'" height="12" alt="'.$l['language_code'].'" width="18" />';
            if(!$l['active']) echo '</a>';
        }
    }
}

这个函数的输出需要另外加以样式化。 例如,将此函数放到 div 块中并为 img 标签定义自定义样式。

<div id="flags_language_selector"><?php language_selector_flags(); ?></div >

CSS:

#flags_language_selector img{
 margin:1px;
 border:1px solid #333;
}
国旗语言选择器

语言切换器(仅显示未启用的语言)

本文中的代码示例可用于创建具有以下特征的语言切换器:

  • 水平显示
  • 附加到特定菜单
  • 使用语言国旗和当地名称
  • 只显示非启用语言

您应该将此代码添加到您的主题的functions.php文件中。 更好的解决方案是将其添加到您主题下子主题functions.php中。

该代码默认可以通过theme_location == 『primary』很好地处理默认WordPress主题(Twenty Sixteen, Twenty Fifteen等)。

这是Twenty Sixteen 主题中的语言切换器,当前的语言是英语。
这是 Twenty Sixteen主题中的结果,当前的语言是英语。

使代码与主题一致

其他主题可以使用其他主题位置。 因此,如果代码不适合您的主题,请遵循以下步骤使其可用。

  1. 取消对该行的注释//echo 「args: 「; print_r($args); echo 」 「;换句话说,删除包含上述代码的行开头的双斜杠(//)。
  2. 访问您网站的前端。 您将看到类似[theme_location] => my-theme-location这样的主题位置。
  3. 选择你想要的菜单位置,例如:my-theme-location,将以下行:
if ( $languages && $args->theme_location == 'primary') {

改为:

if ( $languages && $args->theme_location == 'my-theme-location') {

如果不确定使用哪个位置正确,可以逐个尝试菜单位置。

  1. 还原我们在第一步中所做的更改,使该行与原始代码相同。

代码

// Filter wp_nav_menu() to add additional links and other output
// Show only other language in language switcher
// Use the new filter: https://wpml.org/wpml-hook/wpml_active_languages/ 
add_filter('wp_nav_menu_items', 'new_nav_menu_items', 10, 2);
function new_nav_menu_items($items, $args) {
 // uncomment this to find your theme's menu location
 //echo "args:&lt;pre&gt;"; print_r($args); echo "&lt;/pre&gt;";

 // get languages
 $languages = apply_filters( 'wpml_active_languages', NULL, 'skip_missing=0' );

 // add $args-&gt;theme_location == 'primary-menu' in the conditional if we want to specify the menu location.

 if ( $languages &amp;&amp; $args-&gt;theme_location == 'primary') {

 if(!empty($languages)){

 foreach($languages as $l){
 if(!$l['active']){
 // flag with native name
 $items = $items . '
&lt;li class="menu-item"&gt;&lt;a href="' . $l['url'] . '"&gt;&lt;img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /&gt; ' . $l['native_name'] . '&lt;/a&gt;&lt;/li&gt;

';
 //only flag
 //$items = $items . '
&lt;li class="menu-item menu-item-language"&gt;&lt;a href="' . $l['url'] . '"&gt;&lt;img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /&gt;&lt;/a&gt;&lt;/li&gt;

';
 }
 }
 }
 }

 return $items;
}

替换国旗和更改语言名称

WPML 包含一个用于编辑语言信息的 GUI。 转到 WPML->语言,点击编辑语言。 您将能够改变语言名称,编辑其区域设置值,选择不同的国旗。

'skip_missing=0&orderby=name'