Usando WordPress para crear un sistema de preguntas frecuentes con tipos de publicaciones personalizadas (Custom Post Types)
Spanish (Español) translation by steven (you can also view the original English article)
Recientemente trabajé con una clienta mía, que trabaja como consultora profesional en su área de trabajo. Me preguntó si podía implementar un sistema de preguntas y respuestas, o una página de preguntas frecuentes, para ser exactos. Le dije: "Claro, podemos crear una página y pegar las preguntas y respuestas allí con diferentes estilos", pero ella dijo que crearía diferentes páginas y categorizaría preguntas y respuestas, y para estar más organizada; ella necesitaba un enfoque diferente.
Con ese fin, les mostraré cómo manejé sus solicitudes con algunas líneas simples de código usando tipos de publicaciones, taxonomías y códigos cortos personalizados.
El tipo de publicación personalizada y la taxonomía
¿Qué necesitamos para construir un sistema de preguntas frecuentes?
- Necesitamos campos para preguntas y respuestas.
- Necesitamos categorías para clasificar y separar diferentes tipos de preguntas y sus respuestas.
- En nuestro caso, necesitamos un código corto para incrustar estos grupos de preguntas o todas las preguntas en una página o publicación.
Comencemos creando el tipo de publicación personalizada.
Paso 1: Crear el tipo de publicación personalizada
Naturalmente, comenzaremos configurando un tipo de publicación personalizada para nuestros artículos de preguntas frecuentes. Vamos a crear un nuevo tipo de publicación personalizada con la ayuda de la función register_post_type(), pero si deseas una GUI para crear tu tipo de publicación, puedes generarla con la herramienta GenerateWP's Post Type Generator como hice en este ejemplo:
1 |
<?php
|
2 |
|
3 |
if ( ! function_exists( 'tuts_faq_cpt' ) ) { |
4 |
|
5 |
// register custom post type
|
6 |
function tuts_faq_cpt() { |
7 |
|
8 |
// these are the labels in the admin interface, edit them as you like
|
9 |
$labels = array( |
10 |
'name' => _x( 'FAQs', 'Post Type General Name', 'tuts_faq' ), |
11 |
'singular_name' => _x( 'FAQ', 'Post Type Singular Name', 'tuts_faq' ), |
12 |
'menu_name' => __( 'FAQ', 'tuts_faq' ), |
13 |
'parent_item_colon' => __( 'Parent Item:', 'tuts_faq' ), |
14 |
'all_items' => __( 'All Items', 'tuts_faq' ), |
15 |
'view_item' => __( 'View Item', 'tuts_faq' ), |
16 |
'add_new_item' => __( 'Add New FAQ Item', 'tuts_faq' ), |
17 |
'add_new' => __( 'Add New', 'tuts_faq' ), |
18 |
'edit_item' => __( 'Edit Item', 'tuts_faq' ), |
19 |
'update_item' => __( 'Update Item', 'tuts_faq' ), |
20 |
'search_items' => __( 'Search Item', 'tuts_faq' ), |
21 |
'not_found' => __( 'Not found', 'tuts_faq' ), |
22 |
'not_found_in_trash' => __( 'Not found in Trash', 'tuts_faq' ), |
23 |
);
|
24 |
$args = array( |
25 |
// use the labels above
|
26 |
'labels' => $labels, |
27 |
// we'll only need the title, the Visual editor and the excerpt fields for our post type
|
28 |
'supports' => array( 'title', 'editor', 'excerpt', ), |
29 |
// we're going to create this taxonomy in the next section, but we need to link our post type to it now
|
30 |
'taxonomies' => array( 'tuts_faq_tax' ), |
31 |
// make it public so we can see it in the admin panel and show it in the front-end
|
32 |
'public' => true, |
33 |
// show the menu item under the Pages item
|
34 |
'menu_position' => 20, |
35 |
// show archives, if you don't need the shortcode
|
36 |
'has_archive' => true, |
37 |
);
|
38 |
register_post_type( 'tuts_faq', $args ); |
39 |
|
40 |
}
|
41 |
|
42 |
// hook into the 'init' action
|
43 |
add_action( 'init', 'tuts_faq_cpt', 0 ); |
44 |
|
45 |
}
|
46 |
|
47 |
?>
|
Sugerencia: Si tu proyecto va a involucrar más tipos de publicaciones personalizadas que pueden ser más complejas que este tipo de publicación de preguntas frecuentes, puedo sugerir una herramienta genial llamada SuperCPT que te permite crear nuevos tipos de publicaciones con un código aún más simple. También escribí un tutorial sobre SuperCPT, puedes consultarlo aquí.
Paso 2: Crear la taxonomía personalizada
Para separar los diferentes tipos de preguntas (como las preguntas y respuestas de mi clienta sobre el aborto espontáneo y la depresión posparto), necesitaremos un sistema de categorías. Como muchos de ustedes ya saben, WordPress proporciona esta funcionalidad con taxonomías personalizadas.
La función esencial aquí es register_taxonomy() pero nuevamente, puedes usar la herramienta GenerateWP's Taxonomy Generator si necesitas una interfaz gráfica.
Aquí está el código:
1 |
<?php
|
2 |
|
3 |
if ( ! function_exists( 'tuts_faq_tax' ) ) { |
4 |
|
5 |
// register custom taxonomy
|
6 |
function tuts_faq_tax() { |
7 |
|
8 |
// again, labels for the admin panel
|
9 |
$labels = array( |
10 |
'name' => _x( 'FAQ Categories', 'Taxonomy General Name', 'tuts_faq' ), |
11 |
'singular_name' => _x( 'FAQ Category', 'Taxonomy Singular Name', 'tuts_faq' ), |
12 |
'menu_name' => __( 'FAQ Categories', 'tuts_faq' ), |
13 |
'all_items' => __( 'All FAQ Cats', 'tuts_faq' ), |
14 |
'parent_item' => __( 'Parent FAQ Cat', 'tuts_faq' ), |
15 |
'parent_item_colon' => __( 'Parent FAQ Cat:', 'tuts_faq' ), |
16 |
'new_item_name' => __( 'New FAQ Cat', 'tuts_faq' ), |
17 |
'add_new_item' => __( 'Add New FAQ Cat', 'tuts_faq' ), |
18 |
'edit_item' => __( 'Edit FAQ Cat', 'tuts_faq' ), |
19 |
'update_item' => __( 'Update FAQ Cat', 'tuts_faq' ), |
20 |
'separate_items_with_commas' => __( 'Separate items with commas', 'tuts_faq' ), |
21 |
'search_items' => __( 'Search Items', 'tuts_faq' ), |
22 |
'add_or_remove_items' => __( 'Add or remove items', 'tuts_faq' ), |
23 |
'choose_from_most_used' => __( 'Choose from the most used items', 'tuts_faq' ), |
24 |
'not_found' => __( 'Not Found', 'tuts_faq' ), |
25 |
);
|
26 |
$args = array( |
27 |
// use the labels above
|
28 |
'labels' => $labels, |
29 |
// taxonomy should be hierarchial so we can display it like a category section
|
30 |
'hierarchical' => true, |
31 |
// again, make the taxonomy public (like the post type)
|
32 |
'public' => true, |
33 |
);
|
34 |
// the contents of the array below specifies which post types should the taxonomy be linked to
|
35 |
register_taxonomy( 'tuts_faq_tax', array( 'tuts_faq' ), $args ); |
36 |
|
37 |
}
|
38 |
|
39 |
// hook into the 'init' action
|
40 |
add_action( 'init', 'tuts_faq_tax', 0 ); |
41 |
|
42 |
}
|
43 |
|
44 |
?>
|
¡Eso es todo! ¡Ahora tienes un tipo de publicación de preguntas frecuentes con una taxonomía llamada "Categorías de preguntas frecuentes" vinculadas entre sí! Revisa tu panel de administración y verás el elemento de menú "Categorías de preguntas frecuentes" debajo de las "Preguntas frecuentes".
Al igual que las categorías de publicaciones normales, puedes agregarlas, editarlas o eliminarlas en la página "Categorías de preguntas frecuentes", o puedes agregar nuevas categorías mientras escribes un nuevo elemento de preguntas frecuentes.
Paso 3: Creación del Shortcode o código corto [faq]
Aquí viene la parte divertida: construir el código corto. (Si has leído mis publicaciones anteriores, sabrás que soy un gran admirador de los códigos cortos de WordPress). Básicamente, vamos a hacer que los elementos de las preguntas frecuentes se puedan incrustar en publicaciones y páginas.
Esto es lo que va a pasar:
- vamos a consultar dentro de nuestro nuevo tipo de publicación personalizada,
- filtrar sus categorías con un parámetro de código corto,
- mostrar las preguntas y respuestas como títulos y contenido,
- mostrar un extracto de la respuesta con un enlace "Más...", controlado por otro parámetro de código corto.
Comencemos a construir el shortcode. Al igual que el código anterior, incluiré algunos comentarios útiles:
1 |
<?php
|
2 |
|
3 |
if ( ! function_exists( 'tuts_faq_shortcode' ) ) { |
4 |
|
5 |
function tuts_faq_shortcode( $atts ) { |
6 |
extract( shortcode_atts( |
7 |
array( |
8 |
// category slug attribute - defaults to blank
|
9 |
'category' => '', |
10 |
// full content or excerpt attribute - defaults to full content
|
11 |
'excerpt' => 'false', |
12 |
), $atts ) |
13 |
);
|
14 |
|
15 |
$output = ''; |
16 |
|
17 |
// set the query arguments
|
18 |
$query_args = array( |
19 |
// show all posts matching this query
|
20 |
'posts_per_page' => -1, |
21 |
// show the 'tuts_faq' custom post type
|
22 |
'post_type' => 'tuts_faq', |
23 |
// show the posts matching the slug of the FAQ category specified with the shortcode's attribute
|
24 |
'tax_query' => array( |
25 |
array( |
26 |
'taxonomy' => 'tuts_faq_tax', |
27 |
'field' => 'slug', |
28 |
'terms' => $category, |
29 |
)
|
30 |
),
|
31 |
// tell WordPress that it doesn't need to count total rows - this little trick reduces load on the database if you don't need pagination
|
32 |
'no_found_rows' => true, |
33 |
);
|
34 |
|
35 |
// get the posts with our query arguments
|
36 |
$faq_posts = get_posts( $query_args ); |
37 |
$output .= '<div class="tuts-faq">'; |
38 |
|
39 |
// handle our custom loop
|
40 |
foreach ( $faq_posts as $post ) { |
41 |
setup_postdata( $post ); |
42 |
$faq_item_title = get_the_title( $post->ID ); |
43 |
$faq_item_permalink = get_permalink( $post->ID ); |
44 |
$faq_item_content = get_the_content(); |
45 |
if( $excerpt == 'true' ) |
46 |
$faq_item_content = get_the_excerpt() . '<a href="' . $faq_item_permalink . '">' . __( 'More...', 'tuts_faq' ) . '</a>'; |
47 |
|
48 |
$output .= '<div class="tuts-faq-item">'; |
49 |
$output .= '<h3 class="tuts-faq-item-title">' . $faq_item_title . '</h3>'; |
50 |
$output .= '<div class="tuts-faq-item-content">' . $faq_item_content . '</div>'; |
51 |
$output .= '</div>'; |
52 |
}
|
53 |
|
54 |
wp_reset_postdata(); |
55 |
|
56 |
$output .= '</div>'; |
57 |
|
58 |
return $output; |
59 |
}
|
60 |
|
61 |
add_shortcode( 'faq', 'tuts_faq_shortcode' ); |
62 |
|
63 |
}
|
64 |
|
65 |
?>
|
¡Eso es todo! Ahora tenemos un código corto ordenado para incrustar nuestras preguntas y respuestas. Puedes diseñarlo con los nombres de clase tuts-faq, tuts-faq-item, tuts-faq-item-title y tuts-faq-item-content. Aunque, debería estar bien incluso si no incluyes un estilo adicional.
Paso 4: Resumiendo el código
Dado que estos fragmentos de código no se tratan solo de diseñar el front-end, sino también de introducir nuevas funciones, esto cuenta como territorio de complementos. Por eso debemos guardar el código como complemento. Y ya que estamos en eso, también deberíamos eliminar las reglas de reescritura tras la activación y desactivación.
Aquí está el código completo:
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Simple FAQ System
|
4 |
Plugin URI: http://code.tutsplus.com/
|
5 |
Description: Helps you create an FAQ section for your WordPress website. Shortcode usage: <code>[faq]</code>
|
6 |
Version: 1.0
|
7 |
Author: Barış Ünver
|
8 |
Author URI: http://hub.tutsplus.com/authors/baris-unver
|
9 |
License: Public Domain
|
10 |
*/
|
11 |
|
12 |
if ( ! function_exists( 'tuts_faq_cpt' ) ) { |
13 |
|
14 |
// register custom post type
|
15 |
function tuts_faq_cpt() { |
16 |
|
17 |
// these are the labels in the admin interface, edit them as you like
|
18 |
$labels = array( |
19 |
'name' => _x( 'FAQs', 'Post Type General Name', 'tuts_faq' ), |
20 |
'singular_name' => _x( 'FAQ', 'Post Type Singular Name', 'tuts_faq' ), |
21 |
'menu_name' => __( 'FAQ', 'tuts_faq' ), |
22 |
'parent_item_colon' => __( 'Parent Item:', 'tuts_faq' ), |
23 |
'all_items' => __( 'All Items', 'tuts_faq' ), |
24 |
'view_item' => __( 'View Item', 'tuts_faq' ), |
25 |
'add_new_item' => __( 'Add New FAQ Item', 'tuts_faq' ), |
26 |
'add_new' => __( 'Add New', 'tuts_faq' ), |
27 |
'edit_item' => __( 'Edit Item', 'tuts_faq' ), |
28 |
'update_item' => __( 'Update Item', 'tuts_faq' ), |
29 |
'search_items' => __( 'Search Item', 'tuts_faq' ), |
30 |
'not_found' => __( 'Not found', 'tuts_faq' ), |
31 |
'not_found_in_trash' => __( 'Not found in Trash', 'tuts_faq' ), |
32 |
);
|
33 |
$args = array( |
34 |
// use the labels above
|
35 |
'labels' => $labels, |
36 |
// we'll only need the title, the Visual editor and the excerpt fields for our post type
|
37 |
'supports' => array( 'title', 'editor', 'excerpt', ), |
38 |
// we're going to create this taxonomy in the next section, but we need to link our post type to it now
|
39 |
'taxonomies' => array( 'tuts_faq_tax' ), |
40 |
// make it public so we can see it in the admin panel and show it in the front-end
|
41 |
'public' => true, |
42 |
// show the menu item under the Pages item
|
43 |
'menu_position' => 20, |
44 |
// show archives, if you don't need the shortcode
|
45 |
'has_archive' => true, |
46 |
);
|
47 |
register_post_type( 'tuts_faq', $args ); |
48 |
|
49 |
}
|
50 |
|
51 |
// hook into the 'init' action
|
52 |
add_action( 'init', 'tuts_faq_cpt', 0 ); |
53 |
|
54 |
}
|
55 |
|
56 |
if ( ! function_exists( 'tuts_faq_tax' ) ) { |
57 |
|
58 |
// register custom taxonomy
|
59 |
function tuts_faq_tax() { |
60 |
|
61 |
// again, labels for the admin panel
|
62 |
$labels = array( |
63 |
'name' => _x( 'FAQ Categories', 'Taxonomy General Name', 'tuts_faq' ), |
64 |
'singular_name' => _x( 'FAQ Category', 'Taxonomy Singular Name', 'tuts_faq' ), |
65 |
'menu_name' => __( 'FAQ Categories', 'tuts_faq' ), |
66 |
'all_items' => __( 'All FAQ Cats', 'tuts_faq' ), |
67 |
'parent_item' => __( 'Parent FAQ Cat', 'tuts_faq' ), |
68 |
'parent_item_colon' => __( 'Parent FAQ Cat:', 'tuts_faq' ), |
69 |
'new_item_name' => __( 'New FAQ Cat', 'tuts_faq' ), |
70 |
'add_new_item' => __( 'Add New FAQ Cat', 'tuts_faq' ), |
71 |
'edit_item' => __( 'Edit FAQ Cat', 'tuts_faq' ), |
72 |
'update_item' => __( 'Update FAQ Cat', 'tuts_faq' ), |
73 |
'separate_items_with_commas' => __( 'Separate items with commas', 'tuts_faq' ), |
74 |
'search_items' => __( 'Search Items', 'tuts_faq' ), |
75 |
'add_or_remove_items' => __( 'Add or remove items', 'tuts_faq' ), |
76 |
'choose_from_most_used' => __( 'Choose from the most used items', 'tuts_faq' ), |
77 |
'not_found' => __( 'Not Found', 'tuts_faq' ), |
78 |
);
|
79 |
$args = array( |
80 |
// use the labels above
|
81 |
'labels' => $labels, |
82 |
// taxonomy should be hierarchial so we can display it like a category section
|
83 |
'hierarchical' => true, |
84 |
// again, make the taxonomy public (like the post type)
|
85 |
'public' => true, |
86 |
);
|
87 |
// the contents of the array below specifies which post types should the taxonomy be linked to
|
88 |
register_taxonomy( 'tuts_faq_tax', array( 'tuts_faq' ), $args ); |
89 |
|
90 |
}
|
91 |
|
92 |
// hook into the 'init' action
|
93 |
add_action( 'init', 'tuts_faq_tax', 0 ); |
94 |
|
95 |
}
|
96 |
|
97 |
if ( ! function_exists( 'tuts_faq_shortcode' ) ) { |
98 |
|
99 |
function tuts_faq_shortcode( $atts ) { |
100 |
extract( shortcode_atts( |
101 |
array( |
102 |
// category slug attribute - defaults to blank
|
103 |
'category' => '', |
104 |
// full content or excerpt attribute - defaults to full content
|
105 |
'excerpt' => 'false', |
106 |
), $atts ) |
107 |
);
|
108 |
|
109 |
$output = ''; |
110 |
|
111 |
// set the query arguments
|
112 |
$query_args = array( |
113 |
// show all posts matching this query
|
114 |
'posts_per_page' => -1, |
115 |
// show the 'tuts_faq' custom post type
|
116 |
'post_type' => 'tuts_faq', |
117 |
// show the posts matching the slug of the FAQ category specified with the shortcode's attribute
|
118 |
'tax_query' => array( |
119 |
array( |
120 |
'taxonomy' => 'tuts_faq_tax', |
121 |
'field' => 'slug', |
122 |
'terms' => $category, |
123 |
)
|
124 |
),
|
125 |
// tell WordPress that it doesn't need to count total rows - this little trick reduces load on the database if you don't need pagination
|
126 |
'no_found_rows' => true, |
127 |
);
|
128 |
|
129 |
// get the posts with our query arguments
|
130 |
$faq_posts = get_posts( $query_args ); |
131 |
$output .= '<div class="tuts-faq">'; |
132 |
|
133 |
// handle our custom loop
|
134 |
foreach ( $faq_posts as $post ) { |
135 |
setup_postdata( $post ); |
136 |
$faq_item_title = get_the_title( $post->ID ); |
137 |
$faq_item_permalink = get_permalink( $post->ID ); |
138 |
$faq_item_content = get_the_content(); |
139 |
if( $excerpt == 'true' ) |
140 |
$faq_item_content = get_the_excerpt() . '<a href="' . $faq_item_permalink . '">' . __( 'More...', 'tuts_faq' ) . '</a>'; |
141 |
|
142 |
$output .= '<div class="tuts-faq-item">'; |
143 |
$output .= '<h2 class="faq-item-title">' . $faq_item_title . '</h2>'; |
144 |
$output .= '<div class="faq-item-content">' . $faq_item_content . '</div>'; |
145 |
$output .= '</div>'; |
146 |
}
|
147 |
|
148 |
wp_reset_postdata(); |
149 |
|
150 |
$output .= '</div>'; |
151 |
|
152 |
return $output; |
153 |
}
|
154 |
|
155 |
add_shortcode( 'faq', 'tuts_faq_shortcode' ); |
156 |
|
157 |
}
|
158 |
|
159 |
function tuts_faq_activate() { |
160 |
tuts_faq_cpt(); |
161 |
flush_rewrite_rules(); |
162 |
}
|
163 |
|
164 |
register_activation_hook( __FILE__, 'tuts_faq_activate' ); |
165 |
|
166 |
function tuts_faq_deactivate() { |
167 |
flush_rewrite_rules(); |
168 |
}
|
169 |
register_deactivation_hook( __FILE__, 'tuts_faq_deactivate' ); |
170 |
|
171 |
?>
|
Margen de mejora
Mi clienta estaba contenta con los resultados cuando le mostré cómo usarlo. Pero aquí, podemos expandir el código con más funcionalidad, como...
- Efecto de acordeón: Si deseas que tus secciones de preguntas frecuentes sean más atractivas con algunos efectos de alternancia, puedes usar algunos complementos de jQuery fabulosos. Si deseas utilizar jQuery UI, hay un increíble tutorial de Shane Osbourne que muestra cómo hacerlo.
- Paginación: Si tienes muchas preguntas y respuestas para una categoría y no deseas mostrar todos los elementos a la vez, puedes limitar la cantidad de publicaciones cambiando el parámetro
posts_per_pageen la consulta personalizada de nuestro shortcode y agrega el código requerido para enlaces de paginación debajo de la línea con el códigowp_reset_postdata();. Sin embargo, recuerda eliminar la línea'no_found_rows' => true,¡la paginación no funcionará si no la eliminas! - Pregunta aleatoria: Digamos que deseas mostrar una pregunta y respuesta al azar en la página de inicio y deseas que cambie con cada actualización de la página. Todo lo que necesitas hacer es dirigirte a la consulta personalizada, cambiar el parámetro
posts_per_pagede-1a1y agregar otra línea con el código'orderby' => 'random', ¡y listo!
Conclusión
Así es como se crea un sistema simple de preguntas frecuentes en WordPress mediante el uso de tipos de publicaciones personalizadas, taxonomías personalizadas y códigos cortos. Espero que hayas disfrutado de este tutorial y puedas utilizarlo en tu próximo proyecto. ¡No olvides compartir el artículo, si te gustó!
¿Tienes alguna idea para mejorar este sistema de preguntas frecuentes? ¡Comparte tus comentarios a continuación!



