Originally written
25 января, 2013
Обновлено
30 декабря, 2019

Разработчики могут создавать собственные пользовательские переключатели языка с помощью API-вызова icl_get_languages из WPML. В этом руководстве подробно описан 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 указывает для функции, что делать с языками, на которых нет переводов.
  • Сочетание orderby и order позволяет создать раскрывающийся переключатель языка или переключатели языка, в которых языки всегда отображаются в одном месте.
  • Можно определить собственный порядок в консоли администратора WordPress в разделе WPML » Языки » Параметры переключателя языка

Функция возвращает массив с элементами каждого языка. Например, в случае сайта 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: URL-адрес изображения флага страны в формате PNG
  • 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’]

В результате мы получим следующее:

Сообщение о том, что запись доступна на других языках
Сообщение о том, что запись доступна на других языках

Чтобы это сообщение отображалось в записях, добавьте вызов к icl_post_languages() из single.php.

Список названий языков с их флагами в нижнем колонтитуле

Даже если у вас есть селектор языков вверху страницы, список названий языков с их флагами в нижнем колонтитуле не помешает. Многие посетители сразу прокручивают страницу вниз для лучшего представления о сайте, поэтому вы, скорее всего, поможете своим иностранным гостям, разместив там видный переключатель языка.

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’]);

WPML создает функцию icl_disp_language(). Она проверяет, различаются ли эти два аргумента (native_language_name, translated_language_name) are different. Если да, она возвращает оба, в противном случае она возвращает только один.

Необходимо добавить немного 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 .

* Обратите внимание: этот горизонтальный переключатель языка легко превратить в вертикальный. Просто удалите оператор display: inline из CSS-кода.

Селектор языка только с флагами

Простая функция для отображения флагов, связанных с переводами текущей страницы.

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 ее дочерней темы.

По умолчанию код отлично работает со стандартными темами WordPress (Twenty Sixteen, Twenty Fifteen и т.д.) с помощью theme_location == ‘primary’.

Это переключатель языка в теме Twenty Sixteen английским в качестве текущего языка.
Это результат в теме Twenty Sixteen английским в качестве текущего языка.

Обеспечение работоспособности кода в вашей теме

В других темах могут использоваться другие расположения. Поэтому, если код не работает в вашей теме, выполните указанные ниже действия, чтобы это исправить.

  1. Раскомментируйте строку Другими словами удалите две косые черты (//) в начале строки с вышеупомянутым кодом.
  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. Отмените изменения, внесенные в первом пункте, чтобы строка совпадала с исходным кодом.

Код

// Фильтровать wp_nav_menu() для добавления дополнительных ссылок и другого вывода
// Показывать только другой язык в переключателе языка
// Используйте новый фильтр: 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) {
 // раскомментируйте для определения расположения меню вашей темы
 //echo "args:<pre>"; print_r($args); echo "</pre>";

 // получить языки
 $languages = apply_filters( 'wpml_active_languages', NULL, 'skip_missing=0' );

 // добавьте $args->theme_location == 'primary-menu' в условии, если необходимо указать расположение меню.

 if ( $languages && $args->theme_location == 'primary') {

 if(!empty($languages)){

 foreach($languages as $l){
 if(!$l['active']){
 // флаг с родным названием языка
 $items = $items . '
<li class="menu-item"><a href="' . $l['url'] . '"><img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /> ' . $l['native_name'] . '</a></li>

';
 //только флаг
 //$items = $items . '
<li class="menu-item menu-item-language"><a href="' . $l['url'] . '"><img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /></a></li>

';
 }
 }
 }
 }

 return $items;
}

Замена флагов стран и изменение названий языков

Для изменения информации о языке в WPML есть графический интерфейс. Перейдите в WPML->Языки и щелкните Изменить языки. Здесь можно изменить названия языков, их стандарт и выбрать другие флаги.

'skip_missing=0&orderby=name'