Как создать автономную систему комментирования в WordPress без плагинов

В стандартной установке WordPress система комментариев тесно связана с базой данных и встроенными функциями. Однако бывают случаи, когда необходимо создать полностью автономную систему комментирования — например, для кастомных страниц, специфических постов или когда стандартный функционал не подходит по техническим или дизайнерским требованиям. В этой статье мы подробно разберём, как создать такую систему без использования сторонних плагинов, используя только возможности PHP, AJAX и WordPress API.

Почему стоит создавать собственную систему комментирования

Стандартные комментарии WordPress отлично подходят для большинства сайтов, но иногда они имеют ограничения:

  • Ограниченная кастомизация — сложно изменить структуру хранения комментариев или их внешний вид без глубокого погружения;
  • Производительность — на больших сайтах с тысячами комментариев стандартная система может замедляться;
  • Независимость — хотелось бы отделить комментарии от основной базы данных WordPress или реализовать независимый функционал;
  • Особые требования — например, поддержка вложенных форматов, кастомных полей, или интеграция с внешними сервисами.

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

Создание таблицы для хранения комментариев

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

Добавим функцию wordpresses_create_comments_table, которая создаст таблицу при активации темы или плагина:

function wordpresses_create_comments_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'custom_comments';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        post_id BIGINT(20) UNSIGNED NOT NULL,
        user_name VARCHAR(100) NOT NULL,
        user_email VARCHAR(100) NOT NULL,
        comment_text TEXT NOT NULL,
        parent_id BIGINT(20) UNSIGNED DEFAULT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY post_id (post_id),
        KEY parent_id (parent_id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

// Вызов функции при инициализации темы или плагина
add_action('after_switch_theme', 'wordpresses_create_comments_table');

Это создаст таблицу wp_custom_comments с полями для хранения ID поста, имени и email пользователя, текста комментария, ссылки на родительский комментарий и времени создания.

Создание формы и обработка комментариев через AJAX

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

<form id="wordpresses-comment-form" data-post-id="<?php the_ID(); ?>">
    <input type="text" name="user_name" placeholder="Ваше имя" required />
    <input type="email" name="user_email" placeholder="Ваш email" required />
    <textarea name="comment_text" placeholder="Комментарий" required></textarea>
    <input type="hidden" name="parent_id" value="0" />
    <button type="submit">Отправить</button>
</form>
<div id="wordpresses-comments-list"></div>

Далее добавим JavaScript для отправки данных:

jQuery(document).ready(function($) {
    $('#wordpresses-comment-form').on('submit', function(e) {
        e.preventDefault();
        var form = $(this);
        var data = {
            action: 'wordpresses_submit_comment',
            post_id: form.data('post-id'),
            user_name: form.find('[name="user_name"]').val(),
            user_email: form.find('[name="user_email"]').val(),
            comment_text: form.find('[name="comment_text"]').val(),
            parent_id: form.find('[name="parent_id"]').val(),
            security: wordpresses_ajax_object.nonce
        };

        $.post(wordpresses_ajax_object.ajax_url, data, function(response) {
            if(response.success) {
                alert('Комментарий добавлен!');
                loadComments(data.post_id);
                form[0].reset();
            } else {
                alert('Ошибка: ' + response.data);
            }
        });
    });

    function loadComments(postId) {
        $.get(wordpresses_ajax_object.ajax_url, { action: 'wordpresses_load_comments', post_id: postId }, function(response) {
            if(response.success) {
                $('#wordpresses-comments-list').html(response.data);
            }
        });
    }

    loadComments($('#wordpresses-comment-form').data('post-id'));
});

Для корректной работы AJAX нужно зарегистрировать скрипт и локализовать переменные в PHP:

function wordpresses_enqueue_scripts() {
    wp_enqueue_script('wordpresses-comments', get_template_directory_uri() . '/js/comments.js', array('jquery'), '1.0', true);
    wp_localize_script('wordpresses-comments', 'wordpresses_ajax_object', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wordpresses_nonce')
    ));
}
add_action('wp_enqueue_scripts', 'wordpresses_enqueue_scripts');

Обработка отправки комментариев в PHP

Создадим обработчик wordpresses_submit_comment, который будет валидировать данные, сохранять комментарий и возвращать ответ:

function wordpresses_handle_submit_comment() {
    check_ajax_referer('wordpresses_nonce', 'security');

    global $wpdb;
    $table_name = $wpdb->prefix . 'custom_comments';

    $post_id = intval($_POST['post_id']);
    $user_name = sanitize_text_field($_POST['user_name']);
    $user_email = sanitize_email($_POST['user_email']);
    $comment_text = sanitize_textarea_field($_POST['comment_text']);
    $parent_id = intval($_POST['parent_id']);

    if(empty($user_name) || empty($user_email) || empty($comment_text) || !is_email($user_email)) {
        wp_send_json_error('Некорректные данные');
    }

    $inserted = $wpdb->insert($table_name, array(
        'post_id' => $post_id,
        'user_name' => $user_name,
        'user_email' => $user_email,
        'comment_text' => $comment_text,
        'parent_id' => $parent_id > 0 ? $parent_id : null,
        'created_at' => current_time('mysql', 1)
    ));

    if($inserted) {
        wp_send_json_success();
    } else {
        wp_send_json_error('Ошибка при сохранении комментария');
    }
}
add_action('wp_ajax_wordpresses_submit_comment', 'wordpresses_handle_submit_comment');
add_action('wp_ajax_nopriv_wordpresses_submit_comment', 'wordpresses_handle_submit_comment');

Загрузка и отображение комментариев

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

function wordpresses_load_comments() {
    $post_id = intval($_GET['post_id']);
    global $wpdb;
    $table_name = $wpdb->prefix . 'custom_comments';

    $comments = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name WHERE post_id = %d ORDER BY created_at ASC",
        $post_id
    ));

    if(!$comments) {
        wp_send_json_success('<p>Комментариев пока нет.</p>');
    }

    // Формируем иерархию комментариев
    $tree = array();
    $refs = array();

    foreach ($comments as $comment) {
        $comment->children = array();
        $refs[$comment->id] = $comment;
        if ($comment->parent_id) {
            $refs[$comment->parent_id]->children[] = $comment;
        } else {
            $tree[] = $comment;
        }
    }

    $output = wordpresses_render_comments_tree($tree);
    wp_send_json_success($output);
}
add_action('wp_ajax_wordpresses_load_comments', 'wordpresses_load_comments');
add_action('wp_ajax_nopriv_wordpresses_load_comments', 'wordpresses_load_comments');

function wordpresses_render_comments_tree($comments) {
    $html = '<ul class="wordpresses-comments">';
    foreach ($comments as $comment) {
        $html .= '<li>';
        $html .= '<strong>' . esc_html($comment->user_name) . '</strong> <em>' . esc_html($comment->created_at) . '</em>';
        $html .= '<p>' . nl2br(esc_html($comment->comment_text)) . '</p>';
        if (!empty($comment->children)) {
            $html .= wordpresses_render_comments_tree($comment->children);
        }
        $html .= '</li>';
    }
    $html .= '</ul>';
    return $html;
}

Дополнительные улучшения и безопасность

Для повышения безопасности и удобства можно добавить следующие улучшения:

  • Валидация и фильтрация на стороне клиента и сервера (уже частично реализована);
  • Реализация защиты от спама — например, капча или ограничение частоты отправки;
  • Отображение кнопки «Ответить» для вложенных комментариев и передача parent_id в форму;
  • Кэширование комментариев для уменьшения нагрузки на базу;
  • Интеграция с REST API для расширенного взаимодействия и мобильных приложений.

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

Как добавить автоматическое сохранение в визуальном редакторе Gutenberg WordPress
05.03.2026
Как использовать хуки WordPress для оптимизации загрузки сайта
17.01.2026
Как удалить или изменить атрибуты img в WordPress без плагинов
20.02.2026
Как создать инструмент для массовой замены текстов в постах WordPress
11.02.2026
WordPress: как сделать дедупликацию метаданных постов для ускорения сайта
01.02.2026