Создание динамического виджета в WordPress с поддержкой AJAX — одна из востребованных задач для разработчиков, которые хотят улучшить пользовательский опыт своих сайтов. Такой виджет позволяет обновлять содержимое без перезагрузки страницы, что особенно полезно для отображения свежих данных или интерактивных элементов.
Что такое динамический виджет и зачем нужна поддержка AJAX в WordPress
Виджет — это самостоятельный блок интерфейса, который можно добавить в боковую панель или другие области сайта. Обычно виджеты отображают статичное содержимое, например, список категорий или календарь. Но динамический виджет способен менять содержимое без перезагрузки страницы, что делает сайт более отзывчивым и современным.
AJAX (Asynchronous JavaScript and XML) — технология, которая позволяет отправлять запросы на сервер и получать ответы асинхронно, без перезагрузки страницы. В WordPress AJAX часто используется для обновления контента, загрузки комментариев, фильтрации товаров и в других случаях.
Объединяя виджет и AJAX, можно реализовать, к примеру, обновление списка последних постов по категории, сортировку элементов или подгрузку дополнительных данных по кнопке.
Создание простого динамического виджета с AJAX в WordPress
Рассмотрим пример создания виджета, который выводит список последних постов, но с возможностью обновления по кнопке без перезагрузки страницы.
Регистрация виджета
Для начала создадим класс виджета, наследующийся от WP_Widget и зарегистрируем его.
class Wpdevelop_Dynamic_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'wpdevelop_dynamic_widget',
'Динамический виджет WPDevelop',
['description' => 'Виджет с динамическим обновлением через AJAX']
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
echo '<div id="wpdevelop-dynamic-content">';
$this->display_latest_posts();
echo '</div>';
echo '<button id="wpdevelop-refresh-btn">Обновить список</button>';
echo $args['after_widget'];
}
private function display_latest_posts() {
$posts = get_posts(['numberposts' => 5]);
echo '<ul>';
foreach ($posts as $post) {
echo '<li>' . esc_html($post->post_title) . '</li>';
}
echo '</ul>';
}
public function form($instance) {
echo '<p>Настроек нет</p>';
}
public function update($new_instance, $old_instance) {
return $old_instance;
}
}
function wpdevelop_register_dynamic_widget() {
register_widget('Wpdevelop_Dynamic_Widget');
}
add_action('widgets_init', 'wpdevelop_register_dynamic_widget');
Этот код создаст виджет, который выведет 5 последних постов и кнопку «Обновить список».
Подключение скриптов и реализация AJAX
Чтобы кнопка обновления работала без перезагрузки, добавим JavaScript с AJAX-запросом и обработчик на сервере.
function wpdevelop_enqueue_scripts() {
wp_enqueue_script('wpdevelop-ajax-script', plugin_dir_url(__FILE__) . 'wpdevelop-ajax.js', ['jquery'], null, true);
wp_localize_script('wpdevelop-ajax-script', 'wpdevelop_ajax_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdevelop_ajax_nonce')
]);
}
add_action('wp_enqueue_scripts', 'wpdevelop_enqueue_scripts');
// Обработчик AJAX-запроса
function wpdevelop_ajax_get_latest_posts() {
check_ajax_referer('wpdevelop_ajax_nonce', 'nonce');
$posts = get_posts(['numberposts' => 5]);
$response = '';
if (!empty($posts)) {
$response .= '<ul>';
foreach ($posts as $post) {
$response .= '<li>' . esc_html($post->post_title) . '</li>';
}
$response .= '</ul>';
} else {
$response = 'Посты не найдены';
}
wp_send_json_success($response);
}
add_action('wp_ajax_wpdevelop_get_latest_posts', 'wpdevelop_ajax_get_latest_posts');
add_action('wp_ajax_nopriv_wpdevelop_get_latest_posts', 'wpdevelop_ajax_get_latest_posts');
Создадим файл wpdevelop-ajax.js с кодом для кнопки:
jQuery(document).ready(function($) {
$('#wpdevelop-refresh-btn').on('click', function() {
var container = $('#wpdevelop-dynamic-content');
$.ajax({
url: wpdevelop_ajax_obj.ajax_url,
type: 'POST',
data: {
action: 'wpdevelop_get_latest_posts',
nonce: wpdevelop_ajax_obj.nonce
},
beforeSend: function() {
container.html('Загрузка...');
},
success: function(response) {
if (response.success) {
container.html(response.data);
} else {
container.html('Ошибка загрузки данных');
}
},
error: function() {
container.html('Ошибка AJAX запроса');
}
});
});
});
Расширение функционала: добавление фильтрации по категориям
Для большего практического применения добавим в виджет возможность выбирать категорию для отображения последних постов. В форме виджета добавим селектор категорий, а AJAX-запрос будет учитывать выбранное значение.
Изменения в методе form и сохранении настроек
public function form($instance) {
$category = !empty($instance['category']) ? $instance['category'] : 0;
$categories = get_categories(['hide_empty' => false]);
?>
<p>
<label for="<?php echo $this->get_field_id('category'); ?>">Выберите категорию:</label>
<select id="<?php echo $this->get_field_id('category'); ?>" name="<?php echo $this->get_field_name('category'); ?>" class="widefat">
<option value="0">Все категории</option>
<?php foreach ($categories as $cat): ?>
<option value="<?php echo esc_attr($cat->term_id); ?>" <?php selected($category, $cat->term_id); ?>><?php echo esc_html($cat->name); ?></option>
<?php endforeach; ?>
</select>
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = [];
$instance['category'] = !empty($new_instance['category']) ? intval($new_instance['category']) : 0;
return $instance;
}
Использование выбранной категории в выводе и AJAX обработчике
При выводе виджета сохраним выбранную категорию в data-атрибут кнопки, чтобы JS мог ее отправлять.
public function widget($args, $instance) {
$category = !empty($instance['category']) ? $instance['category'] : 0;
echo $args['before_widget'];
echo '<div id="wpdevelop-dynamic-content">';
$this->display_latest_posts($category);
echo '</div>';
echo '<button id="wpdevelop-refresh-btn" data-category="' . esc_attr($category) . '">Обновить список</button>';
echo $args['after_widget'];
}
private function display_latest_posts($category = 0) {
$args = ['numberposts' => 5];
if ($category) {
$args['category'] = $category;
}
$posts = get_posts($args);
echo '<ul>';
foreach ($posts as $post) {
echo '<li>' . esc_html($post->post_title) . '</li>';
}
echo '</ul>';
}
В AJAX-обработчике принимаем параметр категории и фильтруем посты:
function wpdevelop_ajax_get_latest_posts() {
check_ajax_referer('wpdevelop_ajax_nonce', 'nonce');
$category = !empty($_POST['category']) ? intval($_POST['category']) : 0;
$args = ['numberposts' => 5];
if ($category) {
$args['category'] = $category;
}
$posts = get_posts($args);
$response = '';
if (!empty($posts)) {
$response .= '<ul>';
foreach ($posts as $post) {
$response .= '<li>' . esc_html($post->post_title) . '</li>';
}
$response .= '</ul>';
} else {
$response = 'Посты не найдены';
}
wp_send_json_success($response);
}
И изменим JavaScript, чтобы отправлять выбранную категорию:
jQuery(document).ready(function($) {
$('#wpdevelop-refresh-btn').on('click', function() {
var container = $('#wpdevelop-dynamic-content');
var category = $(this).data('category');
$.ajax({
url: wpdevelop_ajax_obj.ajax_url,
type: 'POST',
data: {
action: 'wpdevelop_get_latest_posts',
nonce: wpdevelop_ajax_obj.nonce,
category: category
},
beforeSend: function() {
container.html('Загрузка...');
},
success: function(response) {
if (response.success) {
container.html(response.data);
} else {
container.html('Ошибка загрузки данных');
}
},
error: function() {
container.html('Ошибка AJAX запроса');
}
});
});
});
Советы по улучшению и интеграции с плагинами WPShop
Для повышения производительности и удобства администрирования можно интегрировать такой виджет с плагинами из набора WPShop. Например, с Clearfy Pro можно оптимизировать AJAX-запросы и кешировать ответы, а с WPRemark — расширить возможности комментариев, если виджет будет выводить их.
Также стоит учитывать, что AJAX-запросы должны быть безопасными, поэтому мы использовали wp_create_nonce и проверку check_ajax_referer. Это стандартная практика для защиты от CSRF-атак.
Итог
Создание динамического виджета с поддержкой AJAX — это несложная задача, если знать базовые принципы работы WordPress и jQuery. Такой виджет повышает интерактивность сайта, улучшает UX и позволяет гибко выводить данные. Приведенный пример легко адаптируется под разные задачи, от вывода постов до фильтрации товаров WooCommerce.