Advertisement
  1. Code
  2. WordPress

Cómo Implementar Varios Bucles con Una Sóla Consulta a la Base de Datos

Scroll to top
Read Time: 9 min

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.php 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:

The category page with two loopsThe category page with two loopsThe category page with two loops

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.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.