Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
Ahora que hemos aprendido casi todo sobre la clase WP_Query
, es el momento de probar con algunos ejemplos. En esta parte, vamos a trabajar con 10 escenarios diferentes en los que hacer uso de WP_Query
y de funciones relacionadas.
Será un ejercicio divertido y espero que sea al mismo tiempo didáctico. ¡Vamos!
Rápido Repaso sobre la Creación de un Loop Con WP_Query
Con el objetivo de hacer el artículo comprensible por separado de la serie completa "Dominar WP_Query", debería realizar un breve nano-tutorial sobre la creación de loops en WordPress mediante la clase WP_Query
.
En el fondo, no se diferencia mucho de la creación de un loop común. Un típico loop de WordPress sería así:
<?php if ( have_posts() ) { while ( have_posts() ) { the_post(); // Post data goes here. } } ?>
Y la creación de un loop con la clase WP_Query
solo contiene algunas diferencias:
<?php $args = array( 'category_name' => 'news', 'posts_per_page' => 3 ); $my_query = new WP_Query( $args ); if ( $my_query->have_posts() ) { while ( $my_query->have_posts() ) { $my_query->the_post(); // Post data goes here. } } // Reset the `$post` data to the current post in main query. wp_reset_postdata(); ?>
Veamos cuáles son estas entre ambos:
- Establecemos algunos argumentos para nuestra instancia
WP_Query
, - Iniciamos la clase
WP_Query
, - Hemos añadido
$my_query->
al principio de las funcioneshave_posts()
ythe_post()
( de forma que ahora constituyen métodos de la claseWP_Query
), - Y hemos reajustado los datos de
$post
de forma que pueda responder a la query principal.
Ahora sabemos como crear un loop con WP_Query
y la diferencia entre un loop normal y otro creado con WP_Query
. No vamos a crear loops en cada ejemplo (con el fin de mantener el tutorial breve y centrado en el tópico), así que si necesitas crear un loop con los ejemplos de abajo puedes consultar esta sección.
Ejemplo #1: Los Artículos de Un Autor Durante Este Año
Imagina que quieres enumerar los artículos que un autor en particular ha escrito en el transcurso de este año reunidos en una sección especial, "Los Artículos del Autor en Este Año". Una sencilla combinación de dos parámetros WP_Query será suficiente:
<?php // Get the year we're in. $current_year = date( 'Y' ); // Setup arguments. $args = array( // Get the author with the nicename "john". 'author' => 'john', // Get his posts from this year. 'year' => $current_year ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
Procesa esta cadena en un loop y, ¡ya lo tienes!
Ejemplo #2: "Los Últimos Artículos De Esta Categoría" (Exceptuando el Actual)
Digamos que quieres crear un loop bajo cada artículo en las páginas individuales de cada post o entrada, y listar las últimas entradas de su misma categoría. Por supuesto, en este caso debes excluir la entrada actual si es la más reciente en la categoría. Aquí tienes cómo crear la query con los parámetros 'cat'
y 'post__not_in'
:
<?php // Get the current post id. $current_post_id = get_the_ID(); // Get the current post's category (first one if there's more than one). $current_post_cats = get_the_category(); $current_post_first_cat_id = $current_post_cats[ 0 ]->term_id; // Setup arguments. $args = array( // Get category's posts. 'cat' => $current_post_first_cat_id, // Exclude current post. 'post__not_in' => array( $current_post_id ) ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
Para el loop, te sugiero que construyas tres o cuatro columnas con miniaturas sobre los títulos de las entradas. Quedará perfecto justo bajo el artículo y antes de la sección de comentarios.
Ejemplo #3: "Los Artículos Más Populares" Ordenados según la Cantidad de Comentarios
WordPress no dispone de un sistema interno que haga la función de "contador de visitas a entradas", y los plugins que sí la ofrecen tienen fama de ralentizar las páginas (ya que con cada visita a la entrada, estos plugins escriben en la base de datos repetidamente para grabarlas todas). De todas formas, existe otros medios para medir la "popularidad" de un artículo: el conteo de los comentarios. Y a diferencia del número de visitas, los comentarios ya existen en la base de datos —la clase WP_Query
hace que resulte verdaderamente fácil ordenar las entradas bajo el criterio del número de comentarios.
<?php // Setup arguments. $args = array( // Order by comment count. 'orderby' => 'comment_count' ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
¿Vemos lo fácil que es? Imagínate creando una plantilla de página personalizada con un loop procesando esta cadena —una página con "Los Artículos Más Comentados".
Ejemplo #4: Ajustar Un Sencillo Slider o Visor de Diapositivas
Cuando usamos WordPress para crear páginas web corporativas, portafolios o revistas digitales, los sliders pasan a ser casi un estándar obligatorio. Yo no soy un gran admirador de los sliders (creo que son nefastos para UX - la experiencia del usuario) pero a la web parecen gustarle, así que no puedo decir que no a mis clientes si realizo webs para ellos. Si quieren sliders, uso una cadena simple mediante la clase WP_Query
:
<?php // Setup arguments. $args = array( // Get the "slider" post type. 'post_type' => 'slider', // Get a specific slider category. 'category_name' => 'home-slides', // Get all slides and don't paginate. 'nopaging' => true ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
El argumento 'cat'
se puede usar para obtener las diapositivas del slider que ilustrarán las diferentes categorías, y así puedes separar conjuntos de diapositivas y usar multiples sliders en multiples páginas. Si vas a usar solo un slider en tu web, puedes eliminar esa línea seguir sin problemas.
Ejemplo #5: Una Cita Aleatoria para la Barra Lateral
Si te chiflasen la literatura o los temas religiosos, podrías querer ubicar algunas de tus citas favoritas en la barra lateral —no es un desperdicio del espacio si empleas esa área con un propósito. Así que, si vas a incluir un número de citas aleatorias a tu barra lateral para cada visita a la página, puedes usar el siguiente fragmento de código para crear un tipo de entrada y usar la siguiente cadena para el loop en la barra lateral.
<?php /* * Create new post type called "Quotes" * (refer to the `register_post_type` function to * learn more about creating custom post types). */ function quote_post_type() { $args = array( 'label' => 'Quotes', 'public' => true ); register_post_type( 'quotes', $args ); } add_action( 'init', 'quote_post_type' ); // Setup arguments. $args = array( // Get the "quotes" psot type. 'post_type' => 'quotes', // Randomize the order. 'orderby' => 'rand', // Get only one item. 'posts_per_page' => 1, ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
Una solución fácil y elegante.
Ejemplo #6: Enumerar Productos Dentro de un Rango de Precio
Encontré este ejemplo en Scribu.net y debo decir, que es el mejor truco con WP_Query
de este tutorial. Es un poco más técnico que los otros ya que, además, puede ser aplicado a un sitio web de e-commerce construido con WordPress.
Aquí tienes el fragmento de código que usarías si quisieses enumerar los artículos de una entrada personalizada de "producto" y filtrar los resultados con los campos personalizados para el "precio".
<?php // Source: http://scribu.net/wordpress/advanced-metadata-queries.html // Setup arguments. $args = array( // Get the "product" post type. 'post_type' => 'product', // Setup the "meta query". 'meta_query' => array( array( // Get the "price" custom field. 'key' => 'price', // Set the price values. 'value' => array( 100, 200 ), // Set the compare operator. 'compare' => 'BETWEEN', // Only look at numeric fields. 'type' => 'numeric', ) ) ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
¡Gran ovación para Silviu-Cristian Burca!
Ejemplo #7: Un Atajo para Incrustar Entradas Dentro de Entradas
Aquí tenemos un ejercicio simpático—¡y nos habituaremos a usar la API del código corto! En este ejemplo, vamos a crear un código corto que sea capaz de incrustar una entrada en otra. (casi tengo que contenerme al dar nombre al código corto [postception]
.) En el siguiente fragmento de código, hemos creado una función de código corto que nos permitirá incrustar entradas (o cualquier post type) y también elegir si mostramos la entrada completa o un resumen.
<?php /* * Usage: * * [embed_post slug="my-post"] * [embed_post slug="my-post" full="false"] * [embed_post type="movie" slug="inception"] */ function tutsplus_embedded_post_shortcode( $attributes ) { // Extract shortcode attributes. extract( shortcode_atts( array( 'type' => 'post', 'slug' => '', 'full' => true ), $attributes ) ); // Setup arguments. $args = array( // Get post type ("post" by default). 'post_type' => $type, // Get post by slug. 'name' => $slug ); // Instantiate new query instance. $my_query = new WP_Query( $args ); // Check that we have query results. if ( $my_query->have_posts() ) { // Begin generating markup. $output = '<section class="embedded-post">'; // Start looping over the query results. while ( $my_query->have_posts() ) { $my_query->the_post(); // Add title to output. $output .= '<h2 class="embedded-post-title">'; $output .= get_the_title(); $output .= '</h2>'; // Get full post if `$full` is true, otherwise, show the get excerpt if ( 'true' === $full ) { // Add full content to output. $output .= '<div class="embedded-post-content">'; $output .= get_the_content(); $output .= '</div>'; } else { // Add excerpt to output. $output .= '<div class="embedded-post-excerpt">'; $output .= get_the_excerpt(); $output .= '… <a href="' . get_permalink() . '">' . __( 'See full post', 'tutsplus' ) . ' »</a>'; $output .= '</div>'; } } // End generating markup. $output .= '</section>'; } else { // Output message to let user know that no posts were found. $output = '<section class="embedded-post-error">'; $output .= '<p>' . __( 'No posts found.', 'tutsplus' ) . '</p>'; $output .= '</section>'; } wp_reset_postdata(); return $output; } add_shortcode( 'embed_post', 'tutsplus_embedded_post_shortcode' ); ?>
Ejemplo #8: Listado de Las Entradas Actualmente Programadas (Con Resúmenes Opcionales)
Te propongo una idea: ¿Por qué no desvelas algunas "pequeñas pistas" sobre próximos artículos a tus visitantes? Puedes usar la siguiente función para enumerar tus artículos programados con o sin extracto tras el título:
<?php /* * Usage with Excerpts: * * <?php echo tutsplus_show_drafts(); ?> * * Usage without Excerpts: * * <?php echo tutsplus_show_drafts( false ); ?> */ function tutsplus_show_drafts( $show_excerpts = true ) { // Setup arguments. $args = array( 'post_status' => 'pending', 'nopaging' => true ); // Instantiate new query instance. $my_query = new WP_Query( $args ); // Check that we have query results. if ( $my_query->have_posts() ) { // Begin generating markup. $output = '<section class="pending-posts">'; // Start looping over the query results. while ( $my_query->have_posts() ) { $my_query->the_post(); // Output draft post title and excerpt (if enabled). $output .= '<div class="pending">'; $output .= '<h3 class="pending-title">' . get_the_title() . '</h3>'; $output .= get_the_title(); $output .= '</h3>'; if ( $show_excerpts ) { $output .= '<div class="pending-excerpt">'; $output .= get_the_excerpt(); $output .= '</div>'; } $output .= '</div>'; } // End generating markup. $output .= '</section>'; } else { // Let user know that nothing was found. $output = '<section class="drafts-error">'; $output .= '<p>' . __( 'Nothing found', 'tutsplus' ) . '</p>'; $output .= '</section>'; } wp_reset_postdata(); return $output; } ?>
Ejemplo #9: "Artículo De Hace Un Año"
Si tu blog tiene más de un año de antigüedad, y tu contenido no es caduco (es decir, una persona encontrará el contenido relevante tanto en 2015 como en 2015), añadir una sección llamada "Artículo De Hace Un Año" podría impulsar el índice de páginas vistas. Cómo conseguirlo:
<?php // Setup arguments. $args = array( // Day (1 - 31). 'day' => date( 'j' ), // Month (1 - 12). 'monthnum' => date( 'n' ), // Year (minus 1). 'year' => date( 'Y' ) - 1, // Show only one post. 'posts_per_page' => 1 ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
Usa esta cadena para construir un loop que muestre una única entrada del año anterior.
Ejemplo #10: Mostrar Una Página Descendiente de la Actual
¿No tienes más que los títulos de las sub-páginas para ubicar en las páginas "Servicios", "Nuestros Trabajos", o "Mi Portafolio"? Quizá un párrafo introductorio, está bién, esas páginas suelen estar destinadas a convertirse en "contenedores vacíos". En cualquier caso, es buena idea tener sub-páginas de este tipo—quizá una retícula con miniaturas rectangulares y títulos superpuestos. Veamos que cadena deberíamos usar para crear este tipo de plantilla de página que acabo de sugerirte:
<?php $current_page_id = get_the_ID(); // Setup arguments. $args = array( // Get children of current page. 'parent' => $current_page_id, // Disable pagination. 'nopaging' => true ); // Instantiate new query instance. $my_query = new WP_Query( $args ); ?>
Resumiendo
Espero que hayas disfrutado con estos ejemplos tanto como yo mientras los preparaba. Presté especial atención en ofrecer variedad tanto para que fuesen amenos como para ampliar tu creatividad.
Si se te ocurren mejores ejemplos mientras lees estos, o tienes preguntas, no seas tímido y coméntalo más abajo. Y si te ha gustado el artículo, ¡no olvides compartirlo con tus amigos!
En la proxima parte, hablaremos sobre WP_User_Query
, una de las clases hermanas de WP_Query
. ¡Hasta entonces!