Современные сайты на WordPress часто требуют интеграции динамических элементов, таких как опросы, которые могут обновляться без перезагрузки страницы. В этом руководстве мы разберём, как создать собственный REST API для опросов в WordPress. Это позволит вам создавать, получать и голосовать в опросах через AJAX-запросы с фронтенда, обеспечивая удобство и интерактивность.
Что такое REST API в WordPress и зачем он нужен для опросов
REST API — это интерфейс взаимодействия с сайтом через протокол HTTP, который позволяет отправлять и получать данные в формате JSON. В WordPress встроен REST API, и его можно расширять своими маршрутами и эндпоинтами.
Для опросов REST API полезен тем, что вы можете управлять опросами и голосами не только из админки, но и с фронтенда, мобильных приложений или сторонних сервисов. Это открывает широкие возможности для кастомных интерфейсов и автоматизации.
Рассмотрим пример, как создать кастомный тип записи для опросов, добавить к нему REST API эндпоинты и обеспечить голосование через AJAX.
Регистрация кастомного типа записи и REST API эндпоинтов
Первым делом регистрируем тип записи poll с поддержкой REST API:
function wppolls_register_poll_cpt() {
$args = [
'public' => true,
'label' => 'Опросы',
'show_in_rest' => true,
'rest_base' => 'polls',
'supports' => ['title', 'editor'],
];
register_post_type('poll', $args);
}
add_action('init', 'wppolls_register_poll_cpt');Теперь создадим собственный REST маршрут для голосования. Для этого используем хук rest_api_init:
function wppolls_register_vote_route() {
register_rest_route('wppolls/v1', '/vote/(?P<poll_id>\d+)', [
'methods' => 'POST',
'callback' => 'wppolls_handle_vote',
'permission_callback' => '__return_true',
'args' => [
'poll_id' => ['required' => true],
'option' => ['required' => true],
],
]);
}
add_action('rest_api_init', 'wppolls_register_vote_route');Обработка голосования в колбэке
Функция wppolls_handle_vote принимает ID опроса и выбранный вариант, сохраняет голос и возвращает актуальную статистику:
function wppolls_handle_vote(WP_REST_Request $request) {
$poll_id = (int)$request->get_param('poll_id');
$option = sanitize_text_field($request->get_param('option'));
// Проверяем, существует ли опрос
$poll = get_post($poll_id);
if (!$poll || $poll->post_type !== 'poll') {
return new WP_Error('invalid_poll', 'Опрос не найден', ['status' => 404]);
}
// Получаем текущие голоса из метаполя
$votes = get_post_meta($poll_id, '_wppolls_votes', true);
if (!$votes || !is_array($votes)) {
$votes = [];
}
// Инкрементируем голос для выбранного варианта
if (!isset($votes[$option])) {
$votes[$option] = 0;
}
$votes[$option]++;
// Сохраняем обновлённые голоса
update_post_meta($poll_id, '_wppolls_votes', $votes);
return [
'success' => true,
'votes' => $votes,
];
}Отправка голосов через AJAX на фронтенде
Чтобы пользователи могли голосовать без перезагрузки, используем JavaScript и fetch API для отправки POST-запроса на наш REST маршрут.
document.addEventListener('DOMContentLoaded', function() {
const pollForm = document.querySelector('.wppolls-form');
if (!pollForm) return;
pollForm.addEventListener('submit', function(e) {
e.preventDefault();
const pollId = pollForm.dataset.pollId;
const option = pollForm.querySelector('input[name="option"]:checked').value;
fetch(`/wp-json/wppolls/v1/vote/${pollId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wppolls.nonce // передать nonce из локализации скрипта
},
body: JSON.stringify({ option: option })
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Ваш голос принят!');
// Здесь можно обновить отображение результатов
} else {
alert('Ошибка при отправке голоса');
}
});
});
});Добавление nonce для безопасности
Для защиты от CSRF стоит использовать nonce. Добавьте в PHP код локализацию скрипта:
function wppolls_enqueue_scripts() {
wp_enqueue_script('wppolls-vote', get_template_directory_uri() . '/js/wppolls-vote.js', ['jquery'], null, true);
wp_localize_script('wppolls-vote', 'wppolls', [
'nonce' => wp_create_nonce('wp_rest'),
]);
}
add_action('wp_enqueue_scripts', 'wppolls_enqueue_scripts');Расширение функционала: интеграция с плагинами и аналитика
Если вы хотите использовать готовые решения, обратите внимание на плагин Quizle от WPShop. Он поддерживает REST API и легко настраивается.
Кроме того, для анализа результатов можно встроить WPRemark, который помогает собирать подробную аналитику ответов и строить отчёты.
Для удобства администрирования и кастомизации REST API можно использовать register_rest_field для добавления дополнительных полей в ответах, например, даты создания голосов, IP-адреса (с осторожностью), или пользовательских меток.
Пример добавления дополнительного поля в REST API
function wppolls_add_votes_count_rest_field() {
register_rest_field('poll', 'total_votes', [
'get_callback' => function($post) {
$votes = get_post_meta($post['id'], '_wppolls_votes', true);
if (!$votes) return 0;
return array_sum($votes);
},
'schema' => [
'type' => 'integer',
'description' => 'Общее количество голосов'
],
]);
}
add_action('rest_api_init', 'wppolls_add_votes_count_rest_field');Вывод опроса с результатами через REST API
Для отображения опроса и результатов можно сделать следующий AJAX-запрос на фронтенде:
fetch(`/wp-json/wp/v2/polls/${pollId}`)
.then(res => res.json())
.then(poll => {
console.log('Опрос:', poll);
console.log('Всего голосов:', poll.total_votes);
// здесь отобразите варианты и прогресс бары
});Таким образом, REST API превращает WordPress в мощную платформу для создания интерактивных опросов с полной поддержкой AJAX и кастомных интерфейсов.
Заключение
Использование REST API для опросов в WordPress — это современный и гибкий способ добавить интерактивность на ваш сайт. Вы получаете контроль над созданием, голосованием и аналитикой опросов без ограничений интерфейса админки. Приведённые примеры помогут быстро начать разработку собственного решения или расширить существующие плагины.