
🔄 Переключатель языков 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 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 */ 5 add_filter( 'wp_nav_menu_items', 'wpml_iso_menu_items', 10, 2 ); 6 7 function 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() приводит коды к верхнему регистру: ru → RU. Если нужны строчные, уберите вызов.
Способ 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 */ 5 add_shortcode( 'wpml_custom_lang_ISO', 'wpml_shortcode_lang_iso' ); 6 7 function 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), и найдите строку вида:
1 wp_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 21 a.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-коды? Делитесь в комментариях своим опытом настройки многоязычных сайтов, интересно сравнить подходы.



