В современных проектах на WordPress всё чаще требуется реализовать не просто опросы или квизы, а динамические интерактивные квизы с возможностью фильтрации вопросов и ответов по категориям, тегам или другим параметрам. В этой статье мы подробно разберём, как создать такой квиз своими силами, используя PHP, AJAX и возможности WordPress. Это позволит сделать опросник максимально гибким и удобным для пользователей.
Почему динамический квиз с фильтрами важен для сайта
Статичные квизы часто ограничены фиксированным набором вопросов. Если у вас большой контент, например, образовательный ресурс или сайт с тестами по разным темам, пользователю важно выбирать лишь релевантные вопросы. Фильтрация помогает:
- Улучшить UX за счёт показа только нужного контента.
- Сократить время на прохождение опроса.
- Собрать более точные данные для аналитики.
WordPress даёт множество инструментов для реализации таких функций, в том числе пользовательские типы записей и AJAX-запросы.
Создание пользовательского типа записи для вопросов
Первый шаг — зарегистрировать пользовательский тип записи wpquiz_question, чтобы хранить вопросы отдельно от стандартных постов. Это упростит организацию и фильтрацию.
function wpquiz_register_post_type_question() {
$labels = array(
'name' => 'Вопросы квиза',
'singular_name' => 'Вопрос',
'add_new' => 'Добавить вопрос',
'add_new_item' => 'Добавить новый вопрос',
'edit_item' => 'Редактировать вопрос',
'new_item' => 'Новый вопрос',
'view_item' => 'Просмотреть вопрос',
'search_items' => 'Поиск вопросов',
'not_found' => 'Вопросы не найдены',
'not_found_in_trash' => 'Вопросы не найдены в корзине',
);
$args = array(
'labels' => $labels,
'public' => false,
'show_ui' => true,
'supports' => array('title', 'editor'),
'has_archive' => false,
'rewrite' => false,
);
register_post_type('wpquiz_question', $args);
}
add_action('init', 'wpquiz_register_post_type_question');
В дальнейшем для фильтрации можно использовать таксономии. Например, создадим таксономию wpquiz_category для группировки вопросов.
Добавление таксономии для фильтрации вопросов
Таксономии помогут структурировать вопросы по темам или сложности. Вот пример регистрации таксономии:
function wpquiz_register_taxonomy_category() {
$labels = array(
'name' => 'Категории вопросов',
'singular_name' => 'Категория вопроса',
'search_items' => 'Поиск категорий',
'all_items' => 'Все категории',
'edit_item' => 'Редактировать категорию',
'add_new_item' => 'Добавить категорию',
'new_item_name' => 'Название новой категории',
'menu_name' => 'Категории',
);
$args = array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
);
register_taxonomy('wpquiz_category', array('wpquiz_question'), $args);
}
add_action('init', 'wpquiz_register_taxonomy_category');
Теперь при добавлении вопросов вы можете присваивать их к определённым категориям, что даст возможность фильтровать вопросы по этим категориям.
Вывод и фильтрация вопросов на фронтенде с помощью AJAX
Чтобы пользователь мог выбирать категории и получать вопросы без перезагрузки страницы, воспользуемся AJAX.
Для начала создадим форму выбора категорий и контейнер для вопросов:
<select id="wpquiz_category_select">
<option value="">Выберите категорию</option>
<?php
$categories = get_terms(array('taxonomy' => 'wpquiz_category', 'hide_empty' => false));
foreach ($categories as $category) {
echo '<option value="' . esc_attr($category->term_id) . '">' . esc_html($category->name) . '</option>';
}
?>
</select>
<div id="wpquiz_questions_container"></div>
Далее добавим JavaScript для обработки выбора и отправки AJAX-запроса:
jQuery(document).ready(function($) {
$('#wpquiz_category_select').on('change', function() {
var category_id = $(this).val();
$.ajax({
url: wpquiz_ajax_object.ajax_url,
method: 'POST',
data: {
action: 'wpquiz_load_questions',
category: category_id,
},
beforeSend: function() {
$('#wpquiz_questions_container').html('Загрузка вопросов...');
},
success: function(response) {
$('#wpquiz_questions_container').html(response);
},
error: function() {
$('#wpquiz_questions_container').html('Ошибка загрузки вопросов.');
}
});
});
});
Не забудьте локализовать скрипт в PHP, чтобы передать URL ajax:
function wpquiz_enqueue_scripts() {
wp_enqueue_script('wpquiz-ajax-script', get_template_directory_uri() . '/js/wpquiz-ajax.js', array('jquery'), null, true);
wp_localize_script('wpquiz-ajax-script', 'wpquiz_ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php')
));
}
add_action('wp_enqueue_scripts', 'wpquiz_enqueue_scripts');
Обработка AJAX-запроса и вывод вопросов
Теперь добавим PHP-функцию, которая будет обрабатывать запрос и возвращать HTML с вопросами из выбранной категории.
function wpquiz_load_questions_ajax() {
$category_id = intval($_POST['category']);
$args = array(
'post_type' => 'wpquiz_question',
'posts_per_page' => -1,
);
if ($category_id) {
$args['tax_query'] = array(
array(
'taxonomy' => 'wpquiz_category',
'field' => 'term_id',
'terms' => $category_id,
)
);
}
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul class="wpquiz-questions-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<li><strong>' . get_the_title() . '</strong><br>' . get_the_content() . '</li>';
}
echo '</ul>';
} else {
echo 'Вопросы не найдены.';
}
wp_reset_postdata();
wp_die();
}
add_action('wp_ajax_wpquiz_load_questions', 'wpquiz_load_questions_ajax');
add_action('wp_ajax_nopriv_wpquiz_load_questions', 'wpquiz_load_questions_ajax');
Расширение: добавление вариантов ответов и подсчёт результатов
Для полноценного квиза необходимо хранить варианты ответов и логику подсчёта. Для этого можно использовать метаполя или отдельный пользовательский тип записи.
В простом варианте можно добавить поле с вариантами через Custom Fields или использовать плагин Advanced Custom Fields (ACF). Пример добавления вариантов с помощью метаполей:
add_action('add_meta_boxes', 'wpquiz_add_answers_metabox');
function wpquiz_add_answers_metabox() {
add_meta_box('wpquiz_answers', 'Варианты ответов', 'wpquiz_answers_metabox_callback', 'wpquiz_question', 'normal', 'default');
}
function wpquiz_answers_metabox_callback($post) {
$answers = get_post_meta($post->ID, '_wpquiz_answers', true);
if (!is_array($answers)) {
$answers = array('', '', '', '');
}
for ($i = 0; $i < 4; $i++) {
echo '<p><label>Ответ ' . ($i + 1) . ': </label>';
echo '<input type="text" name="wpquiz_answers[' . $i . ']" value="' . esc_attr($answers[$i]) . '" style="width:100%;" /></p>';
}
wp_nonce_field('wpquiz_save_answers', 'wpquiz_answers_nonce');
}
add_action('save_post', 'wpquiz_save_answers');
function wpquiz_save_answers($post_id) {
if (!isset($_POST['wpquiz_answers_nonce']) || !wp_verify_nonce($_POST['wpquiz_answers_nonce'], 'wpquiz_save_answers')) {
return;
}
if (isset($_POST['wpquiz_answers']) && is_array($_POST['wpquiz_answers'])) {
$answers = array_map('sanitize_text_field', $_POST['wpquiz_answers']);
update_post_meta($post_id, '_wpquiz_answers', $answers);
}
}
Далее при выводе вопросов можно показывать варианты ответов с радио-кнопками, а на стороне JavaScript реализовать подсчёт и вывод результатов.
Рекомендации по плагинам для расширения функционала
Если вы хотите избежать рутинного программирования, посмотрите на плагины, которые помогут создать и управлять квизами с расширенными функциями, включая фильтры:
- Quizle — удобный плагин для создания интерактивных квизов с продвинутыми настройками и фильтрацией.
- WPRemark — плагин для отзывов и опросов, который можно адаптировать под квизы с различными условиями.
Использование готовых решений ускорит запуск проекта, а описанный вручную подход даёт полный контроль и возможность кастомизации.