WP desde cero (11): modificar el loop II

En esta entrada veremos cómo realizar consultas directas y cómo preparar loops secundarios mediante la clase WP_Query.

Roy Lichtenstein

archivado en: WordPress / 19 diciembre, 2012 / taller:

Seguimos con la serie de WordPress desde cero.

En la primera parte de este artículo vimos cómo modificar el loop principal con la función query_post() o, mejor, con un hook o gancho en pre_get_post. Pero no es suficiente.

A la que una web sea un poco compleja hay que usar más de un loop. Por ejemplo, en la portada de esta web, además del loop principal, tengo otro en la parte superior para mostrar el último artículo y otro más en el sidebar para las microentradas. Para estos loops secundarios hay que usar la clase WP_Query.

Antes de ver cómo funciona es importante saber un detalle de la programación orientada a objetos (poo). Como ya sabemos, una función es un conjunto de instrucciones que se pueden usar en cualquier parte de una web. Cuando escribimos the_content(), por ejemplo, estamos invocando una función que lanza una consulta a la base de datos y devuelve el resultado en código HTML.

Hay un tipo especial de funciones llamadas clases, que son como una especie de superfunciones que no se pueden usar directamente, sino a través de copias. Es decir, primero hay que definir una instancia o copia de la clase y luego ya se puede emplear como si fuera una función normal. Para eso se utiliza la palabra clave new.

  • $instancia de la clase = new clase;

Sabiendo esto, nos resultará más fácil trabajar con la clase WP_Query. (Ver explicación más detallada sobre la programación orientada a objetos).

3. WP_Query

La sintaxis básica para estos loops secundarios es:

  1. <?php
  2. $the_query = new WP_Query( $args );
  3. while ( $the_query->have_posts() ) : $the_query->the_post();
  4. // el loop...
  5. endwhile;
  6. // Reseteamos
  7. wp_reset_query();
  8. wp_reset_postdata();

El mecanismo es muy similar al loop normal, solo que antes se instancia la clase WP_Query y luego en el bucle, en vez de emplear directamente las funciones have_post() y the_post(), se usan como métodos de la clase, esto es, anteponiendo el nombre de la instancia, en el ejemplo $the_query, con el operador ->.

Al final, líneas 7 y 8, es muy importante resetear la query, pues de lo contrario los demás loops se verán afectados.

Como ocurría con query_post(), podemos indicar los parámetros de la consulta directamente o usando un array. Por ejemplo, así indicaríamos directamente que nos tiene que devolver los primeros 3 post de la categoría 3 (fijaos que los parámetros se indican entre comillas simples).

  • $query_post = new WP_Query ('cat=3&posts_per_page=3');

En cambio, de la segunda manera, primero se define un array y luego se envía a la consulta. (Se puede definir directamente el array, pero así es más limpio). Así, en el mismo caso anterior podríamos haber escrito:

  • $consulta = array (
  • 'cat' => '3',
  • 'posts_per_page' => '1'
  • );
  • $query_post = new WP_Query( $consulta );

Observad que en este caso, como estamos utilizando un array, el parámetro se indica sin comillas.

Además, en algunos parámetros del array hay que utilizar otro array. Por ejemplo, así seleccionaríamos todos los post menos los id definidos en post__not_in:

  • $consulta = array (
  • 'post_type' => 'post',
  • 'post__not_in' => array ( 2, 5, 12, 14, 20 )
  • );
  • $query = new WP_Query( $consulta );

4. Selección directa

Por último, también se puede hacer la selección directamente, para lo cual se necesita conocer MySQL, que es un lenguaje para trabajar con bases de datos. Si no es tu caso, sáltate lo que sigue.

Hay dos maneras de realizar una consulta: la forma salvaje y la wordpressiana. La primera no tiene mayor misterio. Se lanza la consulta en mysqli igual que cualquier otra. Es decir, preparas la conexión y ya haces la consulta que sea como siempre contra cualquier tabla de WordPress:

  • <?php
  • $dbhost = 'host';
  • $dbuser = 'usuario';
  • $dbpass = 'contraseña';
  • $dbname = 'nombre de la base de datos';
  • $link_id = new mysqli($dbhost,$dbuser,$dbpass,$dbname);
  • if ($link_id ->connect_error) {
  • echo "Error de Connexion ($link_id->connect_errno)
  • $link_id->connect_error\n";
  • exit;
  • $resultado = $link_id->query("SELECT * FROM posts....
  • }
  • ?>

No hay ninguna razón real para no usar estas consultas directas si se necesitan, pero solo se pueden hacer sobre un WordPress del que se conocen los datos de conexión (recuperar los que vienen en el config es un quilombo) y, además, no permite interactuar con las funciones normales de WP.

No sucede lo mismo si hacemos la consulta de manera más civilizada, es decir, usando el wordpressiano y para eso hay que utilizar una clase denominada $wpdb, cuya sintaxis básica es esta:

  • global $wpdb;
  • $mi_consulta = query( $consulta );

Donde global $wpdb es una manera de declarar una variable global que sirve para acceder a los métodos de la clase $wpdb. Es decir, para el caso es como si hubiéramos escrito esto:

  • $wpdb = new $wpdb();

$mi_consulta o cómo se quiera llamar es el array donde se guardan los resultados; query es un método para recibir o manipular la base de datos y $consulta la query. Por ejemplo, así sacaríamos las primeras 10 entradas de la tabla post, que es donde se guardan (ver tablas de WP).

  • global $wpdb;
  • $mi_consulta = $wpdb->get_results("SELECT * FROM $wpdb->posts LIMIT 1");

Luego solo tenemos que recorrer el array con un foreach. Así, por ejemplo, sacaríamos los títulos:

  • foreach ($mi_consulta as $mi_consulta) {
  • echo $mi_consulta->post_title;
  • }

Y así los resúmenes

  • foreach ($mi_consulta as $mi_consulta) {
  • echo $mi_consulta->post_excerpt;
  • }

Los principales métodos o tipos de queries para seleccionar resultados, es decir, para usar con la sentencia SELECT, son:

  1. $wpdb->get_results: devuelve los resultados de la consulta.
  2. $wpdb->get_row: devuelve la fila que se corresponde a la consulta. Por ejemplo: $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10").
  3. $wpdb->get_col: devuelve una columna.

Bueno, habría mucho más que analizar sobre la clase $wpdb, como la inserción o el borrado de datos, pero es algo que escapa al objeto de esta entrada, que es el loop. Otro día preparo una entrada sobre el tema, que ahora no tiene mucho sentido tratarlo.

En síntesis de estas dos entradas: para manipular el loop principal, lo mejor es usar un hook y para añadir loops secundarios, la clase WP_Query. En el próximo post de esta serie veremos algunos ejemplos prácticos y ya en el siguiente pasamos al sidebar y los menús.

Abrazos++;

|| Tags: , , ,

valoración de los lectores sobre WP desde cero (11): modificar el loop II

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 4.6 sobre 5 (5 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

2 respuestas a “WP desde cero (11): modificar el loop II

  1. Note: If you use the_post() with your query, you need to run wp_reset_postdata() afterwards to have Template Tags use the main query’s current post again.