Это вторая часть серии статей о разработке плагина викторины с множественным выбором для WordPress. В первой части мы создали бэкэнд нашего плагина для сбора необходимых данных для хранения в базе данных.
В этой заключительной части мы создадим внешний интерфейс плагина, где пользователи смогут проходить тесты и оценивать свои знания.
Следующие темы будут рассмотрены в этой части завершения нашего плагина:
- Создать шорткод для отображения викторины
- Интеграция jQuery Slider для отображения вопросов и навигации
- Завершение викторины и получение результатов
- Создание таймера викторины
Нам понадобится значительное количество вопросов в бэкэнде, чтобы генерировать случайные тесты. Я надеюсь, что вы уже работали с бэкэндом и сохранили достаточно вопросов для викторин.
Итак, начнем.
Создать шорткод для отображения викторины
Сначала у нас должен быть пост или страница, которая загружает отображаемые элементы теста. Это может быть достигнуто с помощью либо шорткода, либо шаблона страницы. В этом плагине шорткод будет использоваться, чтобы сделать его независимым от темы.
Первоначально шорткод должен выводить доступные категории тестов, чтобы пользователи могли выбрать категорию для создания теста. add_shortcode
код будет добавлен в конструктор с использованием функции add_shortcode
как указано в следующем коде.
1
|
add_shortcode( ‘wpq_show_quiz’, array( $this, ‘wpq_show_quiz’ ) );
|
Теперь давайте посмотрим на реализацию шорткода путем извлечения доступных категорий тестов из базы данных.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
function wpq_show_quiz( $atts ) {
global $post;
$html = ‘<div id=»quiz_panel»><form action=»» method=»POST»>’;
$html .= ‘<div class=»toolbar»>’;
$html .= ‘<div class=»toolbar_item»><select name=»quiz_category» id=»quiz_category»>’;
// Retrive the quiz categories from database
$quiz_categories = get_terms( ‘quiz_categories’, ‘hide_empty=1’ );
foreach ( $quiz_categories as $quiz_category ) {
$html .= ‘<option value=»‘ . $quiz_category->term_id . ‘»>’ .
}
$html .= ‘</select></div>’;
$html .= ‘<input type=»hidden» value=»select_quiz_cat» name=»wpq_action» />’;
$html .= ‘<div class=»toolbar_item»><input type=»submit» value=»Select Quiz Category» /></div>’;
$html .= ‘</form>’;
$html .= ‘<div class=»complete toolbar_item» ><input type=»button» id=»completeQuiz» value=»Get Results» /></div>’;
// Implementation of Form Submission
// Displaying the Quiz as unorderd list
return $html;
}
|
Наш шорткод сгенерирует форму HTML и необходимые элементы управления, используемые для теста. Мы извлекаем список доступных категорий викторины в раскрывающееся поле, чтобы пользователь мог выбрать предпочитаемую категорию. Мы можем использовать функцию get_terms
с hide_empty=1
чтобы получить категории hide_empty=1
в которых есть хотя бы один вопрос.
Скрытое поле wpq_action
используется для проверки значений $_POST
после отправки.
После того, как вы вставите шорткод в страницу или сообщение, вывод будет выглядеть следующим образом.
Теперь пользователь может выбрать категорию теста и отправить форму, чтобы получить тест. Итак, мы собираемся обработать отправку формы внутри короткого кода, чтобы получить выбранную категорию и получить случайные вопросы для викторин.
Следующий код содержит реализацию извлечения вопросов из выбранной категории.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
$questions_str = «»;
if ( isset( $_POST[‘wpq_action’] ) && ‘select_quiz_cat’ == $_POST[‘wpq_action’] ) {
$html .= ‘<div id=»timer» style=»display: block;»></div>’;
$html .= ‘<div style=»clear: both;»></div></div>’;
$quiz_category_id = $_POST[‘quiz_category’];
$quiz_num = get_option( ‘wpq_num_questions’ );
$args = array(
‘post_type’ => ‘wptuts_quiz’,
‘tax_query’ => array(
array(
‘taxonomy’ => ‘quiz_categories’,
‘field’ => ‘id’,
‘terms’ => $quiz_category_id
)
),
‘orderby’ => ‘rand’,
‘post_status’ => ‘publish’,
‘posts_per_page’ => $quiz_num
);
$query = new WP_Query( $args );
$quiz_index = 1;
while ( $query->have_posts() ) : $query->the_post();
// Generating the HTML for Questions
endwhile;
wp_reset_query();
// Embedding Slider
}
else {
$html .= ‘<div id=»timer» style=»display: none;»></div>’;
$html .= ‘<div style=»clear: both;»></div></div>’;
}
|
Данный код должен быть включен в раздел « Реализация формы представления » предыдущего кода.
После отправки формы мы проверяем, содержит ли форма требуемое действие, используя скрытое поле, которое мы создали ранее. Затем мы получаем выбранную категорию викторины из массива $_POST
.
Затем мы запрашиваем в базе данных сообщения wptuts_quiz
с выбранной категорией теста.
Важно установить orderby
как rand
чтобы генерировать случайные вопросы для тестов, которые в противном случае будут генерировать один и тот же набор вопросов каждый раз. Кроме того, обязательно установите posts_per_page
чтобы задать максимальное количество вопросов на каждый заданный тест.
Как только результаты будут сгенерированы, нам нужно добавить вопросы в необходимые элементы HTML, и мы будем реализовывать их в следующем разделе.
Интеграция jQuery Slider для отображения вопросов и навигации
Тесты могут быть созданы в виде экрана, который содержит все вопросы одновременно, или экрана, который содержит один вопрос за один раз с элементами управления навигацией. Я считаю, что последняя техника является фаворитом среди большинства людей. Поэтому мы собираемся отобразить этот тест с одним вопросом и навигацией для перехода к предыдущему и следующему вопросам.
Создание этой функциональности с нуля может быть трудоемкой задачей, а также изобретать велосипед. Слайдер jQuery будет идеальным решением в этой ситуации, и я буду использовать RhinoSlider , так как он мой любимый, поэтому возьмите его с собой.
Внутри загруженной папки вы увидите три папки с именами img , js и css . Скопируйте папки img и css в наш плагин и скопируйте файлы из папки js в существующую папку js, которая есть в нашем плагине для викторины. Теперь мы можем начать с включения необходимых скриптов и стилей для слайдера.
Включая сценарии внешнего интерфейса
В первой части мы создали необходимые скрипты для бэкэнда. В этой части мы собираемся включить необходимые скрипты для RhinoSlider, а также quiz.js для пользовательских функций.
Рассмотрим следующий код для включения скриптов и необходимых данных конфигурации.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
function wpq_frontend_scripts() {
wp_register_script( ‘rhino’, plugins_url( ‘js/rhinoslider-1.05.min.js’, __FILE__ ), array( ‘jquery’ ) );
wp_register_script( ‘rhino-mousewheel’, plugins_url( ‘js/mousewheel.js’, __FILE__ ), array( ‘jquery’ ) );
wp_register_script( ‘rhino-easing’, plugins_url( ‘js/easing.js’, __FILE__ ), array( ‘jquery’ ) );
wp_register_script( ‘quiz’, plugins_url( ‘js/quiz.js’, __FILE__ ), array( ‘jquery’, ‘rhino’, ‘rhino-mousewheel’, ‘rhino-easing’ ) );
wp_enqueue_script( ‘quiz’ );
$quiz_duration = get_option( ‘wpq_duration’ );
$quiz_duration = ( ! empty( $quiz_duration ) ) ?
$config_array = array(
‘ajaxURL’ => admin_url( ‘admin-ajax.php’ ),
‘quizNonce’ => wp_create_nonce( ‘quiz-nonce’ ),
‘quizDuration’ => $quiz_duration,
‘plugin_url’ => $this->plugin_url
);
wp_localize_script( ‘quiz’, ‘quiz’, $config_array );
}
|
Здесь у нас есть три файла JavaScript, используемых для RhinoSlider, и файл quiz.js для пользовательских функций. В предыдущей части мы настраивали продолжительность викторины. Мы можем получить продолжительность, используя функцию get_option
и назначить ее для массива $config
. Кроме того, мы должны включить общие конфигурации в массив конфигурации.
Наконец, мы можем использовать функцию wp_localize_script
чтобы назначить данные конфигурации в файле quiz.js.
Включая стили веб-интерфейса
Точно так же мы можем включить CSS-файлы, необходимые для Rhino Slider, используя следующий код.
1
2
3
4
5
6
7
|
function wpq_frontend_styles() {
wp_register_style( ‘rhino-base’, plugins_url( ‘css/rhinoslider-1.05.css’, __FILE__ ) );
wp_enqueue_style( ‘rhino-base’ );
}
|
Наконец, нам нужно обновить конструктор плагина, чтобы добавить необходимые действия для включения скриптов и стилей, как показано в следующем коде.
1
2
3
|
add_action( ‘wp_enqueue_scripts’, array( $this, ‘wpq_frontend_scripts’ ) );
add_action( ‘wp_enqueue_scripts’, array( $this, ‘wpq_frontend_styles’ ) );
|
Все готово для интеграции слайдера с вопросами в шорткод, который мы создали ранее. Давайте двигаться вперед.
Встраивание ползунка в шорткод
В настоящее время у нас есть два комментария внутри функции шорткода, упоминающие «Генерация HTML для вопросов» и «Слайдер внедрения». Эти разделы должны быть обновлены с соответствующим кодом для создания слайдера. Сначала нам нужно обновить цикл while следующим образом.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
while ( $query->have_posts() ) : $query->the_post();
$question_id = get_the_ID();
$question = the_title( », », FALSE ) .
$question_answers = json_decode( get_post_meta( $question_id, ‘_question_answers’, true ) );
$questions_str .= ‘<li>’;
$questions_str .= ‘<div class=»ques_title»><span class=»quiz_num»>’ .
$questions_str .= ‘<div class=»ques_answers» data-quiz-id=»‘ . $question_id . ‘»>’;
$quiestion_index = 1;
foreach ( $question_answers as $key => $value ) {
if ( » != $value ) {
$questions_str .= $quiestion_index .
}
$quiestion_index++;
}
$questions_str .= ‘</div></li>’;
$quiz_index++;
endwhile;
|
Код Объяснение
- Внутри цикла сначала мы получаем вопрос, объединяя поля заголовка и содержимого для вопросов.
- Затем мы получаем ответы на каждый вопрос с помощью функции
get_post_meta
. - Внутри цикла
foreach
все ответы будут назначены переключателям с необходимыми значениями. - Необходимые элементы списка будут назначены внутри цикла, включая атрибуты данных HTML, которые пригодятся в следующем разделе.
- Конечным результатом цикла while будет строковая переменная, которая содержит список вопросов и их ответов, встроенных в HTML.
Далее нам нужно создать контейнеры для слайдера в разделе, который прокомментирован как «Внедрение слайдера». Следующий код содержит HTML-код для создания контейнеров.
1
2
3
4
5
6
7
|
$html .= ‘<ul id=»slider»>’ .
$html .= ‘<li id=»quiz_result_page»><div class=»ques_title»>Quiz Results <span id=»score»>
$html .= ‘<div id=»quiz_result»></div>’;
$html .= ‘</li></ul></div>’;
|
В качестве контейнера для Rhino Slider мы будем использовать неупорядоченный список с именем slider
. Изначально мы включаем набор вопросов и ответов, сгенерированных внутри цикла, используя $questions_str
. Он будет содержать коллекцию элементов списка.
Затем мы должны вручную создать еще один элемент списка, чтобы показать результаты теста и оценки.
Теперь все данные и слайды, необходимые для приложения викторины, настроены. Мы можем инициализировать Rhino Slider в quiz.js, чтобы увидеть тест в действии.
jQuery (документ) .ready (function ($) { $ ('# slider'). rhinoslider ({ controlMousewheel: ложь, controlsPlayPause: false, showBullets: «всегда», showControls: 'всегда' }); });
Я использовал несколько пользовательских стилей CSS для улучшения внешнего вида. Вы можете найти все модифицированные CSS в разделе wp_quiz файла rhinoslider-1.05.css . Теперь у вас должно быть что-то вроде следующего изображения.
Завершение викторины и получение результатов
Как только тест загружен, вы можете использовать элементы навигации для перемещения между вопросами и выбора ответов. Вы должны нажать кнопку «Получить результаты», как только ответы на все вопросы. Теперь нам нужно создать результаты теста, используя запрос AJAX.
Давайте реализуем код jQuery для выполнения запроса AJAX.
$ ("# completeQuiz"). click (function () { wpq_quiz_results (); }); var wpq_quiz_results = function () { var selected_answers = {}; $ (". Ques_answers"). each (function () { var question_id = $ (this) .attr ("data-quiz-id"); var selected_answer = $ (this) .find ('input [type = radio]: флажок'); if (selected_answer.length! = 0) { var selected_answer = $ (selected_answer) .val (); selected_answers ["qid _" + question_id] = selected_answer; } еще { selected_answers ["qid _" + question_id] = ''; } }); // AJAX-запрос };
После нажатия кнопки «Получить результаты» мы вызываем функцию wpq_quiz_results
используя jQuery. Каждый вопрос был добавлен в слайдер с помощью специального класса CSS под названием ques_answers
.
ques_answers
каждый элемент с ques_answers
класса ques_answers
, мы получаем идентификатор вопроса, используя атрибут data-quiz-id
HTML с именем data-quiz-id
а выбранный переключатель — с помощью jQuery.
Наконец, мы назначаем все вопросы и выбранные ответы в массив с именем selected_answers
для передачи в запрос AJAX.
Взгляните на следующий код для реализации запроса AJAX.
$ .post (quiz.ajaxURL, { действие: "get_quiz_results", nonce: quiz.quizNonce, данные: selected_answers, }, функция (данные) { // AJAX код обработки результата }, "JSON");
Сначала мы создаем AJAX-запрос, используя данные конфигурации, назначенные функцией wpq_frontend_scripts
. Список ответов, сгенерированный в предыдущем разделе, будет отправлен в качестве параметра данных. Перед обработкой результата мы должны взглянуть на реализацию кода на стороне сервера в следующем разделе.
Создание обработчика AJAX на стороне сервера
Сначала мы должны обновить конструктор действиями, необходимыми для использования AJAX как для зарегистрированных пользователей, так и для обычных пользователей, как показано в следующем коде.
1
2
3
|
add_action( ‘wp_ajax_nopriv_get_quiz_results’, array( $this, ‘get_quiz_results’ ) );
add_action( ‘wp_ajax_get_quiz_results’, array( $this, ‘get_quiz_results’ ) );
|
Затем мы можем перейти к реализации функции get_quiz_results
как показано в следующем коде.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
function get_quiz_results() {
$score = 0;
$question_answers = $_POST[«data»];
$question_results = array();
foreach ( $question_answers as $ques_id => $answer ) {
$question_id = trim( str_replace( ‘qid_’, », $ques_id ) ) .
$correct_answer = get_post_meta( $question_id, ‘_question_correct_answer’, true );
if ( $answer == $correct_answer ) {
$score++;
$question_results[«$question_id»] = array( «answer» => $answer, «correct_answer» => $correct_answer, «mark» => «correct» );
}
else {
$question_results[«$question_id»] = array( «answer» => $answer, «correct_answer» => $correct_answer, «mark» => «incorrect» );
}
}
$total_questions = count( $question_answers );
$quiz_result_data = array(
«total_questions» => $total_questions,
«score» => $score,
«result» => $question_results
);
echo json_encode( $quiz_result_data );
exit;
}
|
Код Объяснение
- Выбранные ответы на все вопросы будут получены с использованием параметра data внутри массива
$_POST
. - Затем мы получаем идентификатор вопроса для каждого вопроса, заменяя префикс
qid_
. - Далее мы получаем правильный ответ на каждый вопрос из базы данных, используя функцию
get_post_meta
. - Затем мы проверяем, соответствует ли предоставленный ответ правильному ответу, и создаем
$question_results
на основе состояния результата. - При проверке ответов нам нужно обновить оценку теста, используя переменную
$score
. - Наконец, мы присваиваем результаты и оценки
$quiz_result_data
массиву$quiz_result_data
который будет отправлен в качестве ответа.
До сих пор мы создавали запрос AJAX и реализовывали ответ на стороне сервера. В следующем разделе мы собираемся завершить процесс генерации результатов теста, обрабатывая ответ AJAX.
Обработка данных ответа AJAX
В части обработки ответов у нас довольно много задач, включая отображение результатов и результатов тестов. Итак, я собираюсь разделить код на несколько разделов, чтобы пояснить это объяснение. Рассмотрим следующий код, который содержит полный запрос AJAX.
$ .Post ( quiz.ajaxURL, { действие: 'get_quiz_results', nonce: quiz.quizNonce, данные: selected_answers }, функция (данные) { // Секция 1 var total_questions = data.total_questions; $ ('# slider'). data ('rhinoslider'). next ($ ('# rhino-item' + total_questions)); $ ('# score'). html (data.score + '/' + total_questions); // Раздел 2 var result_html = '<таблица>'; result_html + = '<tr> <td> Question </ td> <td> Ответ </ td> <td> Правильный ответ </ td> <td> Result </ td> </ tr>'; var quiz_index = 1; $ .each (data.result, функция (ключ, вопрос) { result_html + = '<tr> <td>' + quiz_index + '</ td> <td>' + Ques.answer + '</ td> <td>' + Ques.correct_answer + '</ td>'; result_html + = '<td> <img src = "' + quiz.plugin_url + 'img /' + Ques.mark + '.png" /> </ td> </ tr>'; quiz_index ++; }); result_html + = '<tr> <td> & nbsp; </ td> <td> </ td> <td> </ td>'; result_html + = '<td> </ td> </ tr>'; // Раздел 3 $ ( '# Quiz_result') родитель () CSS ( 'переполнение-у', 'свитка')..; $ ( '# Quiz_result') HTML (result_html). $ ( '# Таймер') скрыть (). }, 'JSON' );
Пояснение к разделу 1
Сначала мы получаем общие вопросы теста из ответа, полученного с сервера. Затем мы используем next
функцию Rhino Slider, чтобы перенаправить пользователя на слайд с результатами. Затем мы устанавливаем оценку пользователя с помощью общих вопросов внутри контейнера #score
.
Пояснение к разделу 2
Начальная часть этого кода генерирует таблицу HTML с необходимыми заголовками для отображения результатов. Затем мы присваиваем вопросы таблице внутри each
цикла jQuery. Мы использовали два изображения, чтобы отобразить статус вопроса об успехе или неудаче.
Пояснение к разделу 3
Первоначально мы должны разрешить прокрутку на странице результатов, так как она может быть довольно длинной для тестов с большим количеством вопросов. Атрибут CSS overflow-y
используется для разрешения прокрутки. Наконец, мы устанавливаем таблицу результатов #quiz_result
контейнер #quiz_result
и скрываем таймер, который мы будем реализовывать в следующем разделе.
После завершения теста ваш экран должен выглядеть примерно так, как показано на следующем рисунке.
Создание таймера викторины
Обычно любой экзамен или викторина имеет заранее определенные временные рамки. Поэтому мы будем использовать продолжительность, которую мы настроили на странице настроек нашего плагина, чтобы сгенерировать таймер викторины. Мы уже настроили таймер, чтобы он был скрыт при начальной загрузке страницы и отображался при отправке формы в шорткоде.
Давайте сосредоточимся на динамически меняющемся таймере с использованием кода jQuery, как показано ниже.
var duration = quiz.quizDuration * 60; $ (документ) .ready (функция ($) { SetTimeout ( "startPuzzleCount ()", 1000); }); var startPuzzleCount = function () { duration--; $ ('# timer'). html (продолжительность + "оставшиеся секунды"); if (duration == '0') { $ ('# timer'). html ("Время истекло"); wpq_quiz_results (); возвращение; } SetTimeout ( "startPuzzleCount ()", 1000); };
Продолжительность wp_localize_script
определяется с использованием массива конфигурации, переданного с wp_localize_script
функции wp_localize_script
. Длительность затем конвертируется в секунды путем умножения на 60
.
Затем мы создаем функцию setTimeout
для запуска таймера. Внутри функции мы сокращаем продолжительность на 1
и присваиваем контейнеру #timer
. Когда время уменьшается до нуля, мы вызываем функцию wpq_quiz_results
чтобы автоматически завершить тест и сгенерировать результаты.
Наконец, мы вызываем функцию setTimeout
для обновления оставшегося времени. Мы завершили реализацию таймера, и ваш тест должен выглядеть следующим образом с таймером.
Заворачивать
В этой серии из двух частей мы разработали простой и полный плагин с несколькими вариантами ответов для WordPress. Вы можете расширить функциональность этого плагина в соответствии с требованиями вашего приложения. Я предлагаю вам улучшить плагин, попробовав следующее:
- Создайте способ присваивать вопросы викторинам вместо создания случайных викторин.
- Сохраните результаты теста для зарегистрированных пользователей.
- Создать конкурс викторины между пользователями.
Дайте мне знать ваши предложения и как это происходит с процессом расширения плагина.
С нетерпением жду Вашего ответа.