Как создать собственный виджет для выбора языка в WordPress

В современном мире многоязычность сайта — важный аспект удобства для пользователей из разных стран. Многие разработчики используют готовые решения, такие как Polylang, WPML или TranslatePress, но зачастую хочется более гибко настроить внешний вид и функциональность элемента выбора языка. В этой статье мы подробно разберём, как создать собственный виджет для выбора языка в WordPress, который можно адаптировать под любой дизайн и логику.

Почему стоит создавать собственный виджет выбора языка в WordPress

Готовые виджеты от плагинов часто ограничены по дизайну и функционалу. Если вы хотите:

  • Иметь полный контроль над выводом списка языков;
  • Добавить кастомные стили и анимации;
  • Интегрировать выбор языка с нестандартной логикой;
  • Оптимизировать нагрузку и убрать лишний код;

то создание собственного виджета — отличный выбор. Это позволит вам не зависеть от обновлений плагинов и расширить возможности по своему усмотрению.

Подготовка: определяем источники данных о языках

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

Работа с Polylang

Polylang хранит языки как термины таксономии language и предоставляет API для получения списка.

Работа с WPML

WPML предоставляет глобальные функции для получения активных языков, например icl_get_languages().

Без плагинов (ручная реализация)

Если вы не используете плагин, можно хранить языки в опциях или использовать кастомные поля. Но чаще всего — это интеграция с плагинами.

Создание базового виджета выбора языка

Мы создадим класс виджета, который будет выводить список языков с ссылками на соответствующие версии сайта.

class Wptranslate_Widget_Language_Select extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wptranslate_language_select',
            __('Выбор языка (wptranslate)', 'wptranslate'),
            array('description' => __('Кастомный виджет для выбора языка', 'wptranslate'))
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        if (!empty($instance['title'])) {
            echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
        }
        echo $this->wptranslate_get_language_list();
        echo $args['after_widget'];
    }

    private function wptranslate_get_language_list() {
        $output = '<ul class="wptranslate-language-list">';

        if (function_exists('pll_get_the_languages')) {
            // Polylang
            $languages = pll_get_the_languages();
            if (!empty($languages)) {
                foreach ($languages as $lang) {
                    $class = $lang['current_lang'] ? ' class="current-language"' : '';
                    $output .= '<li' . $class . '>';
                    $output .= '<a href="' . esc_url($lang['url']) . '">' . esc_html($lang['name']) . '</a>';
                    $output .= '</li>';
                }
            }
        } elseif (function_exists('icl_get_languages')) {
            // WPML
            $languages = icl_get_languages('skip_missing=0&orderby=code');
            if (!empty($languages)) {
                foreach ($languages as $lang) {
                    $class = $lang['active'] ? ' class="current-language"' : '';
                    $output .= '<li' . $class . '>';
                    $output .= '<a href="' . esc_url($lang['url']) . '">' . esc_html($lang['native_name']) . '</a>';
                    $output .= '</li>';
                }
            }
        } else {
            // Без плагина — можно вывести статический список или реализовать свой механизм
            $output .= '<li>Языки не настроены</li>';
        }

        $output .= '</ul>';
        return $output;
    }

    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : __('Выбор языка', 'wptranslate');
        ?>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php _e('Заголовок:'); ?></label>
            <input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
        </p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['title'] = (!empty($new_instance['title'])) ? sanitize_text_field($new_instance['title']) : '';
        return $instance;
    }
}

function wptranslate_register_language_widget() {
    register_widget('Wptranslate_Widget_Language_Select');
}
add_action('widgets_init', 'wptranslate_register_language_widget');

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

Добавление кастомного стиля и UX улучшения

Для удобства пользователей стоит оформить список языков красивыми кнопками или выпадающим меню. Например, добавим простой CSS:

.wptranslate-language-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    gap: 10px;
}
.wptranslate-language-list li {
    margin: 0;
}
.wptranslate-language-list li a {
    display: inline-block;
    padding: 5px 10px;
    background: #0073aa;
    color: #fff;
    text-decoration: none;
    border-radius: 3px;
    transition: background-color 0.3s ease;
}
.wptranslate-language-list li a:hover {
    background: #005177;
}
.wptranslate-language-list li.current-language a {
    background: #00a0d2;
    font-weight: bold;
}

Добавьте этот CSS в файл стилей вашей темы или через кастомайзер. Такой дизайн улучшит восприятие и сделает переключение языков интуитивным.

Расширение виджета: поддержка флагов и AJAX переключения

Добавление флагов к языкам

Для визуального обозначения языка удобно использовать флаги. В Polylang в массиве языков есть поле flag_url, а в WPML — country_flag_url. Дополним вывод:

foreach ($languages as $lang) {
    $flag_url = $lang['flag_url'] ?? $lang['country_flag_url'] ?? '';
    $class = ($lang['current_lang'] ?? $lang['active']) ? ' class="current-language"' : '';
    $output .= '<li' . $class . '>';
    if ($flag_url) {
        $output .= '<img src="' . esc_url($flag_url) . '" alt="' . esc_attr($lang['name'] ?? $lang['native_name']) . '" style="width:20px; height:auto; margin-right:5px; vertical-align:middle;">';
    }
    $output .= '<a href="' . esc_url($lang['url']) . '">' . esc_html($lang['name'] ?? $lang['native_name']) . '</a>';
    $output .= '</li>';
}

Переключение языка без перезагрузки страницы с помощью AJAX

Если хочется сделать переключение более плавным, можно реализовать AJAX-запрос, который меняет язык и подгружает контент без полной перезагрузки. Это уже сложнее и требует работы с JavaScript и серверной частью.

Пример упрощённого подхода:

jQuery(document).on('click', '.wptranslate-language-list a', function(e) {
    e.preventDefault();
    var url = jQuery(this).attr('href');
    jQuery.ajax({
        url: url,
        success: function(data) {
            var newContent = jQuery(data).find('#content').html();
            jQuery('#content').html(newContent);
            history.pushState(null, '', url);
        }
    });
});

Этот скрипт подгружает только содержимое с ID content и обновляет адрес в браузере. Важно, чтобы ваш шаблон имел уникальный ID для основного контента. Для полноценной работы нужно учитывать SEO и навигацию.

Выводы и рекомендации по кастомизации виджета выбора языка

Создание собственного виджета для выбора языка даёт максимальную свободу: вы контролируете внешний вид, логику и интеграцию с другими элементами сайта. При этом не нужно отказываться от преимуществ популярных плагинов, можно использовать их API.

Советы для успешной реализации:

  • Используйте API выбранного плагина для получения данных о языках.
  • Добавляйте кастомные стили для улучшения UX.
  • Рассмотрите добавление флагов для наглядности.
  • Если хотите плавное переключение, реализуйте AJAX с учётом SEO.
  • Тестируйте виджет на разных устройствах и браузерах.

Таким образом, вы получите удобный и красивый выбор языка, который повысит удобство пользователей и улучшит общий уровень сайта.

Как добавить автоперевод форм в WordPress
16.01.2026
Как сделать автоперевод контента WordPress на основе open source решений
23.01.2026
Как сделать перевод административной панели WordPress на русский язык
06.01.2026
Как исправить проблему с переводом постоянных ссылок (Permalinks) в WordPress
09.12.2025
Как добавить поддержку мультиязычности в собственном плагине WordPress
23.12.2025