Как сделать многоязычный сайт на WordPress без плагинов

|

Создание многоязычного сайта – частая задача для владельцев проектов на 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 без плагинов возможно, если использовать кастомные типы записей для языков, связывать записи с языками через метаполя и фильтровать контент на фронтенде. Также важно реализовать корректные правила перезаписи и удобный переключатель языков для пользователей.

Этот метод подойдет тем, кто хочет минимизировать использование стороннего ПО и иметь полный контроль над многоязычностью своего сайта.

Как добавить поддержку WebP в WordPress без плагинов
18.03.2026
Как добавить обработку файлов в REST API WordPress с примерами кода
05.02.2026
Создать собственный виджет WordPress: подробное руководство с примерами кода
08.11.2025
WooCommerce: решение проблемы с неактивными кнопками корзины после обновления
22.05.2026
Как добавить автоматическое удаление старого контента в WordPress
14.02.2026
×
WPShop
партнерка без «но»!

До 3225₽ за каждую продажу

Подключиться к игре