Как создать производительный виджет в WordPress с помощью REST API

Создание собственных виджетов в WordPress — популярная задача для разработчиков, которые хотят добавить уникальный функционал и улучшить пользовательский опыт. Однако классические виджеты, использующие PHP и серверные вызовы напрямую, иногда становятся узким местом в производительности, особенно при большом числе посетителей.

В этой статье разберём, как создать производительный кастомный виджет, который максимально эффективно использует REST API, чтобы загружать данные асинхронно и разгружать сервер от лишних операций при генерации страницы.

Преимущества использования REST API для виджетов в WordPress

REST API даёт нам возможность отделить логику получения данных от генерации HTML на стороне сервера. Вместо того, чтобы загружать все данные сразу при формировании страницы, виджет может подгружать информацию динамически через JavaScript. Это существенно снижает нагрузку на сервер и ускоряет время отклика.

Кроме того, такой подход облегчает кеширование HTML, так как основной шаблон страницы становится более статичным, а динамическая часть обновляется по необходимости.

Ещё одно преимущество — возможность легко адаптировать виджет под различные запросы и фильтры, передавая параметры в REST-запросы.

Создание эндпоинта REST API для виджета

Для начала создадим собственный эндпоинт REST API, который будет возвращать нужные данные для виджета. Допустим, нам нужно отображать последние 5 постов определённой категории.

add_action('rest_api_init', function () {
    register_rest_route('wphelper/v1', '/latest-posts/', array(
        'methods' => 'GET',
        'callback' => 'wphelper_get_latest_posts',
        'args' => array(
            'category' => array(
                'required' => false,
                'validate_callback' => function($param) {
                    return is_numeric($param);
                }
            ),
        ),
    ));
});

function wphelper_get_latest_posts($request) {
    $category = $request->get_param('category');
    $args = [
        'posts_per_page' => 5,
        'post_status' => 'publish',
    ];
    if ($category) {
        $args['category'] = intval($category);
    }
    $posts = get_posts($args);
    $data = [];
    foreach ($posts as $post) {
        $data[] = [
            'id' => $post->ID,
            'title' => get_the_title($post->ID),
            'link' => get_permalink($post->ID),
            'date' => get_the_date('', $post->ID),
        ];
    }
    return rest_ensure_response($data);
}

Этот код регистрирует маршрут /wp-json/wphelper/v1/latest-posts/, который возвращает JSON с последними 5 публикациями. Параметр category позволяет фильтровать посты по категории.

Создание JavaScript для загрузки данных виджета

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

document.addEventListener('DOMContentLoaded', function() {
    const widget = document.getElementById('wphelper-latest-posts-widget');
    if (!widget) return;

    const category = widget.getAttribute('data-category') || '';
    let url = '/wp-json/wphelper/v1/latest-posts/';
    if (category) {
        url += '?category=' + encodeURIComponent(category);
    }

    fetch(url)
        .then(response => response.json())
        .then(data => {
            if (data.length === 0) {
                widget.innerHTML = '<p>Посты не найдены.</p>';
                return;
            }
            const ul = document.createElement('ul');
            data.forEach(post => {
                const li = document.createElement('li');
                const a = document.createElement('a');
                a.href = post.link;
                a.textContent = post.title + ' (' + post.date + ')';
                li.appendChild(a);
                ul.appendChild(li);
            });
            widget.innerHTML = '';
            widget.appendChild(ul);
        })
        .catch(() => {
            widget.innerHTML = '<p>Ошибка загрузки данных.</p>';
        });
});

Этот скрипт ищет элемент с id wphelper-latest-posts-widget, получает опциональный атрибут data-category и делает запрос к REST API. После получения данных он формирует список ссылок на посты.

Регистрация и вывод виджета в WordPress

Теперь нужно зарегистрировать виджет и вывести его в нужном месте темы. Пример регистрации через виджетный класс:

class WPHelper_Latest_Posts_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wphelper_latest_posts',
            'WPHelper: Последние посты с REST API',
            ['description' => 'Виджет для отображения последних постов с использованием REST API']
        );
    }

    public function widget($args, $instance) {
        $category = !empty($instance['category']) ? intval($instance['category']) : '';
        echo $args['before_widget'];
        echo $args['before_title'] . 'Последние посты' . $args['after_title'];
        echo '<div id="wphelper-latest-posts-widget" data-category="' . esc_attr($category) . '">Загрузка...</div>';
        echo $args['after_widget'];
    }

    public function form($instance) {
        $category = !empty($instance['category']) ? intval($instance['category']) : '';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('category'); ?>">ID категории:</label>
            <input class="widefat" id="<?php echo $this->get_field_id('category'); ?>" name="<?php echo $this->get_field_name('category'); ?>" type="number" value="<?php echo esc_attr($category); ?>" />
            <small>Оставьте пустым для всех категорий</small>
        </p>
        <?php
    }

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

add_action('widgets_init', function() {
    register_widget('WPHelper_Latest_Posts_Widget');
});

После добавления этого кода в functions.php темы или в отдельный плагин, в админке появится новый виджет «WPHelper: Последние посты с REST API». Его можно добавить в сайдбар и указать ID категории для фильтрации.

Оптимизация и кеширование REST API ответов

Для повышения производительности желательно кешировать результаты REST API, чтобы избежать лишних запросов к базе данных. В WordPress можно использовать объектный кеш или transient API.

Пример кеширования внутри callback-функции:

function wphelper_get_latest_posts($request) {
    $category = $request->get_param('category');
    $cache_key = 'wphelper_latest_posts_' . ($category ? $category : 'all');
    $cached = get_transient($cache_key);
    if ($cached !== false) {
        return rest_ensure_response($cached);
    }

    $args = [
        'posts_per_page' => 5,
        'post_status' => 'publish',
    ];
    if ($category) {
        $args['category'] = intval($category);
    }
    $posts = get_posts($args);
    $data = [];
    foreach ($posts as $post) {
        $data[] = [
            'id' => $post->ID,
            'title' => get_the_title($post->ID),
            'link' => get_permalink($post->ID),
            'date' => get_the_date('', $post->ID),
        ];
    }
    set_transient($cache_key, $data, HOUR_IN_SECONDS);
    return rest_ensure_response($data);
}

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

Подключение JavaScript в тему

Не забудьте подключить скрипт с загрузкой данных виджета через wp_enqueue_script:

function wphelper_enqueue_widget_script() {
    wp_enqueue_script('wphelper-latest-posts', get_template_directory_uri() . '/js/wphelper-latest-posts.js', [], null, true);
}
add_action('wp_enqueue_scripts', 'wphelper_enqueue_widget_script');

В итоге вы получаете лёгкий, производительный и современный виджет, который использует преимущества REST API и JS для динамического отображения контента без лишней нагрузки на сервер.

Этот подход отлично подходит для сайтов с большим трафиком и поможет улучшить пользовательский опыт без потери функционала.

WooCommerce: автоматическое удаление товаров без заказов
26.05.2026
Как избежать ошибки Maximum execution time в WordPress
24.03.2026
Как создать автоматический бекап WordPress без плагинов
12.01.2026
Как ответить на AJAX-запросы в WordPress без использования admin-ajax.php
09.12.2025
Как правильно подключить внешние стили и скрипты в WordPress
15.03.2026