Si utilizas WordPress a menudo, sabrás que es difícil filtrar entradas por varios parámetros simultáneamente; tales como etiquetas, categorías o custom post types.

Al menos es complicado con las herramientas que nos facilita WordPress por defecto.

Pero como he comentado en otras ocasiones, la evolución de WordPress es clara y sus desarrolladores han incluido herramientas para hacer este tipo de filtrados mucho más sencillos para nosotros; gracias a wp_query() podemos filtrar los contenidos de WordPress con cualquier criterio que se nos ocurra.

¿Qué es WP_Query?

WP_Query es una clase, una de las más importantes del núcleo de WordPress. Se encarga de determinar la consulta necesaria a la base de datos de acuerdo a la información que se está solicitando y, además, guarda este tipo de consultas frecuentes para optimizar la carga de la página.

Por otro lado, se encarga de permitirnos a los desarrolladores realizar consultas a la base de datos de una forma segura y sencilla, sin alterar el código de WordPress ni hacer “virguerías“.

Seguridad

Esta función nos permite, como dije antes, solicitar contenidos a la base de datos siguiendo una serie de criterios bastante complejos, pero lo hace protegiendo nuestro sistema de ataques SQL así como otro tipo de inseguridades que, de programarlo nosotros desde cero, habría más riesgo de dejar al descubierto.

Sencillez

Esta clase genera un objeto y nos evita tener que conocer la base de datos a fondo. Todo “habla por sí mismo”, no hace falta conocer el código interno de WordPress, ni las relaciones de la base de datos, ni nada por el estilo.

Olvídate también de hacer las consultas a la base de datos a mano; limítate a crear los argumentos (como veremos más adelante) que le pasarás a WP_Query y llama a la clase.

¿Cómo funciona WP_Query?

El loop de WordPress por defecto

Para entender el funcionamiento de WP_Query, vamos a ver cómo es un loop estándar:

<?php
   if(have_posts()) :
      while(have_posts()) :
         the_post();
?>
         <h1><?php the_title() ?></h1>
         <div class='post-content'><?php the_content() ?></div>
<?php
      endwhile;
   else :
?>
      Vaya, no hay entradas.
<?php
   endif;
?>

El mismo loop con WP_Query

<?php
   $args = array('cat' => 4);
   $category_posts = new WP_Query($args);
 
   if($category_posts->have_posts()) :
      while($category_posts->have_posts()) :
         $category_posts->the_post();
?>
         <h1><?php the_title() ?></h1>
         <div class='post-content'><?php the_content() ?></div>
<?php
      endwhile;
   else:
?>
      Vaya, no hay entradas.
<?php
   endif;
?>

Sí, es diferente, ¿verdad? Vamos a ver estas diferencias:

  1. Construir la consulta
    En una página de categoría por defecto (por ejemplo category.php), WordPress sabe que ha de mostrar las entradas de esa categoría. Al hacerlo con WP_Query, debemos indicar la categoría nosotros mismos. Tranquilo, veremos esto mejor más adelante.
  2. Inicializar WP_Query y consultar
    Cuando inicializamos WP_Query con el array de argumentos, esto colocará tanto las entradas correspondientes a dicha consulta como otras cosas.
  3. Creando el loop
    Aquí puedes utilizar todas las funciones que usas normalmente, sólo tienes que tratarlo como un objeto en vez de llamarlas directamente; fíjate en los ejemplos siguientes:

    • $category_posts->have_posts() en vez de have_posts().
    • $category_posts->the_post() en vez de the_post().
  4. Trabaja como siempre
    Una vez que has entendido el punto anterior (incluir $category_posts-> delante de las funciones de WordPress) puedes trabajar con total normalidad; como lo has hecho siempre.
  5. No obstante, la variable global $post está también disponible. Esto significa que puedes si utilizas un loop personalizado como el del ejemplo anterior peligra que tengas problemas. Asegúrate de guardar el valor de esa variable global antes de utilizar un loop personalizado con WP_Query para después restaurarlo a su estado original:

    <?php
       $temp_post = $post; // Guardamos el objeto de $post temporalmente
       $my_query = new WP_Query();
       while($my_query->have_posts()) {
          // Aquí va el loop
       }
       $post = $temp_post; // Restauramos el valor original del $post original.
    ?>

    Valores por defecto

    Como todo, WP_Query tiene unos valores por defecto que deberás tener en cuenta si lo utilizas:

    • posts_per_page: valor por defecto que define el número de entradas a mostrar.
    • post_type: siempre será “post” por defecto, hay que agregar o modificar si queremos utilizarlo con custom post types.
    • post_status: mostrará los que tengan una visibilidad “pública” por defecto.

    Puedes leer más sobre los parámetros en el Codex.

    Consejos finales

    WP_Query te permite hacer muchas cosas, modificar y utilizar WordPress como un framework de desarrollo dejando su facilidad de uso intacta, pero ¡cuidado! Puede traer muchos problemas si se utiliza mal.

    Si hacemos que WP_Query realice consultas muy pesadas en un servidor compartido (de esos baratitos) es posible que nos comamos la memoria RAM del servidor y nos llamen la atención (o, peor aún, nos echen la web abajo para prevenir la caída total del servidor).

    Mantén siempre presente que más consultas a la base de datos (o ficheros o consultas en general) conllevan un mayor consumo de recursos dentro del servidor.

    Como consejo final, mantén presente siempre el tipo de consulta por defecto que realiza WordPress en una página, ¿para qué vamos a utilizar WP_Query para traer las últimas entradas del blog a la portada si es algo que ya está ahí por defecto?

    Ahora ya sabes, investiga y prueba cómo WordPress ya no tiene tantos límites como antes.

    Si te ha gustado compártelo en las redes sociales y no dudes en dejar un comentario de agradecimiento o con tus dudas.

6 comentarios en “WP_Query, sacándole jugo a WordPress

  1. Buenas de nuevo Dario, podrias enlazar este tema con el de “Custom Post Types y Taxonomías en WordPress, la forma correcta” para mostrar, por ejemplo, los libros, con una consulta, en una nueva plantilla?
    Gracias un saludo

    1. Hola Juan, para eso no necesitas WP_Query, basta con crear una variable php inicializada a 1 y que incremente su valor en cada paso por el loop. Cuando su valor sea 1 le aplicas la clase “destacado” o la que quieras con los estilos diferentes al resto y si no una clase común al resto.

      Saludos y feliz año.

      1. gracias por la respuesta Darío.

        soy diseñador y el PHP se me escapa un poco, buscaré algo más de información para saber cómo escribir lo que dices.

        te deseo buen año también,

        saludos!

  2. Excelente, puedes cambiar el límite establecido en “Ajustes de lectura” del número de entradas a mostrar, por el que desees configurando el argumento posts_per_page, asi:

    $args = array (
    ‘post_type’ => ‘profesionales’,
    ‘post_status’ => ‘publish’,
    ‘order’ => ‘DESC’,
    ‘posts_per_page’ => 50,
    );

    $query = new WP_Query( $args )

    Saludos y Gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *