Skip to content

Всё для WordPress, веб-разработки — и не только

🔄 Переключатель языков WPML: только ISO-коды вместо флагов и названий

🔄 Переключатель языков WPML: только ISO-коды вместо флагов и названий

Флаги стран в меню сайта, спорное решение. На флаге Великобритании полстраны узнает свой, а вторая половина, нет. Флаг США вместо английского? Для канадцев и австралийцев мимо. А названия языков целиком, «Русский», «Українська», «English», занимают полменю на мобильном экране.

Компактный формат RU | UK | EN решает обе проблемы: читается мгновенно, места почти не занимает и не привязан к географии. Это стандартные ISO-коды языков, двухбуквенные, понятные без перевода в любой стране.

Ниже, два способа заменить стандартный переключатель WPML на ISO-коды. Первый, через фильтр пунктов меню (прост врезкой в functions.php). Второй, шорткод, который выводит переключатель в любом месте сайта.

💡 Быстрый обзор:

  • Способ 1: замена пунктов навигационного меню через хук wp_nav_menu_items, для встроенного переключателя в шапке
  • Способ 2: шорткод [wpml_custom_lang_ISO], вставка в любое место темы (виджет, футер, мобильное меню)
  • CSS: стилизация разделителя |, скрытие активного языка, адаптивность

Как выглядит результат

После добавления кода переключатель языков отображается в формате RU | UK | EN, коротко и аккуратно. Активный язык выделяется или скрывается (задаётся через CSS), остальные языки кликабельны и ведут на соответствующую версию страницы.

Переключатель языков WPML в ISO-формате RU | EN

Код использует штатную функцию WPML icl_get_languages(), она возвращает массив активных языков сайта со всеми данными: URL перевода, код языка, признак активности. Никаких сторонних зависимостей, только API самого WPML.

Способ 1: замена пунктов меню через wp_nav_menu_items

Этот метод перехватывает вывод навигационного меню WordPress и заменяет стандартные пункты-языки на компактные ISO-коды с разделителем.

Куда вставлять: functions.php дочерней темы или через плагин Code Snippets (безопаснее, не сотрётся при обновлении темы).

Перед добавлением сделайте полный бэкап сайта. Код не деструктивный и только добавляет вывод, но бэкап, правило хорошего тона при любой правке functions.php.

1/**
2 * Заменяет пункты языков WPML в меню на ISO-коды.
3 * theme_location задаётся под ваше меню.
4 */
5add_filter( 'wp_nav_menu_items', 'wpml_iso_menu_items', 10, 2 );
6
7function wpml_iso_menu_items( $items, $args ) {
8 // Проверяем, что функция WPML доступна
9 if ( ! function_exists( 'icl_get_languages' ) ) {
10 return $items;
11 }
12
13 $languages = icl_get_languages( 'skip_missing=0&orderby=code' );
14
15 // Укажите здесь theme_location вашего меню (например 'primary', 'top')
16 if ( empty( $languages ) || $args->theme_location !== 'primary' ) {
17 return $items;
18 }
19
20 $lang_links = '';
21
22 foreach ( $languages as $lang ) {
23 $code = strtoupper( $lang['language_code'] );
24
25 if ( $lang['active'] ) {
26 $lang_links .= '<span class="wpml-lang-item active">' . $code . '</span>';
27 } else {
28 $lang_links .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>';
29 }
30
31 $lang_links .= '<span class="wpml-lang-sep">|</span>';
32 }
33
34 // Убираем последний разделитель
35 $lang_links = rtrim( $lang_links, '<span class="wpml-lang-sep">|</span>' );
36
37 return $items . '<li class="menu-item wpml-iso-switcher">' . $lang_links . '</li>';
38}

Что здесь происходит. Хук wp_nav_menu_items срабатывает при формировании каждого меню на сайте. Условие $args->theme_location !== 'primary' ограничивает замену только нужным меню, замените 'primary' на theme_location вашего меню (смотрите в wp_nav_menu() в шаблоне или в админке: Внешний вид → Меню → места размещения).

Функция icl_get_languages('skip_missing=0') получает все опубликованные языки. skip_missing=0 означает «показать язык, даже если у текущей страницы нет перевода», пользователь попадёт на главную этого языка вместо 404.

strtoupper() приводит коды к верхнему регистру: ruRU. Если нужны строчные, уберите вызов.

Способ 2: шорткод [wpml_custom_lang_ISO]

Шорткод универсальнее: вставляйте [wpml_custom_lang_ISO] в любое место, виджет, текст страницы, PHP-шаблон через do_shortcode(). Подходит для мобильного меню, футера или блока под шапкой.

Куда вставлять: functions.php (тот же файл, что и для способа 1). Можно держать оба способа одновременно, конфликта не будет.

1/**
2 * Шорткод [wpml_custom_lang_ISO] — выводит переключатель языков в ISO-формате.
3 * Вставка: [wpml_custom_lang_ISO] в тексте или <?php echo do_shortcode('[wpml_custom_lang_ISO]'); ?> в шаблоне.
4 */
5add_shortcode( 'wpml_custom_lang_ISO', 'wpml_shortcode_lang_iso' );
6
7function wpml_shortcode_lang_iso() {
8 if ( ! function_exists( 'icl_get_languages' ) ) {
9 return '';
10 }
11
12 $languages = icl_get_languages( 'skip_missing=0&orderby=code&order=desc' );
13 $output = '';
14
15 if ( empty( $languages ) ) {
16 return '';
17 }
18
19 foreach ( $languages as $lang ) {
20 $code = strtoupper( $lang['language_code'] );
21
22 if ( $lang['active'] ) {
23 $output .= '<span class="wpml-lang-item active">' . $code . '</span>';
24 } else {
25 $output .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>';
26 }
27
28 $output .= '<span class="wpml-lang-sep">|</span>';
29 }
30
31 // Убираем последний разделитель
32 $output = rtrim( $output, '<span class="wpml-lang-sep">|</span>' );
33
34 return '<div class="wpml-iso-lang-switcher">' . $output . '</div>';
35}

Разница со способом 1: шорткод возвращает HTML-строку, а не дополняет пункты меню. Поэтому его можно разместить где угодно, не привязан к theme_location. Параметр order=desc меняет порядок языков на обратный (опционально, уберите если не нужен).

Как найти theme_location вашего меню

Если вы используете Способ 1, нужно точно указать аргумент theme_location. Откройте файл шаблона, где вызывается меню (обычно header.php), и найдите строку вида:

1wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 'primary-menu' ) );

Значение в одинарных кавычках, например 'primary', и есть ваш theme_location. Ходовые названия: primary для основного меню, top для верхней панели. Подставьте своё в условие $args->theme_location !== 'primary' из кода выше.

Другой способ: в админке откройте Внешний вид → Меню → вкладка «Места размещения», там перечислены все зарегистрированные theme_location темы.

CSS-стили для переключателя

Минимальный набор стилей, чтобы переключатель выглядел аккуратно. Добавьте в Внешний вид → Настроить → Дополнительные CSS или в файл style.css дочерней темы.

1/* Контейнер переключателя */
2.wpml-iso-lang-switcher,
3.wpml-iso-switcher {
4 display: flex;
5 align-items: center;
6 gap: 0;
7 font-family: 'Oswald', sans-serif;
8 font-size: 16px;
9 font-weight: 600;
10 text-transform: uppercase;
11}
12
13/* Ссылки и активный язык */
14.wpml-lang-item {
15 color: #33445d;
16 text-decoration: none;
17 padding: 4px 2px;
18 transition: color 0.2s;
19}
20
21a.wpml-lang-item:hover {
22 color: #0073aa;
23}
24
25.wpml-lang-item.active {
26 color: #999;
27 cursor: default;
28}
29
30/* Разделитель */
31.wpml-lang-sep {
32 margin: 0 6px;
33 color: #ccc;
34 font-weight: 400;
35}
36
37/* Скрыть активный язык и следующий за ним разделитель */
38.wpml-lang-item.active,
39.wpml-lang-item.active + .wpml-lang-sep {
40 display: none;
41}
42
43/* Мобильная адаптация */
44@media screen and (max-width: 768px) {
45 .wpml-iso-lang-switcher,
46 .wpml-iso-switcher {
47 font-size: 18px;
48 padding: 8px 0;
49 }
50}

Ключевой приём: селектор .wpml-lang-item.active + .wpml-lang-sep скрывает разделитель сразу за активным языком. Если активный язык скрыт, то и разделитель за ним исчезает, не остаётся висячей палки | в начале или конце строки.

Шрифт Oswald указан для примера. Замените на шрифт вашей темы или уберите строку font-family совсем, чтобы унаследовать от темы. После добавления CSS проверьте переключатель на мобильном разрешении через инструменты разработчика (F12 → Toggle device toolbar).

⁉️🤔 Частые вопросы

Можно ли показывать названия языков вместо ISO-кодов?

> Да, замените $lang['language_code'] на $lang['native_name'] в обоих вариантах кода. Получите «Русский | English | Українська». Альтернативно, $lang['translated_name'] выводит названия на языке текущей страницы: если посетитель на английской версии, он увидит «Russian | English | Ukrainian». Все доступные ключи массива перечислены в официальной документации WPML по функции icl_get_languages().

Как убрать язык, у которого нет перевода текущей страницы?

Поменяйте в вызове icl_get_languages() параметр skip_missing=0 на skip_missing=1. Языки без перевода просто исчезнут из переключателя, вместо них не будет битой ссылки. Удобно для сайтов, где переведены не все страницы: меню останется чистым, без ссылок ведущих на главную или 404.

Переключатель не появляется, в чём дело?

Проверьте три момента. Первое: активен ли плагин WPML и добавлены ли языки в WPML → Languages. Второе: совпадает ли theme_location в коде с реальным меню (Способ 1). Третье: вставлен ли шорткод через do_shortcode() если используете его в PHP-шаблоне, а не в тексте страницы (Способ 2). Если всё верно, а переключателя нет, включите WP_DEBUG в wp-config.php и проверьте error.log, возможно в functions.php синтаксическая ошибка.

Как сделать флаги вместе с кодами, например, флаг 🇬🇧 + EN?

Добавьте перед $code эмодзи флага по условию: if ($lang['language_code'] === 'en') $code = '🇬🇧 ' . $code;. Но помните, эмодзи флагов могут не отображаться на Windows. Надёжнее использовать CSS-флаги через ::before с background-image либо встроенные флаги WPML.

Подойдёт ли этот код для Polylang или TranslatePress?

Нет: icl_get_languages() это API именно WPML. Для Polylang аналогом будет функция pll_the_languages(), для TranslatePress свой набор хуков. Логика та же, но названия функций разные.

Итоги: меню или шорткод

Способ с фильтром меню, для тех, кому нужен переключатель строго в навигации и кто точно знает theme_location. Минимум движений: вставили код, заменили название локации, готово. Недостаток: привязан к одному меню, для второго потребуется дублировать хук с другим theme_location.

Шорткод, если переключатель должен быть в нестандартном месте: мобильная панель, футер, сайдбар. Добавили шорткод в виджет «HTML-код» или в шаблон, и управляете позицией через стандартные средства WordPress. Плюс: можно вставить в нескольких местах без дублирования кода.

На практике оба способа мирно живут в одном functions.php. Поставьте фильтр для основного меню и шорткод для мобильной версии, получите аккуратный RU | UK | EN на всех устройствах. А если переключатель нужен третий раз (например в футере), просто добавьте ещё один do_shortcode('[wpml_custom_lang_ISO]') в нужный шаблон.

Какой формат переключателя используете вы: флаги, названия или ISO-коды? Делитесь в комментариях своим опытом настройки многоязычных сайтов, интересно сравнить подходы.