Создание системы оценок на сайте WordPress — частая задача для разработчиков, желающих повысить вовлечённость пользователей и собрать обратную связь. В этой статье подробно рассмотрим, как реализовать динамическую систему оценок с помощью AJAX, которая позволит посетителям ставить оценки без перезагрузки страницы. В конце будет готовый пример кода и рекомендации по плагинам, которые можно использовать для расширения функционала.
Почему именно AJAX для системы оценок в WordPress
Оценки — это интерактивный элемент, который требует моментальной реакции. Если реализовать их без AJAX, то при каждой отправке оценки страница будет перезагружаться, что ухудшит пользовательский опыт. AJAX позволяет отправлять данные на сервер и получать ответ асинхронно, без перезагрузки страницы.
В WordPress AJAX реализуется через специальные хуки wp_ajax_ и wp_ajax_nopriv_, что обеспечивает безопасность и удобство обработки запросов как для авторизованных, так и для гостей.
Рассмотрим создание системы с рейтингом от 1 до 5, с сохранением оценок в метаполях поста и предотвращением повторного голосования с одного IP.
Создание пользовательской функции для сохранения оценки
Для начала добавим функцию-обработчик AJAX-запроса. Она будет принимать POST-запрос с ID поста и оценкой, проверять данные и сохранять оценку в метаполе.
function wpbegin_ajax_save_rating() {
// Проверяем nonce для безопасности
check_ajax_referer('wpbegin_rating_nonce', 'security');
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
$rating = isset($_POST['rating']) ? intval($_POST['rating']) : 0;
if ($post_id <= 0 || $rating < 1 || $rating > 5) {
wp_send_json_error('Неверные данные');
}
// Получаем IP пользователя
$user_ip = $_SERVER['REMOTE_ADDR'];
// Проверяем, голосовал ли уже пользователь
$voted_ips = get_post_meta($post_id, '_wpbegin_voted_ips', true);
if (empty($voted_ips)) {
$voted_ips = [];
}
if (in_array($user_ip, $voted_ips)) {
wp_send_json_error('Вы уже голосовали');
}
// Сохраняем IP
$voted_ips[] = $user_ip;
update_post_meta($post_id, '_wpbegin_voted_ips', $voted_ips);
// Получаем текущие оценки
$ratings = get_post_meta($post_id, '_wpbegin_ratings', true);
if (empty($ratings)) {
$ratings = [];
}
$ratings[] = $rating;
update_post_meta($post_id, '_wpbegin_ratings', $ratings);
// Считаем средний рейтинг
$average = array_sum($ratings) / count($ratings);
wp_send_json_success(['average' => round($average, 2), 'count' => count($ratings)]);
}
add_action('wp_ajax_wpbegin_save_rating', 'wpbegin_ajax_save_rating');
add_action('wp_ajax_nopriv_wpbegin_save_rating', 'wpbegin_ajax_save_rating');В этой функции мы используем nonce для безопасности, сохраняем IP пользователя, чтобы ограничить повторное голосование, и считаем средний рейтинг.
Добавление фронтенд-формы рейтинга и AJAX-запроса
Теперь создадим форму с кнопками для оценки и подключим JavaScript, который будет отправлять запросы на сервер без перезагрузки.
В шаблоне single.php или в нужном месте вставьте следующий HTML:
<div id="wpbegin-rating" data-postid="<?php the_ID(); ?>">
<span class="wpbegin-stars" data-rating="1">★</span>
<span class="wpbegin-stars" data-rating="2">★</span>
<span class="wpbegin-stars" data-rating="3">★</span>
<span class="wpbegin-stars" data-rating="4">★</span>
<span class="wpbegin-stars" data-rating="5">★</span>
<div id="wpbegin-rating-result"></div>
</div>Подключим JavaScript. Можно добавить в footer.php или через wp_enqueue_script, например:
function wpbegin_enqueue_rating_scripts() {
wp_enqueue_script('wpbegin-rating', get_template_directory_uri() . '/js/wpbegin-rating.js', ['jquery'], null, true);
wp_localize_script('wpbegin-rating', 'wpbegin_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpbegin_rating_nonce')
]);
}
add_action('wp_enqueue_scripts', 'wpbegin_enqueue_rating_scripts');Создайте файл wpbegin-rating.js в папке темы /js/ с таким содержанием:
jQuery(document).ready(function($) {
$('#wpbegin-rating .wpbegin-stars').on('click', function() {
var rating = $(this).data('rating');
var post_id = $('#wpbegin-rating').data('postid');
$.ajax({
url: wpbegin_ajax_object.ajax_url,
type: 'POST',
data: {
action: 'wpbegin_save_rating',
rating: rating,
post_id: post_id,
security: wpbegin_ajax_object.nonce
},
success: function(response) {
if(response.success) {
$('#wpbegin-rating-result').html('Спасибо за оценку! Средний рейтинг: ' + response.data.average + ' из 5 (' + response.data.count + ' голосов)');
} else {
$('#wpbegin-rating-result').html('Ошибка: ' + response.data);
}
},
error: function() {
$('#wpbegin-rating-result').html('Произошла ошибка при отправке');
}
});
});
});Как улучшить систему оценок
Использование плагинов для расширенного функционала
Если не хочется писать код с нуля, можно использовать плагины, которые интегрируются с AJAX и предлагают удобный интерфейс:
- Expert Review — мощный плагин для отзывов и рейтингов с гибкими настройками.
- WPRemark — плагин для отзывов с AJAX-обновлением и антиспамом.
Они позволяют легко добавить звёздные рейтинги, пользовательские отзывы и статистику без программирования.
Защита от накруток и дублирующих голосов
В нашем примере мы ограничили голосование по IP, но это не всегда надёжно, так как IP могут быть динамическими. Для более серьёзной защиты можно:
- Использовать cookie для запоминания голосов.
- Требовать регистрацию для голосования.
- Добавлять капчу для предотвращения ботов.
- Интегрировать с плагинами вроде CleanTalk для фильтрации спама.
Вывод среднего рейтинга в шаблоне WordPress
Чтобы вывести средний рейтинг в любом месте шаблона, используйте функцию:
function wpbegin_get_average_rating($post_id) {
$ratings = get_post_meta($post_id, '_wpbegin_ratings', true);
if (empty($ratings)) {
return 0;
}
return round(array_sum($ratings) / count($ratings), 2);
}Пример вызова:
echo 'Средний рейтинг: ' . wpbegin_get_average_rating(get_the_ID()) . ' из 5';Итог
Реализация динамической системы оценок с помощью AJAX в WordPress — задача вполне выполнимая и не слишком сложная. Вы получите быструю реакцию интерфейса и удобство для пользователей. При этом можно использовать как собственный код, так и готовые плагины из WPShop, чтобы расширить функционал и обеспечить защиту от накруток.