Система рейтинга – отличный способ повысить вовлечённость пользователей на вашем WordPress-сайте. В этой статье мы подробно разберём, как создать простую и эффективную систему рейтинга для постов, используя собственный плагин и минимальное количество кода. Это поможет вам избежать громоздких сторонних решений и лучше контролировать функциональность.
Зачем нужна собственная система рейтинга в WordPress
Многие владельцы сайтов устанавливают готовые плагины рейтинга, но они часто перегружены лишними функциями, замедляют загрузку страниц и усложняют кастомизацию. Создание собственной системы рейтинга на WordPress позволит вам:
- Контролировать логику и дизайн рейтинга;
- Минимизировать нагрузку на сервер;
- Интегрировать рейтинг с другими функциями или кастомными типами записей;
- Обеспечить уникальный пользовательский опыт.
Далее мы рассмотрим, как реализовать рейтинг с помощью AJAX и пользовательских полей.
Создаем таблицу для хранения рейтингов: wpfind_create_rating_table()
Для хранения голосов создадим отдельную таблицу в базе данных. Это позволит быстро получать и обновлять рейтинги без излишней нагрузки на таблицу постов.
function wpfind_create_rating_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'wpfind_ratings';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
post_id bigint(20) NOT NULL,
user_ip varchar(100) NOT NULL,
rating tinyint(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY post_user (post_id, user_ip)
) $charset_collate;";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
}
register_activation_hook( __FILE__, 'wpfind_create_rating_table' );Эта функция создаёт таблицу с полями для ID записи, IP пользователя, его оценкой и уникальным индексом, чтобы предотвратить повторное голосование с одного IP.
Добавляем рейтинг на страницу поста с помощью шорткода
Чтобы вывести рейтинг на странице, создадим шорткод [wpfind_rating]. Он покажет средний рейтинг и кнопки для голосования.
function wpfind_rating_shortcode() {
if ( ! is_singular() ) return '';
global $wpdb;
$post_id = get_the_ID();
$table = $wpdb->prefix . 'wpfind_ratings';
$average = $wpdb->get_var( $wpdb->prepare(
"SELECT AVG(rating) FROM $table WHERE post_id = %d",
$post_id
) );
$average = $average ? round($average, 2) : 0;
ob_start();
?>
<div id="wpfind-rating" data-postid="<?php echo $post_id; ?>">
<p>Рейтинг: <span id="wpfind-average"><?php echo $average; ?></span> / 5</p>
<div>
<?php for ( $i = 1; $i <= 5; $i++ ) : ?>
<button class="wpfind-rate-btn" data-rate="<?php echo $i; ?>"><?php echo $i; ?></button>
<?php endfor; ?>
</div>
<p id="wpfind-message"></p>
</div>
<?php
return ob_get_clean();
}
add_shortcode('wpfind_rating', 'wpfind_rating_shortcode');Этот код выводит средний рейтинг и пять кнопок для оценки от 1 до 5.
Обработка голосов через AJAX: wpfind_handle_rating()
Для удобства пользователей голосование будет происходить без перезагрузки страницы. Добавим AJAX обработчик.
function wpfind_handle_rating() {
check_ajax_referer( 'wpfind_rating_nonce', 'nonce' );
if ( ! isset($_POST['post_id'], $_POST['rating']) ) {
wp_send_json_error('Неверные данные');
}
$post_id = intval($_POST['post_id']);
$rating = intval($_POST['rating']);
$user_ip = $_SERVER['REMOTE_ADDR'];
if ( $rating < 1 || $rating > 5 ) {
wp_send_json_error('Неверный рейтинг');
}
global $wpdb;
$table = $wpdb->prefix . 'wpfind_ratings';
$exists = $wpdb->get_var( $wpdb->prepare(
"SELECT id FROM $table WHERE post_id = %d AND user_ip = %s",
$post_id, $user_ip
) );
if ( $exists ) {
wp_send_json_error('Вы уже голосовали');
}
$wpdb->insert(
$table,
[
'post_id' => $post_id,
'user_ip' => $user_ip,
'rating' => $rating
],
['%d', '%s', '%d']
);
// Обновляем средний рейтинг после добавления
$average = $wpdb->get_var( $wpdb->prepare(
"SELECT AVG(rating) FROM $table WHERE post_id = %d",
$post_id
) );
wp_send_json_success(['average' => round($average, 2)]);
}
add_action('wp_ajax_wpfind_rate', 'wpfind_handle_rating');
add_action('wp_ajax_nopriv_wpfind_rate', 'wpfind_handle_rating');Обработчик проверяет nonce для безопасности, принимает ID поста и рейтинг, затем сохраняет голос, если пользователь с этим IP ещё не голосовал.
Подключаем JavaScript для AJAX голосования
Добавим скрипт, который отправляет оценку на сервер и обновляет рейтинг на странице.
function wpfind_enqueue_scripts() {
if ( is_singular() ) {
wp_enqueue_script('wpfind-rating', plugin_dir_url(__FILE__) . 'wpfind-rating.js', ['jquery'], null, true);
wp_localize_script('wpfind-rating', 'wpfindData', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpfind_rating_nonce')
]);
}
}
add_action('wp_enqueue_scripts', 'wpfind_enqueue_scripts');В файле wpfind-rating.js разместим следующий код:
jQuery(document).ready(function($) {
$('#wpfind-rating .wpfind-rate-btn').on('click', function() {
var rate = $(this).data('rate');
var postId = $('#wpfind-rating').data('postid');
var message = $('#wpfind-message');
$.post(wpfindData.ajax_url, {
action: 'wpfind_rate',
post_id: postId,
rating: rate,
nonce: wpfindData.nonce
}, function(response) {
if ( response.success ) {
$('#wpfind-average').text(response.data.average);
message.text('Спасибо за ваш голос!').css('color', 'green');
} else {
message.text(response.data).css('color', 'red');
}
});
});
});Расширяем и настраиваем систему рейтинга
Вы можете дополнить систему, например, добавив:
- Вывод количества голосов рядом с рейтингом;
- Возможность голосовать только для зарегистрированных пользователей;
- Кастомный дизайн кнопок и анимацию;
- Кэширование результатов для повышения скорости загрузки;
- Добавление рейтинга в REST API для интеграций.
Для вывода количества голосов можно добавить в запрос среднее и количество:
$data = $wpdb->get_row( $wpdb->prepare(
"SELECT AVG(rating) as avg_rating, COUNT(*) as votes FROM $table WHERE post_id = %d",
$post_id
) );И вывести их в шорткоде.
Использование готовых плагинов для рейтинга
Если вы не хотите писать код, рассмотрите популярные плагины рейтинга:
- WP-PostRatings – классический и простой;
- Yasr – Yet Another Stars Rating – с расширенными возможностями;
- Rating-Widget – виджеты и интеграции с соцсетями.
Однако, собственный плагин даёт максимальную гибкость и экономит ресурсы.