В современном мире многоязычность сайта — важный аспект удобства для пользователей из разных стран. Многие разработчики используют готовые решения, такие как 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.
- Тестируйте виджет на разных устройствах и браузерах.
Таким образом, вы получите удобный и красивый выбор языка, который повысит удобство пользователей и улучшит общий уровень сайта.