Spanish (Español) translation by Oscar Abad Folgueira (you can also view the original English article)
Soy muy fan de la clase WP_Query
: La uso muchas veces en los sitios web de mis clientes para realizar consultas y mostrar el contenido de diferentes formas.
Si quieres ejecutar varios bucles en una página, la forma más fácil de hacerlo es ejecutar WP_Query
cada vez que necesites ejecutar un bucle. Pero hay una desventaja: cada vez que WordPress ejecuta una consulta, está enviando peticiones a la base de datos, lo que lleva tiempo y puede ralentizar tu web. Y si estás usando WP_Query
en lugar de la consulta principal para mostrar el contenido, hace que la consulta principal sea redundante y por consiguiente un consumo de recursos.
Así que te voy a mostrar cómo utilizar una consulta para ejecutar más de un bucle. Puedes hacerlo con la consulta principal (que es la que yo voy a utilizar por ser más eficiente) o puedes usar la misma técnica con WP_Query
.
Hay tres partes para hacerlo:
- Crear un tema hijo y un fichero de plantilla.
- Crear una parte de la plantilla para los contenidos del bucle.
- Crear nuestros bucles.
¡Empecemos!
Que Vas a Necesitar
Para seguir, necesitarás:
- Una instalación en desarrollo de WordPress
- Un editor de código.
- Entradas en tu sitio web con varias categorías - Yo estoy usando WordPress theme unit test data.
- El tema twenty sixteen instalado en tu sitio web.
- Un tema hijo de twenty sixteen instalado y activado - Comentaré brevemente como poner el tema hijo.
No tienes porque usar el tema twenty sixteen con un tema hijo - puedes adaptar esta técnica a tu propio tema. Pero yo voy a usar un tema hijo de twenty sixteen.
Crear un Tema Hijo
En primer lugar vamos a crear el tema hijo de twenty sixteen. Hago esto porque no quiero editar el tema twenty sixteen directamente.
En tu directorio wp-content/themes
, crea un nuevo directorio vacío. Yo he llamado al mío tutsplus-one-query-two-loops
.
En este directorio crea un fichero con el nombre style.css
y añade lo siguiente:
1 |
/*
|
2 |
Theme Name: Tutsplus One Query Multiple Loops
|
3 |
Theme URI: https://.tutsplus.com/tutorials/how-to-code-multiple-loops-while-only-querying-the-database-once--cms-25703
|
4 |
Description: Theme to support Tutorial on running multiple loops while querying the database just once. Child theme for the Twenty Sixteen theme.
|
5 |
Author: Rachel McCollin
|
6 |
Author URI: http://rachelmccollin.co.uk/
|
7 |
Template: twentysixteen
|
8 |
Version: 1.0
|
9 |
*/
|
10 |
|
11 |
@import url("../twentysixteen/style.css"); |
Ahora guarda el fichero y activa tu nuevo tema.
El siguiente paso es crear un fichero de plantilla para las categorías que es con el que trabajaremos.
Haz una copia del fichero archive.php
desde twenty sixteen en tu nuevo tema. No lo muevas, cópialo. Ponle el nombre category.php
. Ahora este es el fichero de plantilla para las categorías de tu sitio web.
Crear un Nuevo Archivo de Parte de Plantilla
El primer paso es configurar un nuevo fichero de parte de plantilla en nuestro tema que contendrá una versión modificada del bucle de twenty sixteen.
En el directorio de tu tema, crea un subdirectorio con el nombre de includes
. Dentro de el crea un nuevo fichero con el nombre loop-category.php
.
Ahora abre el fichero template-parts/content.php
del tema twenty sixteen y busca este código (que es la mayoría del fichero):
1 |
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> |
2 |
<header class="entry-header"> |
3 |
<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?> |
4 |
<span class="sticky-post"><?php _e( 'Featured', 'twentysixteen' ); ?></span> |
5 |
<?php endif; ?> |
6 |
|
7 |
<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?> |
8 |
</header><!-- .entry-header --> |
9 |
|
10 |
<?php twentysixteen_excerpt(); ?> |
11 |
|
12 |
<?php twentysixteen_post_thumbnail(); ?> |
13 |
|
14 |
<div class="entry-content"> |
15 |
<?php
|
16 |
/* translators: %s: Name of current post */
|
17 |
the_content( sprintf( |
18 |
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ), |
19 |
get_the_title() |
20 |
) ); |
21 |
|
22 |
wp_link_pages( array( |
23 |
'before' => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>', |
24 |
'after' => '</div>', |
25 |
'link_before' => '<span>', |
26 |
'link_after' => '</span>', |
27 |
'pagelink' => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%', |
28 |
'separator' => '<span class="screen-reader-text">, </span>', |
29 |
) ); |
30 |
?>
|
31 |
</div><!-- .entry-content --> |
32 |
|
33 |
<footer class="entry-footer"> |
34 |
<?php twentysixteen_entry_meta(); ?> |
35 |
<?php
|
36 |
edit_post_link( |
37 |
sprintf( |
38 |
/* translators: %s: Name of current post */
|
39 |
__( 'Edit<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ), |
40 |
get_the_title() |
41 |
),
|
42 |
'<span class="edit-link">', |
43 |
'</span>'
|
44 |
);
|
45 |
?>
|
46 |
</footer><!-- .entry-footer --> |
47 |
</article><!-- #post-## --> |
Copia esto en tu nuevo fichero.
Editar la Parte de la Plantilla
El bucle de twenty sixteen muestra más de lo que necesito para este archivo, por lo que voy a editarlo. Sólo quiero mostrar el resumen (excerpt) y no el contenido por lo que voy a eliminar esto.
En tu nuevo fichero loop-category.php
, busca este código y elimínalo:
1 |
<div class="entry-content"> |
2 |
<?php
|
3 |
/* translators: %s: Name of current post */
|
4 |
the_content( sprintf( |
5 |
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ), |
6 |
get_the_title() |
7 |
) ); |
8 |
|
9 |
wp_link_pages( array( |
10 |
'before' => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>', |
11 |
'after' => '</div>', |
12 |
'link_before' => '<span>', |
13 |
'link_after' => '</span>', |
14 |
'pagelink' => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%', |
15 |
'separator' => '<span class="screen-reader-text">, </span>', |
16 |
) ); |
17 |
?>
|
18 |
</div><!-- .entry-content --> |
El otro paso es reemplazar la función twenty_sixteen_excerpt()
con la función estándar the_excerpt()
, ya que la versión de twenty sixteen no incluye un enlace para el post completo.
Busca esta línea:
1 |
<?php twenty_sixteen_excerpt(); ?> |
Reemplázala con esto:
1 |
<?php the_excerpt(); ?> |
También necesitamos hacer unos retoques a las etiquetas de la cabecera.
En la parte de la plantilla, edita esta línea:
1 |
<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?> |
Cambia las etiquetas h2
por h3
:
1 |
<?php the_title( sprintf( '<h3 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h3>' ); ?> |
Guarda tu fichero de parte de plantilla. Ahora vuelve a tu fichero category.php
y sigue trabajando con el.
Crear Nuestros Bucles
Primero, vamos a eliminar la llamada a la parte de plantilla de twenty sixteen desde nuestro fichero category.php, tendremos que utilizar el nuevo fichero en su lugar.
En tu fichero category.ph
p busca este código:
1 |
get_template_part( 'template-parts/content', get_post_format() ); |
Elimina esto.
Ahora vamos a crear los bucles.
En este ejemplo voy a listar todos los posts con la etiqueta 'content' primero, usando la etiqueta condicional has_tag()
.
Esto significa que ejecutaré tres bucles:
- El primero chequea si la consulta ha retornado algún post con esta etiqueta.
- Si es así, el segundo muestra las entradas con esta etiqueta.
- Un tercero muestra entradas sin esta etiqueta.
Entre cada uno, usaré rewind_posts()
para resetear las entradas sin resetear la consulta: todavía estamos trabajando con la consulta principal.
El Primer Bucle: Chequeando las Entradas
En tu fichero category.php
busca en comienzo del bucle:
1 |
while ( have_posts() ) : the_post(); |
Debajo de esa línea define una nueva variable llamada $count
:
1 |
$count = 0; |
Ahora, dentro de ese bucle añade este código:
1 |
// check if there are any posts with the '' tag
|
2 |
$tag = 'content'; |
3 |
if ( has_tag( $tag ) ) { |
4 |
$count +=1; |
5 |
}
|
Esto comprueba si las entradas tienen la etiqueta 'content' y si es así, suman 1
a la variable count.
Ahora tu bucle se parecerá a esto:
1 |
// Check for posts in the first loop.
|
2 |
$count = 0; |
3 |
while ( have_posts() ) : the_post(); |
4 |
|
5 |
// check if there are any posts with the '' tag
|
6 |
$tag = 'content'; |
7 |
if ( has_tag( $tag ) ) { |
8 |
$count +=1; |
9 |
}
|
10 |
|
11 |
endwhile; |
El Segundo Bucle: Mostrar las Entradas Con la Etiqueta
El siguiente paso es ejecutar un bucle par mostrar las entradas con esa etiqueta, pero solo si hay alguna, e.j. si el valor de $count
es mayor que 0
.
Añade esto debajo de tu primer bucle:
1 |
if ( $count > 0 ) { |
2 |
|
3 |
rewind_posts(); |
4 |
|
5 |
echo '<h2>Posts tagged with ' . $tag . '</h2>'; |
6 |
|
7 |
|
8 |
while ( have_posts() ) : the_post(); |
9 |
|
10 |
if ( has_tag( $tag ) ) { |
11 |
get_template_part( 'includes/loop', 'category'); |
12 |
}
|
13 |
|
14 |
// End the loop.
|
15 |
endwhile; |
16 |
|
17 |
}
|
Esto comprueba que $count
es mayor que cero y si es así, resetea las entradas y ejecuta de nuevo el bucle. Por cada entrada comprueba si la entrada tiene la etiqueta y, si es así, llama a la parte de la plantilla que acabamos de crear.
El Tercer Bucle: Mostar el Resto de Nuestras Entradas
El bucle final mostrará las entradas que queden. Si esta categoría no tiene ninguna entrada con la etiqueta 'content', entonces mostrará todas las entradas de la categoría.
Después de tu segundo bucle, añade esto:
1 |
rewind_posts(); |
2 |
|
3 |
|
4 |
// Second Loop - posts not with the 'content' tag
|
5 |
while ( have_posts() ) : the_post(); |
6 |
|
7 |
if ( !has_tag( $tag ) ) { |
8 |
get_template_part( 'includes/loop', 'category'); |
9 |
}
|
10 |
|
11 |
// End the loop.
|
12 |
endwhile; ?> |
Esto rebobina las entradas (que has echo la primera vez si no había entradas con la etiqueta o la segunda vez si sí había), y entonces ejecuta de nuevo el bucle. Esta vez comprueba si una entrada no tiene la etiqueta 'content' y entonces la muestra usando nuestra parte de plantilla.
El Archivo Final
Ahora prueba el fichero de página de categoría en tu sitio web.
Si estás utilizando el Wordpress test unit data como yo, encontrarás que la categoría 'Markup' tiene entradas con la etiqueta 'content'. Aquí está la página de archivo de categoría de la categoría 'Markup' en mi sitio web:



Resumen
Ejecutando varios bucles desde con una consulta no es complicado. En lugar de resetear la consulta y crear una nueva, utilizas la función rewind_posts()
para rebobinar la consulta y ejecutarla de nuevo. Y en lugar de definir nuevos parámetros de consulta, usas etiquetas condicionales para especificar los posts que se mostrarán.
Nota importante: No caigas en la tentación de usar query_posts()
para modificar la consulta principal cuando hagas esto. Esto ralentizará tu sitio más que si usas varias consultas.
En este ejemplo hemos ejecutado dos bucles basados en la consulta principal, la cual guardamos utilizando WP_Query
para ejecutar dos consultas adicionales y reducirá la carga del servidor. Puedes aplicar esta técnica con una consulta que tu definas usando WP_Query
o con la consulta principal en otras páginas de archivo editando el fichero de plantilla apropiado.