Динамические виджеты в WordPress — отличный способ отображать актуальный контент, загружаемый асинхронно, без необходимости перезагружать всю страницу. Особенно это актуально при работе с REST API, когда данные приходят с внешних или внутренних источников. В этой статье мы подробно рассмотрим, как создать собственный динамический виджет, который будет загружать данные через REST API, используя нативные возможности WordPress и минимальное количество сторонних библиотек.
Почему стоит использовать REST API в виджетах WordPress
REST API открывает широкие возможности для взаимодействия с данными WordPress и внешними сервисами. В отличие от стандартных виджетов, которые выводят статический HTML, динамические виджеты с REST API позволяют:
- Подгружать свежие данные без перезагрузки страницы;
- Обрабатывать пользовательские запросы и фильтры в реальном времени;
- Интегрироваться с внешними сервисами и источниками данных;
- Уменьшить нагрузку на сервер за счет асинхронных запросов.
Для примера создадим виджет, который будет выводить последние 5 опубликованных записей, получая данные через REST API WordPress.
Создаем базовый класс виджета
Начнем с регистрации собственного виджета. В файле functions.php вашей темы или в отдельном плагине добавьте следующий код:
class WPMart_Widget_Recent_Posts_API extends WP_Widget {
public function __construct() {
parent::__construct(
'wpmart_recent_posts_api',
'WPMart: Динамические последние записи',
['description' => 'Виджет, подгружающий последние записи через REST API']
);
}
public function widget( $args, $instance ) {
echo $args['before_widget'];
echo $args['before_title'] . apply_filters( 'widget_title', 'Последние записи' ) . $args['after_title'];
// Контейнер для динамического контента
echo '<div id="wpmart-recent-posts-container">Загрузка...</div>';
echo $args['after_widget'];
}
public function form( $instance ) {
// Опционально: настройки виджета
}
public function update( $new_instance, $old_instance ) {
// Обработка обновления настроек
return $new_instance;
}
}
function wpmart_register_widget() {
register_widget( 'WPMart_Widget_Recent_Posts_API' );
}
add_action( 'widgets_init', 'wpmart_register_widget' );Этот код регистрирует новый виджет с названием «Динамические последние записи», который выводит заголовок и контейнер для загрузки данных через JavaScript.
Подключаем JavaScript для загрузки данных через REST API
Чтобы загрузить данные динамически, нам нужен скрипт, который выполнит AJAX-запрос к REST API WordPress. Добавим следующий код в functions.php, чтобы подключить скрипт и передать ему параметры:
function wpmart_enqueue_widget_scripts() {
wp_enqueue_script( 'wpmart-recent-posts', get_template_directory_uri() . '/js/wpmart-recent-posts.js', ['jquery'], null, true );
wp_localize_script( 'wpmart-recent-posts', 'wpmartApiSettings', [
'restUrl' => esc_url_raw( rest_url( 'wp/v2/posts' ) ),
'postsPerPage' => 5,
'nonce' => wp_create_nonce( 'wp_rest' )
]);
}
add_action( 'wp_enqueue_scripts', 'wpmart_enqueue_widget_scripts' );Теперь создадим файл js/wpmart-recent-posts.js в вашей теме или плагине с таким содержимым:
(function($) {
$(document).ready(function() {
var container = $('#wpmart-recent-posts-container');
$.ajax({
url: wpmartApiSettings.restUrl,
method: 'GET',
data: {
per_page: wpmartApiSettings.postsPerPage,
_embed: true
},
beforeSend: function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', wpmartApiSettings.nonce);
},
success: function(data) {
if (data.length === 0) {
container.html('<p>Записей не найдено.</p>');
return;
}
var html = '<ul>';
data.forEach(function(post) {
html += '<li><a href="' + post.link + '">' + post.title.rendered + '</a></li>';
});
html += '</ul>';
container.html(html);
},
error: function() {
container.html('<p>Ошибка загрузки данных.</p>');
}
});
});
})(jQuery);Оптимизация и безопасность
Использование wp_create_nonce('wp_rest') и передачи заголовка X-WP-Nonce гарантирует, что запросы к REST API защищены от CSRF-атак. В реальных проектах важно дополнительно фильтровать и кешировать полученные данные для повышения производительности.
Также стоит рассмотреть возможность ограничения доступа к данным, если виджет используется на публичной части сайта, и убедиться, что только необходимые поля возвращаются API, чтобы уменьшить нагрузку и повысить безопасность.
Расширение функционала: добавляем параметры виджета
Для удобства можно добавить в виджет настройки, например, количество выводимых записей или выбор категории. Для этого дополним метод form и добавим обработку в метод update:
public function form($instance) {
$posts_per_page = !empty($instance['posts_per_page']) ? absint($instance['posts_per_page']) : 5;
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('posts_per_page')); ?>">Количество записей:</label>
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('posts_per_page')); ?>" name="<?php echo esc_attr($this->get_field_name('posts_per_page')); ?>" type="number" step="1" min="1" value="<?php echo $posts_per_page; ?>" size="3" />
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = [];
$instance['posts_per_page'] = (!empty($new_instance['posts_per_page'])) ? absint($new_instance['posts_per_page']) : 5;
return $instance;
}И передадим это значение в JavaScript через wp_localize_script, заменив жестко заданное число.
Использование плагина Clearfy Pro для управления REST API
Если вы хотите контролировать доступ к REST API без написания дополнительных фильтров, можно использовать плагин Clearfy Pro. Он позволяет ограничивать доступ к REST API, отключать ненужные эндпоинты и повышать безопасность сайта.
Итог
Создание собственного динамического виджета с загрузкой данных через REST API — мощный инструмент для разработчиков WordPress. Такой подход позволяет создавать гибкие и интерактивные элементы сайта, которые подстраиваются под потребности пользователей и упрощают интеграцию с внешними сервисами.
Используйте приведенный пример как основу для своих проектов и расширяйте функционал в зависимости от задачи. Не забывайте про оптимизацию и безопасность при работе с REST API.