Как создать простую систему отзывов в WordPress

Для многих сайтов на WordPress полезно иметь собственную систему отзывов, чтобы пользователи могли оставлять комментарии о товарах, услугах или самом сайте. Использование громоздких плагинов не всегда оправдано, особенно если нужна легкая и кастомная реализация. В этой статье мы подробно разберем, как создать простую систему отзывов на базе стандартных возможностей WordPress и немного кода.

Почему стоит создавать собственную систему отзывов в WordPress

Плагины для отзывов зачастую бывают перегружены лишним функционалом, который не всегда нужен, и могут замедлять сайт. Кроме того, не всегда плагин позволяет гибко настроить логику и дизайн. Собственная реализация дает полный контроль над процессом, минимизирует нагрузку и позволяет интегрировать отзывы в шаблон так, как нужно именно вам.

Кроме того, при создании своей системы можно легко добавить валидацию, защиту от спама, фильтрацию и кастомные поля для отзывов.

В примерах ниже мы будем использовать стандартные типы записей, метаполя и AJAX для динамического добавления отзывов без перезагрузки страницы.

Создание кастомного типа записей для отзывов

Первым шагом создадим отдельный тип записей wpsystem_review, чтобы отделить отзывы от обычных постов и страниц. Это позволит проще управлять ими через админку и выводить отдельно.

function wpsystem_register_review_cpt() {
    $labels = array(
        'name' => 'Отзывы',
        'singular_name' => 'Отзыв',
        'add_new' => 'Добавить отзыв',
        'add_new_item' => 'Добавить новый отзыв',
        'edit_item' => 'Редактировать отзыв',
        'new_item' => 'Новый отзыв',
        'view_item' => 'Просмотреть отзыв',
        'search_items' => 'Поиск отзывов',
        'not_found' => 'Отзывы не найдены',
        'not_found_in_trash' => 'В корзине отзывов не найдено',
        'menu_name' => 'Отзывы'
    );
    $args = array(
        'labels' => $labels,
        'public' => true,
        'has_archive' => false,
        'supports' => array('title', 'editor', 'author'),
        'menu_position' => 20,
        'menu_icon' => 'dashicons-testimonial',
        'show_in_rest' => true
    );
    register_post_type('wpsystem_review', $args);
}
add_action('init', 'wpsystem_register_review_cpt');

Этот код нужно добавить в functions.php вашей темы или в отдельный плагин. После регистрации у вас появится отдельный раздел "Отзывы" в админке.

Добавление метаполя для оценки (рейтинг)

Часто отзывы сопровождаются оценкой в виде звезд или числового рейтинга. Добавим метаполе wpsystem_review_rating, чтобы хранить рейтинг от 1 до 5.

Сначала создадим поле в админке для удобного ввода:

function wpsystem_add_review_meta_box() {
    add_meta_box('wpsystem_review_rating_meta', 'Рейтинг отзыва', 'wpsystem_review_rating_meta_box_callback', 'wpsystem_review', 'side');
}
add_action('add_meta_boxes', 'wpsystem_add_review_meta_box');

function wpsystem_review_rating_meta_box_callback($post) {
    wp_nonce_field('wpsystem_save_review_rating', 'wpsystem_review_rating_nonce');
    $value = get_post_meta($post->ID, 'wpsystem_review_rating', true);
    echo '<label for="wpsystem_review_rating_field">Оценка (1-5):</label> ';
    echo '<input type="number" id="wpsystem_review_rating_field" name="wpsystem_review_rating_field" min="1" max="5" value="' . esc_attr($value) . '" style="width: 100%;" />';
}

function wpsystem_save_review_rating_meta($post_id) {
    if (!isset($_POST['wpsystem_review_rating_nonce']) || !wp_verify_nonce($_POST['wpsystem_review_rating_nonce'], 'wpsystem_save_review_rating')) {
        return;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (isset($_POST['wpsystem_review_rating_field'])) {
        $rating = intval($_POST['wpsystem_review_rating_field']);
        if ($rating < 1) $rating = 1;
        if ($rating > 5) $rating = 5;
        update_post_meta($post_id, 'wpsystem_review_rating', $rating);
    }
}
add_action('save_post', 'wpsystem_save_review_rating_meta');

Теперь при добавлении или редактировании отзыва можно задать рейтинг от 1 до 5.

Вывод отзывов на сайте с рейтингом

Для вывода отзывов на странице можно использовать WP_Query:

$args = array(
    'post_type' => 'wpsystem_review',
    'posts_per_page' => 10,
    'orderby' => 'date',
    'order' => 'DESC'
);
$review_query = new WP_Query($args);
if ($review_query->have_posts()) {
    echo '<div class="wpsystem-reviews">';
    while ($review_query->have_posts()) {
        $review_query->the_post();
        $rating = get_post_meta(get_the_ID(), 'wpsystem_review_rating', true);
        echo '<div class="wpsystem-review">';
        echo '<h3>' . get_the_title() . '</h3>';
        echo '<div class="wpsystem-rating">' . wpsystem_render_stars($rating) . '</div>';
        echo '<div class="wpsystem-content">' . get_the_content() . '</div>';
        echo '</div>';
    }
    echo '</div>';
    wp_reset_postdata();
} else {
    echo '<p>Отзывов пока нет.</p>';
}

function wpsystem_render_stars($rating) {
    $output = '';
    for ($i = 1; $i <= 5; $i++) {
        if ($i <= $rating) {
            $output .= '<span style="color: gold; font-size: 20px;">★</span>';
        } else {
            $output .= '<span style="color: #ccc; font-size: 20px;">☆</span>';
        }
    }
    return $output;
}

Эта функция wpsystem_render_stars выводит звездочки, закрашенные в золотой цвет в зависимости от рейтинга.

Добавление формы для отправки отзывов с помощью AJAX

Чтобы пользователи могли оставлять отзывы прямо на сайте без перезагрузки страницы, реализуем AJAX-форму.

HTML формы:

<form id="wpsystem-review-form">
    <label for="wpsystem_review_title">Заголовок отзыва:</label>
    <input type="text" id="wpsystem_review_title" name="wpsystem_review_title" required />

    <label for="wpsystem_review_content">Текст отзыва:</label>
    <textarea id="wpsystem_review_content" name="wpsystem_review_content" required></textarea>

    <label for="wpsystem_review_rating">Рейтинг (1-5):</label>
    <input type="number" id="wpsystem_review_rating" name="wpsystem_review_rating" min="1" max="5" value="5" required />

    <button type="submit">Отправить отзыв</button>
</form>
<div id="wpsystem-review-response"></div>

JavaScript для AJAX-запроса (подключите этот скрипт, например, в footer.php или через wp_enqueue_script):

document.getElementById('wpsystem-review-form').addEventListener('submit', function(e) {
    e.preventDefault();
    var form = e.target;
    var data = {
        action: 'wpsystem_submit_review',
        title: form.wpsystem_review_title.value,
        content: form.wpsystem_review_content.value,
        rating: form.wpsystem_review_rating.value,
        nonce: wpsystem_ajax_object.nonce
    };

    fetch(wpsystem_ajax_object.ajax_url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams(data)
    })
    .then(response => response.json())
    .then(result => {
        var responseDiv = document.getElementById('wpsystem-review-response');
        if (result.success) {
            responseDiv.innerHTML = '<p style="color: green;">' + result.data.message + '</p>';
            form.reset();
        } else {
            responseDiv.innerHTML = '<p style="color: red;">' + result.data.message + '</p>';
        }
    })
    .catch(error => console.error('Error:', error));
});

PHP-обработчик AJAX-запроса:

function wpsystem_handle_ajax_review() {
    check_ajax_referer('wpsystem_ajax_nonce', 'nonce');

    $title = sanitize_text_field($_POST['title'] ?? '');
    $content = sanitize_textarea_field($_POST['content'] ?? '');
    $rating = intval($_POST['rating'] ?? 0);

    if (empty($title) || empty($content) || $rating < 1 || $rating > 5) {
        wp_send_json_error(array('message' => 'Пожалуйста, заполните все поля корректно.'));
    }

    $review_post = array(
        'post_title' => $title,
        'post_content' => $content,
        'post_status' => 'pending', // можно сразу 'publish', но лучше модерация
        'post_type' => 'wpsystem_review'
    );

    $post_id = wp_insert_post($review_post);
    if (is_wp_error($post_id)) {
        wp_send_json_error(array('message' => 'Ошибка при сохранении отзыва. Попробуйте позже.'));
    }

    update_post_meta($post_id, 'wpsystem_review_rating', $rating);

    wp_send_json_success(array('message' => 'Спасибо за отзыв! После модерации он появится на сайте.'));
}
add_action('wp_ajax_wpsystem_submit_review', 'wpsystem_handle_ajax_review');
add_action('wp_ajax_nopriv_wpsystem_submit_review', 'wpsystem_handle_ajax_review');

Не забудьте локализовать AJAX-переменные в functions.php:

function wpsystem_enqueue_scripts() {
    wp_enqueue_script('wpsystem-review-ajax', get_template_directory_uri() . '/js/wpsystem-review.js', array(), null, true);
    wp_localize_script('wpsystem-review-ajax', 'wpsystem_ajax_object', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wpsystem_ajax_nonce')
    ));
}
add_action('wp_enqueue_scripts', 'wpsystem_enqueue_scripts');

Защита и улучшения системы отзывов

Чтобы избежать спама, можно добавить капчу (например, Google reCAPTCHA) или ограничить отправку отзывов по IP и времени. Также полезно добавить фильтрацию запрещенных слов и уведомление администрации о новых отзывах.

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

Если нужно вывести средний рейтинг, можно сделать отдельную функцию, которая считает среднее значение по метаполям:

function wpsystem_get_average_rating() {
    global $wpdb;
    $ratings = $wpdb->get_col("SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = 'wpsystem_review_rating'");
    $ratings = array_map('intval', $ratings);
    if (count($ratings) === 0) return 0;
    return round(array_sum($ratings) / count($ratings), 2);
}

Вывод среднего рейтинга:

echo 'Средний рейтинг: ' . wpsystem_get_average_rating();
Кастомная аутентификация для REST API в WordPress: подробное руководство
27.02.2026
Как создать автоматическое удаление старого контента в WordPress
21.01.2026
Как добавить автоматическое сохранение в редактор Gutenberg в WordPress
10.11.2025
WooCommerce: как установить разные ставки НДС на один товар
17.05.2026
Как создать автоматический отзыв с подтверждением в WordPress
19.03.2026