Integración de pruebas de opción múltiple en WordPress - Creación del Backend
Spanish (Español) translation by CYC (you can also view the original English article)
Las preguntas de opción múltiple son algo que la mayoría de nosotros hemos enfrentado al menos una vez en nuestra vida. Los amamos porque podemos proporcionar respuestas correctas pensando lógicamente en las posibilidades proporcionadas, incluso si no sabemos exactamente la respuesta correcta. También responder toma menos tiempo, lo que lo hace tan popular.
Crear una prueba de opción múltiple en WordPress puede ser una tarea muy emocionante y rentable. Puede usarlo en su blog personal para atraer más visitantes, o puede crear una sección premium con exámenes avanzados, o puede crear exámenes centrados en los exámenes de certificación más populares. Existen numerosas posibilidades para hacerlo rentable.
Este complemento no lo llevará a crear cuestionarios para construir un negocio, pero tenemos que comenzar en algún lugar para llegar a donde queremos ir. Por lo tanto, este sería un buen comienzo para crear pruebas y obtener ganancias con él.
Entonces empecemos.
Funcionalidad del Plugin
Primero debemos reunir los requisitos del complemento antes de ir al diseño o implementación. Básicamente, deberíamos ser capaces de crear pruebas de opción múltiple y permitir a los usuarios tomar las pruebas y obtener resultados.
Así que echemos un vistazo a los requisitos y componentes detallados de nuestro complemento:
- El complemento debe tener un backend donde podamos insertar preguntas y respuestas de forma dinámica. También es ideal tener categorías de prueba para agrupar pruebas en secciones específicas.
- El administrador del sitio debe poder configurar los cuestionarios a través de una página de configuración.
- Los usuarios deben tener una interfaz en la que puedan realizar una prueba.
- Una vez que se completa una prueba, los usuarios deben poder obtener las puntuaciones y los resultados.
Este tutorial se construirá como una serie de dos partes, donde desarrollaremos el backend del complemento en la primera parte, seguido por el frontend del complemento en la segunda parte.
Planificación del complemento Backend
En esta parte, nos centraremos en desarrollar el backend del complemento, donde desarrollamos los datos necesarios para las pruebas.
Por lo general, hay una lista de pruebas, cada una de las cuales contiene una lista específica de preguntas. Con este plugin no vamos a crear pruebas. Crearemos preguntas individuales y las asignaremos dinámicamente a las pruebas cuando se soliciten.
Ahora podemos tomarnos el tiempo para identificar los componentes necesarios para implementar el backend como se indica en la siguiente sección.
- Las preguntas deben ser creadas en el backend con las respuestas. Un tipo de mensaje personalizado será la mejor solución para implementar las preguntas. Así que vamos a utilizar un tipo de mensaje personalizado llamado wptuts_quiz .
- Cada pregunta debe tener múltiples respuestas y una respuesta correcta. Los campos para las respuestas se crearán dentro de un cuadro de meta en la pantalla de creación de publicación personalizada.
- Las preguntas se clasificarán en varios subtemas, por lo tanto, necesitamos una taxonomía personalizada llamada quiz_categories para el tipo de publicación wptuts_quiz.
- Entonces necesitamos validar el proceso de creación de la pregunta. Utilizaremos las validaciones de jQuery del lado del cliente cuando sea necesario en la creación de la pregunta.
- Finalmente, necesitamos una página de configuración de complementos para almacenar la cantidad de preguntas por cuestionario y la duración de un cuestionario.
Habiendo identificado los componentes necesarios de WordPress, podemos pasar directamente a la implementación del backend del complemento de prueba.
Creando preguntas
El proceso de creación de preguntas consta de cuatro secciones principales: definición del tipo de publicación personalizada, definición de taxonomía personalizada, asignación de campos personalizados y validaciones. Cada una de estas secciones se analizará con el código detallado en las próximas secciones.
1. Creando el tipo de mensaje personalizado de preguntas
Necesitamos la forma más básica de tipo de publicación personalizada para preguntas sin ninguna configuración avanzada. Lo único que debemos tener en cuenta es la selección del campo correcto para la pregunta.
La pantalla de creación de publicación predeterminada contiene dos campos para el título y el contenido. Puede elegir cualquiera de esos campos para la pregunta. Voy a elegir la concatenación de los campos de título y contenido considerando las posibilidades avanzadas.
Vamos a crear un complemento orientado a objetos en lugar de un complemento funcional, por lo que todas las acciones necesarias, códigos cortos e inicializaciones se realizarán dentro del constructor. El siguiente contiene el código para implementar el tipo de publicación wptuts_quiz .
1 |
class WP_Quiz { |
2 |
|
3 |
public $plugin_url; |
4 |
|
5 |
public function __construct() { |
6 |
|
7 |
$this->plugin_url = plugin_dir_url( __FILE__ ); |
8 |
|
9 |
add_action( 'init', array( $this, 'wpq_add_custom_post_type' ) ); |
10 |
|
11 |
}
|
12 |
|
13 |
public function wpq_add_custom_post_type() { |
14 |
|
15 |
$labels = array( |
16 |
'name' => _x( 'Questions', 'wptuts_quiz' ), |
17 |
'menu_name' => _x( 'WPTuts Quiz', 'wptuts_quiz' ), |
18 |
'add_new' => _x( 'Add New ', 'wptuts_quiz' ), |
19 |
'add_new_item' => _x( 'Add New Question', 'wptuts_quiz' ), |
20 |
'new_item' => _x( 'New Question', 'wptuts_quiz' ), |
21 |
'all_items' => _x( 'All Questions', 'wptuts_quiz' ), |
22 |
'edit_item' => _x( 'Edit Question', 'wptuts_quiz' ), |
23 |
'view_item' => _x( 'View Question', 'wptuts_quiz' ), |
24 |
'search_items' => _x( 'Search Questions', 'wptuts_quiz' ), |
25 |
'not_found' => _x( 'No Questions Found', 'wptuts_quiz' ), |
26 |
);
|
27 |
|
28 |
$args = array( |
29 |
'labels' => $labels, |
30 |
'hierarchical' => true, |
31 |
'description' => 'WP Tuts Quiz', |
32 |
'supports' => array( 'title', 'editor' ), |
33 |
'public' => true, |
34 |
'show_ui' => true, |
35 |
'show_in_menu' => true, |
36 |
'show_in_nav_menus' => true, |
37 |
'publicly_queryable' => true, |
38 |
'exclude_from_search' => false, |
39 |
'has_archive' => true, |
40 |
'query_var' => true, |
41 |
'can_export' => true, |
42 |
'rewrite' => true, |
43 |
'capability_type' => 'post' |
44 |
);
|
45 |
|
46 |
register_post_type( 'wptuts_quiz', $args ); |
47 |
}
|
48 |
}
|
Hemos habilitado los campos de título y editor en el tipo de publicación personalizada para usar en la pregunta. Dado que las funciones están ubicadas dentro de una clase, tenemos que usar $ this en nuestras acciones, filtros y códigos cortos de WordPress para llamar a las funciones.
Aparte de eso, todos los parámetros mencionados en el código se inicializan con sus valores predeterminados.
2. Creando las categorías de preguntas
Para agrupar las preguntas en secciones específicas, necesitamos algo similar a las categorías de WordPress predeterminadas. Por lo tanto, utilizaremos una taxonomía personalizada llamada quiz_categories . Necesitamos llamar a la función de generación de taxonomía personalizada en la acción init como lo hicimos anteriormente. Por lo tanto, el constructor de nuestra clase de complemento debe actualizarse con el siguiente código.
1 |
add_action( 'init', array( $this,'wpq_create_taxonomies' ), 0 ); |
Luego podemos implementar la función wpq_create_taxonomies en el tipo de publicación wptuts_quiz como se muestra en el siguiente código.
1 |
function wpq_create_taxonomies() { |
2 |
|
3 |
register_taxonomy( |
4 |
'quiz_categories', |
5 |
'wptuts_quiz', |
6 |
array( |
7 |
'labels' => array( |
8 |
'name' => 'Quiz Category', |
9 |
'add_new_item' => 'Add New Quiz Category', |
10 |
'new_item_name' => "New Quiz Category" |
11 |
),
|
12 |
'show_ui' => true, |
13 |
'show_tagcloud' => false, |
14 |
'hierarchical' => true |
15 |
)
|
16 |
);
|
17 |
|
18 |
}
|
He utilizado los parámetros de opción predeterminados para crear esta taxonomía personalizada. Una vez que se active el complemento, su tipo de publicación personalizada y taxonomía se mostrarán como se muestra en la siguiente pantalla.
3. Creando las respuestas a las preguntas
A continuación, tenemos que crear múltiples respuestas para cada pregunta. En este complemento, el número máximo de respuestas por pregunta individual se limitará a cinco.
Puede asignar dinámicamente 1-5 respuestas para cualquier pregunta. También debemos especificar la respuesta correcta de la lista de respuestas provista. Dado que estos datos están asociados con nuestras preguntas, podemos usar un meta box con campos personalizados para generar los campos necesarios.
Como de costumbre, necesitamos actualizar el constructor con el siguiente código:
1 |
add_action( 'add_meta_boxes', array( $this,'wpq_quiz_meta_boxes' ) ); |
Considere el siguiente código para la implementación de meta cajas con campos de respuestas.
1 |
function wpq_quiz_meta_boxes() { |
2 |
add_meta_box( 'quiz-answers-info', 'Quiz Answers Info', array( $this, 'wpq_quiz_answers_info' ), 'wptuts_quiz', 'normal', 'high' ); |
3 |
}
|
4 |
|
5 |
function wpq_quiz_answers_info() { |
6 |
|
7 |
global $post; |
8 |
|
9 |
$question_answers = get_post_meta( $post->ID, '_question_answers', true ); |
10 |
|
11 |
$question_answers = ( $question_answers == '' ) ? array( '', '', '', '', '' ) : json_decode( $question_answers ); |
12 |
|
13 |
$question_correct_answer = trim( get_post_meta( $post->ID, '_question_correct_answer', true ) ); |
14 |
|
15 |
$html = '<input type="hidden" name="question_box_nonce" value="' . wp_create_nonce( basename( __FILE__ ) ) . '" />'; |
16 |
|
17 |
$html .= '<table class="form-table">'; |
18 |
|
19 |
$html .= '<tr><th style=""><label for="Price">Correct Answer</label></th><td><select class="widefat" name="correct_answer" id="correct_answer" >'; |
20 |
|
21 |
for ( $i = 1; $i <= 5; $i++ ) { |
22 |
|
23 |
if ( $question_correct_answer == $i ) { |
24 |
$html .= '<option value="' . $i . '" selected >Answer ' . $i . '</option>'; |
25 |
}
|
26 |
else { |
27 |
$html .= '<option value="' . $i . '">Answer ' . $i . '</option>'; |
28 |
}
|
29 |
|
30 |
}
|
31 |
|
32 |
$html .= '</select></td></tr>'; |
33 |
|
34 |
$index = 1; |
35 |
|
36 |
foreach ( $question_answers as $question_answer ) { |
37 |
|
38 |
$html .= '<tr><th style=""><label for="Price">Answer ' . $index . '</label></th>'; |
39 |
$html .= '<td><textarea class="widefat" name="quiz_answer[]" id="quiz_answer' . $index . '" >' . esc_textarea( trim( $question_answer ) ) . '</textarea></td></tr>'; |
40 |
|
41 |
$index++; |
42 |
|
43 |
}
|
44 |
|
45 |
$html .= '</tr>'; |
46 |
|
47 |
$html .= '</table>'; |
48 |
|
49 |
echo $html; |
50 |
}
|
4. Explicación del código
- Las respuestas de cada pregunta se almacenarán en una cadena codificada en JSON en la tabla post_meta con la clave _question_answers . Entonces accedemos a este campo usando la función get_post_meta para obtener los valores actuales.
- Luego obtenemos la respuesta correcta de la pregunta utilizando un método similar. La respuesta correcta se almacenará como una cadena en la tabla post_meta con la clave _question_correct_answer .
- Finalmente, creamos el formulario HTML, que contiene la respuesta correcta como un cuadro desplegable y las posibles respuestas como cinco campos de área de texto.
- Todos los valores existentes recuperados utilizando la función get_post_meta se asignarán a los campos respectivos.
Debería ver algo similar a la siguiente pantalla, una vez que haya creado el meta box.



Ahora tenemos todos los datos necesarios para nuestro complemento de generación de cuestionarios. El siguiente paso es guardar los datos de la pregunta en la base de datos.
Pero necesitamos algunas validaciones antes de eso. Así que vamos a pasar a las validaciones.
Validación de la creación de preguntas
No tenemos reglas de validación complejas en esta etapa del proceso de creación de la pregunta. Por lo tanto, vamos a utilizar validaciones jQuery del lado del cliente antes del envío.
Aquí necesitamos que la acción admin_enqueue_scripts se incluya en el constructor de nuestro complemento.
Así que actualice el constructor con el siguiente código antes de comenzar.
1 |
add_action( 'admin_enqueue_scripts', array( $this, 'wpq_admin_scripts' ) ); |
Ahora mire el siguiente código para incluir los archivos de script necesarios para la validación.
1 |
function wpq_admin_scripts() { |
2 |
|
3 |
wp_register_script( 'quiz-admin', plugins_url( 'js/quiz.js', __FILE__ ), array( 'jquery' ) ); |
4 |
|
5 |
wp_enqueue_script( 'quiz-admin' ); |
6 |
|
7 |
}
|
Usando wp_register_script y wp_enqueue_script , tenemos un archivo JS específico de plugin llamado quiz.js para manejar las validaciones. La validación se realizará utilizando la biblioteca jQuery y, por lo tanto, hemos establecido la biblioteca jQuery incorporada como una dependencia para nuestro JavaScript específico del complemento.
Habiendo incluido los scripts, implementemos las validaciones reales en el archivo quiz.js como se muestra en el siguiente código.
1 |
jQuery(document).ready(function($) { |
2 |
|
3 |
$("#post-body-content").prepend('<div id="quiz_error" class="error" style="display:none" ></div>'); |
4 |
|
5 |
$('#post').submit(function() { |
6 |
|
7 |
if ( $("#post_type").val() =='wptuts_quiz' ) { |
8 |
|
9 |
return wpq_validate_quizes(); |
10 |
|
11 |
}
|
12 |
|
13 |
});
|
14 |
|
15 |
});
|
Primero, asignamos un elemento div vacío a la pantalla de creación de publicación para mostrar cualquier error. Luego podemos llamar a una función JS personalizada en la acción de publicación posterior al verificar el tipo de publicación correcto usando el valor del campo oculto #post_type .
El siguiente código contiene la implementación de la función wpq_validate_quizes .
1 |
var wpq_validate_quizes = function() { |
2 |
|
3 |
var err = 0; |
4 |
|
5 |
$("#quiz_error").html(""); |
6 |
|
7 |
$("#quiz_error").hide(); |
8 |
|
9 |
if ( $("#title").val() == '' ) { |
10 |
|
11 |
$("#quiz_error").append("<p>Please enter Question Title.</p>"); |
12 |
|
13 |
err++; |
14 |
|
15 |
}
|
16 |
|
17 |
var correct_answer = $("#correct_answer").val(); |
18 |
|
19 |
if ( $("#quiz_answer"+correct_answer).val() == "" ) { |
20 |
|
21 |
$("#quiz_error").append("<p>Correct answer cannot be empty.</p>"); |
22 |
|
23 |
err++; |
24 |
|
25 |
}
|
26 |
|
27 |
if ( err > 0 ) { |
28 |
|
29 |
$("#publish").removeClass("button-primary-disabled"); |
30 |
|
31 |
$(".spinner").hide(); |
32 |
|
33 |
$("#quiz_error").show(); |
34 |
|
35 |
return false; |
36 |
|
37 |
}
|
38 |
else { |
39 |
|
40 |
return true; |
41 |
|
42 |
}
|
43 |
};
|
Explicación del Código
- Primero tenemos que ocultar el contenedor de errores y establecer su mensaje de error actual en vacío.
- Luego verificamos si el título existe, ya que el título es obligatorio para las preguntas.
- A continuación, obtenemos la respuesta correcta seleccionada y verificamos si el campo de respuesta relacionado con la respuesta correcta está vacío.
- Cuando se generan los errores de validación, mostramos los errores en el contenedor de errores especificado y evitamos el envío de la publicación.
La siguiente imagen muestra la pantalla de creación de publicación con mensajes de validación personalizados.



Una vez que el formulario se haya validado correctamente sin errores, podemos pasar a guardar los detalles de la pregunta en la base de datos.
Detalles de la pregunta de ahorro
WordPress proporciona una acción llamada save_post , que se ejecutará justo después de la creación posterior. Podemos definir una función personalizada en la acción save_post para guardar los detalles del campo personalizado en la base de datos.
Como de costumbre, actualice el constructor con el código de acción save_post .
1 |
add_action( 'save_post', array( $this, 'wpq_save_quizes' ) ); |
La implementación de la función wpq_save_quizes se proporciona en el siguiente código.
1 |
function wpq_save_quizes( $post_id ) { |
2 |
|
3 |
if ( ! wp_verify_nonce( $_POST['question_box_nonce'], basename( __FILE__ ) ) ) { |
4 |
|
5 |
return $post_id; |
6 |
|
7 |
}
|
8 |
|
9 |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { |
10 |
|
11 |
return $post_id; |
12 |
|
13 |
}
|
14 |
|
15 |
if ( 'wptuts_quiz' == $_POST['post_type'] && current_user_can( 'edit_post', $post_id ) ) { |
16 |
|
17 |
$question_answers = isset( $_POST['quiz_answer'] ) ? ( $_POST['quiz_answer'] ) : array(); |
18 |
|
19 |
$filtered_answers = array(); |
20 |
|
21 |
foreach ( $question_answers as $answer ) { |
22 |
|
23 |
array_push( $filtered_answers, sanitize_text_field( trim( $answer ) ) ); |
24 |
|
25 |
}
|
26 |
|
27 |
$question_answers = json_encode( $filtered_answers ); |
28 |
|
29 |
$correct_answer = isset( $_POST['correct_answer'] ) ? sanitize_text_field( $_POST['correct_answer'] ) : ""; |
30 |
|
31 |
update_post_meta( $post_id, "_question_answers", $question_answers ); |
32 |
|
33 |
update_post_meta( $post_id, "_question_correct_answer", $correct_answer ); |
34 |
|
35 |
}
|
36 |
else { |
37 |
|
38 |
return $post_id; |
39 |
|
40 |
}
|
41 |
}
|
La ID de la publicación se pasa automáticamente a esta función. Inicialmente ejecutamos validaciones para valor nonce y autosave. Lo más importante antes de guardar es la validación del tipo de publicación.
Si omite la verificación de tipo de publicación, este código se ejecutará para todos los tipos de publicación en su instalación de WordPress, incluidas las publicaciones normales, lo que puede resultar en datos incoherentes.
Finalmente, obtenemos los valores de nuestros campos de respuestas y el campo de respuestas correctas que se guardarán en la base de datos mediante la función update_post_meta . Todos los detalles de los campos personalizados se guardarán en la tabla post_meta .
Ahora hemos completado el proceso de creación de la pregunta. Dado que estamos utilizando pruebas generadas aleatoriamente, es posible que necesite muchas preguntas para ver este complemento en acción. Así que prepárese agregando preguntas adicionales antes de implementar la prueba en la siguiente parte.
Página de configuración de prueba
Aunque no es obligatorio, es ideal tener una página de configuración para nuestro complemento para que el administrador pueda personalizar de acuerdo con sus preferencias.
Así que implementemos una página de configuración simple para contener la duración de la prueba y el número de preguntas por prueba. Necesitamos implementar la acción admin_menuen el constructor.
1 |
add_action( 'admin_menu', array( $this, 'wpq_plugin_settings' ) ); |
1 |
function wpq_plugin_settings() { |
2 |
|
3 |
//create new top-level menu
|
4 |
|
5 |
add_menu_page( 'WPTuts Quiz Settings', 'WPTuts Quiz Settings', 'administrator', 'quiz_settings', array( $this, 'wpq_display_settings' ) ); |
6 |
|
7 |
}
|
8 |
|
9 |
function wpq_display_settings() { |
10 |
|
11 |
$html = '<div class="wrap"> |
12 |
<form method="post" name="options" action="options.php">
|
13 |
<h2>Select Your Settings</h2>' . wp_nonce_field( 'update-options' ) . ' |
14 |
|
15 |
<table width="100%" cellpadding="10" class="form-table">
|
16 |
<tr>
|
17 |
<td align="left" scope="row">
|
18 |
<label>Number of Questions</label><input type="text" name="wpq_num_questions" value="' . get_option( 'wpq_num_questions' ) . '" /> |
19 |
</td>
|
20 |
</tr>
|
21 |
<tr>
|
22 |
<td align="left" scope="row">
|
23 |
<label>Duration (Mins)</label><input type="text" name="wpq_duration" value="' . get_option( 'wpq_duration' ) . '" /> |
24 |
</td>
|
25 |
</tr>
|
26 |
</table>
|
27 |
|
28 |
<p class="submit">
|
29 |
<input type="hidden" name="action" value="update" />
|
30 |
<input type="hidden" name="page_options" value="wpq_num_questions,wpq_duration" />
|
31 |
<input type="submit" name="Submit" value="Update" />
|
32 |
</p>
|
33 |
|
34 |
</form>
|
35 |
</div>'; |
36 |
|
37 |
echo $html; |
38 |
}
|
Podemos usar la función add_menu_page para agregar una página de configuración al área de administración. La función wpq_display_settings se utiliza para implementar los elementos de visualización de la página de configuración.
Hemos utilizado dos campos de texto para la duración y preguntas por cuestionario. El envío de formularios y el almacenamiento de datos se pueden manejar manualmente usando un código personalizado, pero WordPress nos proporciona un método simplificado para actualizar las opciones.
En este método, debe establecer la acción del formulario en el archivo options.php . Luego tienes que crear un campo oculto llamado acción para contener el valor de ' actualizar '. Finalmente, necesitamos tener otro campo oculto llamado page_options para contener los nombres de los dos campos de texto que se actualizarán.
Asegúrese de utilizar estas técnicas de actualización de opciones integradas en escenarios donde los requisitos para guardar los campos no sean complejos.
Una vez que se haga clic en el botón Enviar, los detalles del formulario se actualizarán automáticamente sin ningún código personalizado.
Que sigue
Hemos completado el backend de nuestro plugin de prueba. Ahora puede crear preguntas y prepararse para la siguiente parte, donde usaremos estas preguntas para generar pruebas de forma dinámica.
Hasta entonces, hágame saber la mejor manera posible de implementar un cuestionario dinámico en la interfaz. Tenga en cuenta que solo se mostrará una pregunta a la vez. Cuando el usuario solicita una pregunta, puede pasar a la siguiente pregunta.
Esperamos sus sugerencias.



