Создание динамической системы упоминаний пользователей в WordPress

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

Зачем нужна система упоминаний в WordPress

Упоминания — это способ адресовать сообщение конкретному пользователю, используя его имя или никнейм, предваряемое специальным символом, например, @. Это позволяет:

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

Реализовать такую систему можно с помощью плагинов, но зачастую полезно сделать кастомное решение, адаптированное под конкретные задачи и дизайн сайта.

Выбор плагина для реализации упоминаний и его ограничения

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

  • Mentionable — плагин добавляет возможность упоминаний в комментариях и постах, поддерживает автодополнение;
  • Mentions — интегрируется с редактором Gutenberg, позволяет упоминать пользователей;
  • WPRemark — мощный плагин для создания динамических форм и взаимодействий, его можно расширить для поддержки упоминаний.

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

Создание собственной системы упоминаний с автодополнением

Подготовка: получение списка пользователей

Для начала нам нужно получить список пользователей, которых можно упоминать. Обычно это зарегистрированные пользователи с определённой ролью (например, подписчики, авторы, редакторы).

function wp0_get_mentionable_users() {
    $args = [
        'role__in' => ['subscriber', 'author', 'editor'],
        'orderby' => 'display_name',
        'order' => 'ASC',
        'fields' => ['ID', 'display_name', 'user_nicename'],
        'number' => 50
    ];
    $users = get_users($args);
    $result = [];
    foreach ($users as $user) {
        $result[] = [
            'id' => $user->ID,
            'name' => $user->display_name,
            'slug' => $user->user_nicename
        ];
    }
    return $result;
}

Этот код возвращает массив пользователей с их id, отображаемым именем и уникальным слагом.

Реализация AJAX-эндпоинта для автодополнения

Чтобы сделать автодополнение, нужно создать AJAX-запрос, который будет возвращать список пользователей по введённой части имени.

add_action('wp_ajax_wp0_mention_search', 'wp0_ajax_mention_search');
add_action('wp_ajax_nopriv_wp0_mention_search', 'wp0_ajax_mention_search');

function wp0_ajax_mention_search() {
    $term = sanitize_text_field($_GET['term'] ?? '');
    if (empty($term)) {
        wp_send_json([]);
    }
    $users = get_users([
        'search' => "*{$term}*",
        'search_columns' => ['user_login', 'user_nicename', 'display_name'],
        'number' => 20
    ]);
    $result = [];
    foreach ($users as $user) {
        $result[] = [
            'id' => $user->ID,
            'label' => $user->display_name . ' (@' . $user->user_nicename . ')',
            'value' => '@' . $user->user_nicename
        ];
    }
    wp_send_json($result);
    wp_die();
}

Подключение скрипта автодополнения в редакторе и комментариях

Подключим jQuery UI Autocomplete для поля ввода комментария и/или редактора. Пример для комментариев:

function wp0_enqueue_mention_scripts() {
    if (is_singular()) {
        wp_enqueue_script('jquery-ui-autocomplete');
        wp_enqueue_script('wp0-mention', get_template_directory_uri() . '/js/wp0-mention.js', ['jquery', 'jquery-ui-autocomplete'], '1.0', true);
        wp_localize_script('wp0-mention', 'wp0Mention', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('wp0_mention_nonce')
        ]);
    }
}
add_action('wp_enqueue_scripts', 'wp0_enqueue_mention_scripts');

Файл wp0-mention.js:

jQuery(document).ready(function($) {
    $('#comment').autocomplete({
        source: function(request, response) {
            $.ajax({
                url: wp0Mention.ajax_url,
                dataType: 'json',
                data: {
                    action: 'wp0_mention_search',
                    term: request.term
                },
                success: function(data) {
                    response(data);
                }
            });
        },
        minLength: 2,
        select: function(event, ui) {
            var val = $(this).val();
            // Заменяем последнее слово на выбранное упоминание
            var newVal = val.replace(/@\w*$/, ui.item.value + ' ');
            $(this).val(newVal);
            return false;
        }
    });
});

Обработка упоминаний при сохранении и выводе

Преобразование упоминаний в ссылки

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

function wp0_parse_mentions($content) {
    $pattern = '/@([a-zA-Z0-9_-]+)/';
    return preg_replace_callback($pattern, function($matches) {
        $user = get_user_by('slug', $matches[1]);
        if ($user) {
            $url = get_author_posts_url($user->ID);
            return '<a href="' . esc_url($url) . '" class="wp0-mention-link">@' . esc_html($matches[1]) . '</a>';
        }
        return $matches[0];
    }, $content);
}
add_filter('comment_text', 'wp0_parse_mentions');
add_filter('the_content', 'wp0_parse_mentions');

Так мы автоматически превращаем упоминания в ссылки на профиль пользователя.

Отправка уведомлений при упоминании

Чтобы пользователь не пропускал упоминания, можно отправлять ему email-уведомления. Пример:

function wp0_notify_user_on_mention($comment_ID, $comment_approved) {
    if (1 !== $comment_approved) return;

    $comment = get_comment($comment_ID);
    preg_match_all('/@([a-zA-Z0-9_-]+)/', $comment->comment_content, $matches);
    if (empty($matches[1])) return;

    $users_notified = [];
    foreach ($matches[1] as $user_slug) {
        $user = get_user_by('slug', $user_slug);
        if ($user && !in_array($user->ID, $users_notified) && $user->ID != $comment->user_id) {
            $subject = 'Вы были упомянуты в комментарии на сайте ' . get_bloginfo('name');
            $message = 'Пользователь оставил комментарий с вашим упоминанием: ' . "\n";
            $message .= get_comment_link($comment_ID);
            wp_mail($user->user_email, $subject, $message);
            $users_notified[] = $user->ID;
        }
    }
}
add_action('comment_post', 'wp0_notify_user_on_mention', 10, 2);

Расширение функционала и интеграция с WPRemark

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

Пример интеграции с WPRemark:

  • Добавьте в форму поле textarea с атрибутом для обработки упоминаний;
  • Подключите JS автодополнения, используя AJAX-эндпоинт из примера выше;
  • Обработайте сохранённые данные WPRemark фильтрами, как мы делали с комментариями, чтобы преобразовывать упоминания в ссылки;
  • Настройте обработчики событий WPRemark для отправки уведомлений.

Выводы и рекомендации по безопасности

При работе с упоминаниями важно учитывать безопасность:

  • санитизируйте все входящие данные, особенно в AJAX-запросах;
  • не позволяйте упоминать пользователей с запрещёнными или конфиденциальными ролями;
  • ограничивайте количество упоминаний в одном комментарии или записи;
  • используйте nonce-поля для защиты AJAX-запросов;
  • тестируйте производительность при большом количестве пользователей.

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

Наш каталог плагинов WordPress