Создание многоязычного сайта – частая задача для владельцев проектов на WordPress. Обычно для этого используют популярные плагины, такие как WPML или Polylang. Но что делать, если хочется обойтись без плагинов, чтобы не нагружать сайт и иметь полный контроль над реализацией? В этой статье рассмотрим, как сделать многоязычный сайт на WordPress без плагинов, используя собственные функции и настройки.
Почему стоит создавать многоязычный сайт без плагинов
Плагины для многоязычности удобны, но иногда они могут:
- замедлять работу сайта из-за нагрузки;
- создавать сложности с совместимостью при обновлениях;
- ограничивать гибкость кастомизации;
- вводить дополнительную сложность в админ-панель.
Поэтому создание собственной системы переводов — хороший вариант для разработчиков, которые хотят контролировать все аспекты и оптимизировать производительность.
Основные подходы к реализации многоязычности на WordPress без плагинов
Для начала нужно определиться со способом хранения и вывода переводов. Мы рассмотрим популярный подход с использованием кастомных типов записей и шаблонов.
1. Создаем кастомный тип записей для языков
Чтобы разделить контент по языкам, создадим кастомный тип записей language, где будет храниться информация о каждом языке и его свойствах.
function wpzoom_register_language_cpt() {
$labels = array(
'name' => 'Языки',
'singular_name' => 'Язык',
'add_new' => 'Добавить язык',
'add_new_item' => 'Добавить новый язык',
'edit_item' => 'Редактировать язык',
'new_item' => 'Новый язык',
'all_items' => 'Все языки',
'view_item' => 'Просмотр языка',
'search_items' => 'Поиск языков',
'not_found' => 'Языки не найдены',
'not_found_in_trash' => 'В корзине языки не найдены'
);
$args = array(
'labels' => $labels,
'public' => false,
'show_ui' => true,
'supports' => array('title'),
'menu_position' => 20,
'menu_icon' => 'dashicons-translation'
);
register_post_type('wpzoom_language', $args);
}
add_action('init', 'wpzoom_register_language_cpt');В админке появится новый раздел «Языки», где можно добавить, например, «Русский», «Английский» и т.д.
2. Добавляем связь языков с контентом
Чтобы связать языки с записями (постами, страницами), добавим кастомное поле, которое будет хранить ID языка из кастомного типа wpzoom_language. Для удобства можно использовать метабоксы.
function wpzoom_add_language_meta_box() {
add_meta_box('wpzoom_language_meta', 'Язык записи', 'wpzoom_language_meta_box_callback', 'post', 'side', 'default');
add_meta_box('wpzoom_language_meta', 'Язык записи', 'wpzoom_language_meta_box_callback', 'page', 'side', 'default');
}
add_action('add_meta_boxes', 'wpzoom_add_language_meta_box');
function wpzoom_language_meta_box_callback($post) {
$selected_lang = get_post_meta($post->ID, '_wpzoom_language_id', true);
$languages = get_posts(array('post_type' => 'wpzoom_language', 'numberposts' => -1));
echo '<select name="_wpzoom_language_id" style="width:100%;">';
echo '<option value="">Выберите язык</option>';
foreach ($languages as $lang) {
$selected = ($selected_lang == $lang->ID) ? 'selected' : '';
echo '<option value="' . esc_attr($lang->ID) . '" ' . $selected . '>' . esc_html($lang->post_title) . '</option>';
}
echo '</select>';
wp_nonce_field('wpzoom_save_language_meta', 'wpzoom_language_meta_nonce');
}
function wpzoom_save_language_meta($post_id) {
if (!isset($_POST['wpzoom_language_meta_nonce']) || !wp_verify_nonce($_POST['wpzoom_language_meta_nonce'], 'wpzoom_save_language_meta')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (isset($_POST['_wpzoom_language_id'])) {
update_post_meta($post_id, '_wpzoom_language_id', intval($_POST['_wpzoom_language_id']));
}
}
add_action('save_post', 'wpzoom_save_language_meta');Теперь при создании или редактировании записи можно указать, к какому языку она относится.
3. Создаем пользовательскую логику вывода контента по языкам
Следующий шаг – фильтрация контента на фронтенде по выбранному языку пользователя. Для этого добавим функцию, которая определит текущий язык сайта из URL, например, и отфильтрует запросы WordPress.
Предположим, в URL используется префикс с языковым кодом, например, wpzoom.ru/en/ или wpzoom.ru/ru/.
function wpzoom_get_current_language_slug() {
$uri = trim($_SERVER['REQUEST_URI'], '/');
$parts = explode('/', $uri);
$possible_lang = isset($parts[0]) ? $parts[0] : '';
$languages = get_posts(array('post_type' => 'wpzoom_language', 'numberposts' => -1));
foreach ($languages as $lang) {
// Для простоты используем заголовок языка в нижнем регистре как код
if (mb_strtolower($lang->post_title) === mb_strtolower($possible_lang)) {
return $possible_lang;
}
}
return 'ru'; // Язык по умолчанию
}
function wpzoom_filter_posts_by_language($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
$current_lang_slug = wpzoom_get_current_language_slug();
$languages = get_posts(array('post_type' => 'wpzoom_language', 'numberposts' => -1));
$language_id = 0;
foreach ($languages as $lang) {
if (mb_strtolower($lang->post_title) === $current_lang_slug) {
$language_id = $lang->ID;
break;
}
}
if ($language_id) {
$meta_query = array(
array(
'key' => '_wpzoom_language_id',
'value' => $language_id,
'compare' => '='
)
);
$query->set('meta_query', $meta_query);
}
}
add_action('pre_get_posts', 'wpzoom_filter_posts_by_language');Таким образом, если пользователь зашел на /en/, то выведутся только записи, у которых в метаполе установлен язык «English».
Настройка ЧПУ и пермалинков для многоязычности
Чтобы описанный выше метод работал корректно, нужно настроить структуру постоянных ссылок с учетом языковых префиксов.
Для этого можно добавить правила перезаписи в functions.php:
function wpzoom_add_rewrite_rules() {
$languages = get_posts(array('post_type' => 'wpzoom_language', 'numberposts' => -1));
foreach ($languages as $lang) {
$slug = mb_strtolower($lang->post_title);
add_rewrite_rule('^' . $slug . '/?$', 'index.php?post_type=post', 'top');
add_rewrite_rule('^' . $slug . '/([^/]+)/?$', 'index.php?name=$matches[1]&post_type=post', 'top');
}
}
add_action('init', 'wpzoom_add_rewrite_rules');После добавления правил не забудьте обновить постоянные ссылки в админке WordPress (Настройки → Постоянные ссылки).
Переключатель языка на сайте
Чтобы пользователи могли менять язык, сделаем простой переключатель, который будет формировать ссылки с префиксом языка.
function wpzoom_language_switcher() {
$languages = get_posts(array('post_type' => 'wpzoom_language', 'numberposts' => -1));
$current_lang = wpzoom_get_current_language_slug();
echo '<div class="wpzoom-language-switcher">';
foreach ($languages as $lang) {
$slug = mb_strtolower($lang->post_title);
$class = ($slug === $current_lang) ? 'active' : '';
$url = home_url('/' . $slug . '/');
echo '<a href="' . esc_url($url) . '" class="' . esc_attr($class) . '">' . esc_html($lang->post_title) . '</a> ';
}
echo '</div>';
}В шаблоне вызовите wpzoom_language_switcher(), чтобы вывести переключатель языков в удобном месте.
Преимущества и недостатки такого подхода
К плюсам можно отнести полный контроль над кодом, отсутствие дополнительной нагрузки и возможность адаптировать систему под свои нужды.
Минусы — необходимость самостоятельно поддерживать код, отсутствие готовых удобств из плагинов (автоматический перевод, синхронизация контента, SEO-настройки). Но для небольших проектов этот способ отлично подходит.
Итог
Создать многоязычный сайт на WordPress без плагинов возможно, если использовать кастомные типы записей для языков, связывать записи с языками через метаполя и фильтровать контент на фронтенде. Также важно реализовать корректные правила перезаписи и удобный переключатель языков для пользователей.
Этот метод подойдет тем, кто хочет минимизировать использование стороннего ПО и иметь полный контроль над многоязычностью своего сайта.