WP_Query en WordPress: qué es y cómo se usa (Parte 3)

En esta tercera parte de WP_Query en WordPress estudiaremos los parámetros relacionados con los comentarios. Veremos cómo filtrar publicaciones según el número de comentarios, ordenar resultados por popularidad y trabajar con la información de comentarios dentro de nuestras consultas.

En el fichero page-wp-query.php dejemos el elemento <li> como estaba antes de incluir los fragmentos de código que añadimos en el tema anterior.

   
   <li>
      <a href="<?php echo esc_url( the_permalink() ); ?>">
         <?php echo esc_html( the_title() ); ?>
      </a>
   </li>


   $args = [
      'post_type' => 'post',
      'posts_per_page' => 5,
      'paged' => $paged,
      'post_status' => 'publish',
      
      'comment_count' => [
         'value' => 0,
         'compare' => '>',
      ],
   ];

Se indica que únicamente se mostrarán entradas cuyo número de comentarios sea mayor que 0.


   $args = [
      'post_type' => 'post',
      'posts_per_page' => 5,
      'paged' => $paged,
      'post_status' => 'publish',
      // Mostrar solo entradas sin comentarios
      'comment_count'  => 0,
   ];

Nos aparecen 50 entradas que, sumadas a las 6 del ejemplo anterior, dan un total de 56 publicaciones, que son exactamente las entradas que tenemos publicadas en WordPress.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'comment_count' => [
         'value' => 3,
         'compare' => '>',
      ],
   ];

WordPress mostrará únicamente las entradas que tengan más de 3 comentarios.

Es prácticamente igual al ejemplo anterior; únicamente cambia el operador matemático de comparación.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'comment_count'  => [
         'value' => 6,
         'compare' => '>=',
      ],
   ];


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 10,
      'paged' => $paged,
      'orderby' => 'comment_count',
      'order' => 'DESC'
   ];

WordPress mostrará primero las entradas con mayor número de comentarios.

Para esta consulta nos encontramos con una limitación de WP_Query: el parámetro comment_count no permite filtrar por rangos de comentarios.
Para solucionarlo utilizaremos el filtro posts_clauses junto con una función personalizada que modificará directamente la consulta SQL.

La función personalizada la podemos integrar en el propio fichero, por ejemplo al inicio del fichero page-wp-query.php, colocarla en el fichero functions.php o incluso incluirla dentro de un plugin personalizado

Si observamos el listado de entradas veremos que la mayoría tienen muy pocos comentarios. Sin embargo, existen publicaciones que cuentan con 5 comentarios y otras con 19, así que utilizaremos el rango comprendido entre 5 y 19 comentarios.


   function filtrar_comentarios_entre_rango( $clauses, $query ) {
       global $wpdb;

       // Solo aplicar a esta query
       if ( $query->get( 'comentarios_entre' ) ) {
           
           $clauses['where'] .= $wpdb->prepare(
               " AND {$wpdb->posts}.comment_count BETWEEN %d AND %d",
               5, 19
           );
       }
       return $clauses;
   }

No olvidemos eliminar el filtro después de la consulta:
remove_filter( ‘posts_clauses’, ‘filtrar_comentarios_entre_rango’, 10 );


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'comentarios_entre' => true,
   ];

Al utilizar el filtro posts_clauses estamos modificando directamente la consulta SQL que genera WordPress, lo que nos permite superar algunas limitaciones nativas de WP_Query.

Otra de las grandes ventajas de WP_Query es que podemos combinar los parámetros relacionados con comentarios junto con otros argumentos de la consulta.
Esto nos permite crear filtros mucho más precisos y dinámicos.

Para este ejemplo quizás convenga dales algunos comentarios a algunas entradas, yo me limitaré a usar los que ya existen.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'comment_count' => [
         'value' => 0,
         'compare' => '>',
      ],
      // Rango de fechas
      'date_query' => [
         [
            'after' => '2012-01-01',
            'before' => '2023-02-01',
            'inclusive' => true,
         ],
      ],
   ];

Como actualmente no tenemos publicaciones destacadas, voy a marcar como destacadas tres entradas cualquiera: una con comentarios y las otras dos sin comentarios, para realizar las pruebas.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      // Mostrar solo entradas destacadas
      'post__in' => get_option( 'sticky_posts' ),

      'ignore_sticky_posts' => 1,
   ];


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'post__in' => get_option( 'sticky_posts' ),
      //Solo entradas con comentarios
      'comment_count' => [
         'value' => 0,
         'compare' => '>',
      ],
      'ignore_sticky_posts' => 1,
   ];

   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'author_name' => 'pepitoperez',
      'comment_count' => [
         'value' => 0,
         'compare' => '>',
      ],
      'orderby' => 'comment_count',
      'order' => 'DESC',
   ];

Todos los ejemplos vistos hasta ahora funcionan igualmente con entradas, páginas, CPT y cualquier otro tipo de contenido registrado en WordPress.

Los parámetros de paginación en WP_Quey nos permiten dividir los resultados de una consulta en varias páginas.
Estos parámetros hacen referencia a la paginación de entradas o de cualquier otro tipo de contenido de WordPress, como páginas o CPT.

Al hablar de paginación, seguramente nos viene a la cabeza el apartado Ajustes → Lectura de WordPress, donde podemos definir el número máximo de publicaciones que se mostrarán por página.

Es posible que algunos de los argumentos de búsqueda ya los hayamos visto anteriormente, pero volveremos a repasarlos para mantener una estructura didáctica y ordenada en la entrada.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => -1,
   ];


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'paged' => $paged,
      'posts_per_page' => 6,
   ];


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,
      'offset' => 3,
   ];

Compruébalo accediendo al listado de entradas y verás que el parámetro funciona correctamente.

Debemos tener cuidado al combinar offset y paged, ya que una configuración incorrecta puede provocar errores en la paginación, como páginas vacías, resultados repetidos o un número incorrecto de páginas.

El número de páginas de la paginación dependerá del valor configurado en Ajustes → Lectura.
En nuestro caso estableceremos 3, lo que significa que cada página de la paginación mostrará únicamente tres entradas.



   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 3,
      'paged' => $paged = 3,
   ];

En paged hemos colocado directamente el valor:
‘paged’ => $paged = 3,
aunque es más recomendable definir primero la variable:
$paged = 3,
y posteriormente utilizarla dentro de los argumentos.

La paginación personalizada es uno de los apartados más interesantes de WP_Query, porque nos permite crear nuestra propia navegación entre páginas en lugar de depender únicamente de la paginación automática de WordPress.

Gracias a ella podemos:

  • mostrar enlaces numerados,
  • crear botones “Anterior” y “Siguiente”,
  • personalizar el diseño de la paginación,
  • cambiar textos,
  • añadir clases CSS,
  • o adaptar completamente la navegación al diseño del proyecto.

La paginación personalizada es fundamental cuando trabajamos con consultas personalizadas, ya que WordPress no siempre genera automáticamente la navegación entre páginas.

Si creamos una paginación personalizada normalmente debemos evitar mostrar también la paginación automática del tema, porque terminarías teniendo dos paginaciones distintas, o bien generando un error.


   <div class="mi-paginacion">

       <?php
       echo paginate_links( [

         'total' => $the_query->max_num_pages,
         'current' => max( 1, get_query_var( 'paged' ) ),

         'prev_text' => '← Atrás',
         'next_text' => 'Adelante →',

       ] );
       ?>

   </div>

   .mi-paginacion {
       margin-top: 30px;
   }

   .mi-paginacion a,
   .mi-paginacion span {
       padding: 5px 10px;
   }

Podemos dar estilos y adaptar completamente la navegación al diseño del proyecto.

Como norma, la paginación deberíamos colocarla después del cierre del bucle while y antes de finalizar la condición if.

Puedes ampliar conocimientos visitando:

Los parámetros de fecha y hora en WP_Quey nos permiten filtrar publicaciones utilizando información temporal relacionada con:

  • años, meses, días,
  • horas, minutos, segundos,
  • rangos de fechas,
  • incluso publicaciones anteriores,
  • o posteriores a una fecha concreta.

Gracias a estos parámetros podemos:

  • mostrar entradas publicadas este año,
  • obtener publicaciones de un mes concreto,
  • crear archivos personalizados,
  • mostrar contenido reciente,
  • filtrar entradas antiguas,
  • o construir consultas cronológicas avanzadas.

Eliminemos la paginación personalizada del apartado anterior y volvamos a la paginación nativa de WordPress.

Eliminemos todas las entradas que tengamos marcadas como fijas o destacadas.


   $args = [
      'post_type'      => 'post',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'date_query' => [
         [
            'year' => $current_year,
         ],
      ],
   ];

Como ves, date_query funciona como una subconsulta dentro de WP_Query, permitiéndonos filtrar publicaciones por año, mes, día y otros parámetros de fecha.


   $args = [
      'post_type'      => 'post',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'date_query' => [
         [
            'month' => 5,
         ],
      ],
   ];

Nos aparecerán todas las entradas creadas durante el mes de mayo, independientemente del año en que hayan sido publicadas.

Para disponer de varias publicaciones en una fecha específica, vamos a modificar la fecha de las entradas Post Format: Link, Post Format: Chat y Post Format: Quote, asignándoles la fecha 11/02/2023.



   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',   
      'posts_per_page' => 5,
      'paged' => $paged,
      
      'date_query' => [
         [
            'year' => 2023,
            'month' => 2,
            'day' => 11,
         ],
      ],
   ];

Como actualmente no tenemos ninguna publicación creada hoy, vamos a generar dos entradas llamadas Entrada 121/05/206 y Entrada 221/05/2026.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'date_query' => [
         [
            'year'  => date( 'Y' ),
            'month' => date( 'm' ),
            'day'   => date( 'd' ),
         ],
      ],
   ];

La pregunta que podemos hacernos es ¿de donde salen year, month y day?

Esos datos los tenemos dentro de getdate().

Coloquemos dentro de nuestro fichero:

   
   <?php 
   echo '<pre>';
   print_r( getdate() );
   echo '</pre>';
   ?>

Vemos que getdate() nos devuelve todos los datos correspondientes al día actual: segundos, minutos, horas, día del mes, mes, días transcurridos del año, nombre del día de la semana y nombre del mes.

De todos ellos hemos seleccionado únicamente los que necesitamos:

  • año → year
  • mes → mon
  • día → mday

Pero en los argumentos no utilizamos ni mon ni mday, utilizamos month y day, eso se debe a que en los argumentos utilizamos date_query y tenemos:

getdate() utiliza mday, mon y year
date_query utiliza day, month y year

Si trabajamos directamente con getdate() debemos utilizar los nombres de variables que devuelve dicha función.


   // Obtener dato de fecha
   $fecha = getdate();

   //Mostrar día, mes y año
   echo 'Día ' . $fecha['mday'] . '<br>';
   echo 'Mes ' . $fecha['mon'] . '<br>';
   echo 'Año ' . $fecha['year'] . '<br>';


   // Obtener dato de fecha
   $fecha = getdate();

   $args = [
      'post_type' => 'post',
      'date_query' => [
          [
            'year'  => $fecha['year'],
            'month' => $fecha['mon'],
            'day'   => $fecha['mday'],
          ],
      ],
   ];

Al realizar el filtrado obtendremos prácticamente los mismos resultados que en el ejercicio anterior.
Por ello, vamos a modificar la fecha de la entrada Hola mundo resuelto y asignarle un día perteneciente a esta semana; en mi caso la cambiaré al lunes 18.


   $args = [
      'post_type'      => 'post',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'date_query' => [
         [
            'year' => date( 'Y' ),
            'week' => date( 'W' ),
         ],
      ],
   ];


   $args = [
      'post_type'      => 'post',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      
      'date_query' => [
         [
            'hour'    => 12,
            'compare' => '>=',
         ],
         [
            'hour'    => 13,
            'compare' => '<=',
         ],
      ],
   ];

Entiéndase que se filtraran todas las entradas independientemente del día, mes o año de publicación.


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'date_query' => [
         [
            'year' => 2009,
         ],

         [
            'hour' => 12,
            'compare' => '>=',
         ],

         [
            'hour' => 13,
            'compare' => '<=',
         ],
      ],
   ];


   $args = [
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'date_query' => [
         [
            'before' => '2022-01-01',
            'inclusive' => true,
         ],
      ],
   ];


   $args = [
      'post_type'      => 'post',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'date_query' => [
         [
            'after'     => '2023-12-31',
            'column'    => 'post_modified',
            'inclusive' => false,
         ],
      ],
   ];

Puedes ampliar conocimientos visitando:

Los parámetros de taxonomías personalizadas en WP_Query nos permiten filtrar publicaciones utilizando:

  • categorías personalizadas,
  • etiquetas personalizadas,
  • o cualquier taxonomía creada manualmente.

Este tipo de consultas es muy habitual cuando trabajamos con:

  • libros,
  • productos,
  • películas,
  • cursos,
  • portfolios,
  • o cualquier CPT que utilice taxonomías personalizadas.

Se utiliza mediante: tax_query

Gracias a tax_query podemos:

  • mostrar publicaciones de una taxonomía concreta,
  • combinar varias taxonomías,
  • excluir términos,
  • crear relaciones AND / OR,
  • filtrar CPT,
  • o construir sistemas avanzados de filtrado.

Para esta lección vamos a crear un nuevo CPT con el plugin Custom Post Type UI. Va a tener como slug la palabra books y como título libro.

Tendremos que crear varios libros y, para cada uno de ellos, crearemos dos taxonomías personalizadas:

  • Autores, que funcionará como las etiquetas y cuyo slug será book_author.
  • Géneros, cuyo slug será book_genero y que será una taxonomía jerárquica, es decir, permitirá crear términos hijos, igual que ocurre con las categorías.

En realidad, es exactamente lo mismo que trabajar con categorías y etiquetas, solo que en este caso tendrán nombres distintos y estarán asociadas a un nuevo tipo de contenido llamado libro.

Los libros que vamos a dar de alta son:

  • La Celestina
    Autor: Fernando Rojas
    Géneros: Dramático, Novela, Sátira
  • La Regenta
    Autor: Leopoldo Alas
    Géneros: Ficción, Dramático, Tragedia, Ficción
  • Bodas de sangre
    Autor: Federico Garcia Lorca
    Géneros: Dramático, Novela, Misterio
  • La sombra del vientos
    Autor: Carlos Ruíz Zafón
    Géneros: Gótica, Misterio , Histórica, Sátira
  • Don Quijote de la Mancha
    Autor: Miguel de Cervantes Saavedra
    Géneros: Sátira, Ficción, Novela, Parodia

Por el momento lo que haremos es crear una WP_Query solo con estos datos.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,
   ];

Podéis añadir el siguiente código dentro del loop:


                <li>
                  <a href="<?php echo esc_url( get_permalink() ); ?>">
                    <?php echo esc_html( get_the_title() ); ?>
                  </a>
                  <?php 
                    the_terms( get_the_ID(), 'book_genero', ' - Género: ', ' / ' );
                    the_terms( get_the_ID(), 'book_author', ' - Autor: ', ' / ' );
                  ?>
                </li>

Veréis algo así:

Para los ejercicios, yo personalmente prefiero dejarlo como antes, esta forma el código queda más limpio y resulta más sencillo de seguir durante los ejercicios.

Observa que en lugar de utilizar meta_qyery o parámetros tradicionales de búsqueda, ahora usamos tax_query, ya que estamos trabajando con taxonomías personalizadas.

En este caso filtramos los libros pertenecientes al género Novela.

También es importante recordar que:

  • taxonomy hace referencia al slug de la taxonomía.
  • field indica el tipo de valor que utilizaremos para realizar el filtrado.
  • terms contiene el término o términos que queremos buscar.

   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_genero',
            'field' => 'slug',
            'terms' => 'novela',
         ],
      ],
   ];


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_genero',
            'field' => 'slug',
            'terms' => [ 'novela', 'misterio' ],
         ],
      ],
   ];

A medida que vayáis consultando los resultados, comprobaréis la exactitud de las consultas.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_author',
            'field'    => 'slug',
            'terms'    => 'fernando_rojas',
         ],
      ],
   ];

El operador NOT_IN permite excluir publicaciones pertenecientes a determinados términos de una taxonomía.

No busca coincidencias, sino todo lo contrario: elimina de los resultados las publicaciones que contengan dichos términos.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_genero',
            'field' => 'slug',
            'terms' => 'satira',
            'operator' => 'NOT IN',
         ],
      ],
   ];

La relación AND obliga a que todas las condiciones de la consulta se cumplan simultáneamente.

Es decir, WordPress solo mostrará los libros que pertenezcan a ambos géneros al mismo tiempo.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'tax_query' => [
         'relation' => 'AND',

            [
               'taxonomy' => 'book_genero',
               'field'    => 'slug',
               'terms'    => 'dramatico',
            ],

            [
               'taxonomy' => 'book_genero',
               'field'    => 'slug',
               'terms'    => 'tragedia',
            ],
         ],
      ];

La relación OR nos permite mostrar publicaciones que cumplan cualquiera de las condiciones indicadas.

Basta con que se cumpla una sola condición para que la publicación aparezca en los resultados.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'tax_query' => [
         'relation' => 'OR',

         [
            'taxonomy' => 'book_genero',
            'field' => 'slug',
            'terms' => 'dramatico',
         ],

         [
            'taxonomy' => 'book_genero',
            'field' => 'slug',
            'terms' => 'satira',
         ],
      ],
   ];



   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_author',
            'field'    => 'slug',
            'terms'    => [ 
              'fernando_rojas',
              'leopoldo_alas' 
            ],
         ],
      ],
   ];

Para este tipo de consultas necesitamos conocer previamente los IDs internos de los términos que vamos a utilizar en el filtrado.

Ya comentamos anteriormente que, si colocamos el puntero del ratón sobre el nombre de un libro dentro del administrador, en la parte inferior izquierda del navegador aparecerá una URL donde podremos localizar su ID.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'post__in' => [ 1906, 1907 ],
   ];

Filtraremos utilizando las taxonomías Dramático y Novela, cuyos IDs internos son 205 y 206 respectivamente.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'tax_query' => [
         [
            'taxonomy' => 'book_genero',
            'field'    => 'term_id',
            'terms'    => [ 205, 206 ],
         ],
      ],
   ];

Puedes ampliar conocimientos visitando:

Los campos personalizados en WordPress permiten almacenar información adicional asociada a una publicación.

Esa información puede ser prácticamente

cualquier cosa:

  • precios,
  • colores,
  • fechas,
  • autores,
  • valoraciones,
  • ISBN,
  • stock,
  • idiomas,
  • y un largo etc…

Gracias a los campos personalizados podemos convertir WordPress en:

  • una tienda,
  • un catálogo,
  • una biblioteca,
  • un portfolio,
  • un directorio,
  • o prácticamente cualquier tipo de aplicación

Internamente, WordPress almacena estos datos en la tabla: wp_postmeta.

Usa pares de: clave => valor. Por ejemplo: book_price => 19.95

Actualmente la mayoría de proyectos utilizan el plugin Advanced Custom Fields ya que facilitan enormemente la creación y gestión de campos personalizados desde el administrador.

Así que instala el plugin y comenzamos.

Vamos a crear un nuevo grupo de campos llamado Detalles de un libro, donde añadiremos los siguientes campos personalizados:

EtiquetaNombreTipo
Disponible en ebbokbook_sbookVerdadero/Falso
Preciobook_priceNúmero
Best Sellerbook_bsVerdadero/Falso
Destacadobook_featuredVerdadero/Falso
Idiomas disponiblesbook_languagesCasilla de verificación

Para los idiomas en Opciones tenemos:

  • Inglés : inglés
  • Español : español
  • Catalán : catalán
  • Francés francés

En todos los campos posible elegimos la opción UI Estilizada.

Se lo asignamos al Post Type Libro.

En cada libro daremos estos valores a cada uno de los campos

  • Libro: La Celestina
    • Disponible en ebbok: NO
    • Best Seller: NO
    • Precio: 15
    • Destacado: No
    • Idiomas disponibles: Español – Catalán
  • Libro: La Regenta
    • Disponible en ebbok: Si
    • Best Seller: NO
    • Precio: 12,50
    • Destacado: Si
    • Idiomas disponibles: Español – Catalán
  • Libro: Bodas de sangre
    • Disponible en ebbok: NO
    • Best Seller: Si
    • Precio: 15,95
    • Destacado: Si
    • Idiomas disponibles: Español – Francés
  • Libro: La sombra del viento
    • Disponible en ebbok: Si
    • Best Seller: Si
    • Precio: 29,35
    • Destacado: No
    • Idiomas disponibles: Francés – Catalán
  • Libro: Don Quijote de la Mancha
    • Disponible en ebbok: Si
    • Best Seller: Si
    • Precio: 27
    • Destacado: Si
    • Idiomas disponibles: Español – Inglés

Una vez añadidos los nuevos campos personalizados y completados los datos de cada libro, ya tenemos todo preparado para comenzar a trabajar con meta_query en las siguientes lecciones.

En esta segunda parte de los campos personalizados veremos cómo mostrar esos campos dentro del Loop de WordPress.

Hasta ahora hemos aprendido a filtrar publicaciones utilizando:

  • meta_query
  • tax_query

Con los campos personalizados también pueden mostrarse directamente en pantalla utilizando funciones como:

  • get_field()
  • the_field()
  • get_post_meta()

Gracias a ello podremos visualizar información adicional de cada libro, como:

  • precio,
  • idiomas,
  • disponibilidad en ebook,
  • libros destacados,
  • o Best Sellers.

Esto convierte a WordPress en un sistema mucho más dinámico y flexible, permitiéndonos construir catálogos, tiendas, bibliotecas o cualquier tipo de aplicación personalizada.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_query' => [
         [
            'key' => 'book_sbook',
            'value' => 1,
            'compare' => '=',
         ],
      ],
   ];

Estos mismos argumentos pero cambiando la key vale para filtra por:

  • Filtrar libros Best Seller
  • Filtrar libros destacados

Cabe decir que, en ocasiones, el tipo numérico no es suficiente para trabajar correctamente con valores decimales.

En esos casos podemos utilizar: DECIMAL( 20, 2).

Indicando entre paréntesis el número total de dígitos y la cantidad de decimales.


  $args = [
     'post_type' => 'libro',
     'post_status' => 'publish',
     'posts_per_page' => 5,
     'paged' => $paged,

     'meta_query' => [
        [
           'key' => 'book_price',
           'value' => 29.35,
           'compare' => '=',
           'type' => 'DECIMAL(10, 2)',
        ],
     ],
  ];


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_query' => [
         [
            'key' => 'book_price',
            'value' => 15,
            'compare' => '>',
            'type' => 'DECIMAL(10,2)',
         ],
      ],
   ];



   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'meta_query' => [
         [
            'key'     => 'book_price',
            'value'   => 16,
            'compare' => '<',
            'type'    => 'DECIMAL(10,2)',
         ],
      ],
   ];


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_query' => [
         [
            'key' => 'book_price',
            'value' => [ 15, 30 ],
            'compare' => 'BETWEEN',
            type' => 'DECIMAL(10,2)',
         ],
      ],
   ];

‘compare’ => ‘BETWEEN’, devuelve todos los libros cuyos precios estén entre 15 y 30, incluyendo también los dos valores extremos de la consulta.

Si queremos excluir los valores extremos de la búsqueda, no podremos utilizar: ‘compare’ => ‘BETWEEN’.

Tendremos que realizar la comparación manualmente utilizando la relación: AND.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_query' => [
         'relation' => 'AND',

         [
            'key' => 'book_price',
            'value' => 15,
            'compare' => '>',
            'type' => 'DECIMAL(10,2)',            
         ],

         [
            'key' => 'book_price',
            'value' => 30,
            'compare' => '<',
            'type' => 'DECIMAL(10,2)',
         ],

      ],

   ];


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'meta_query' => [
         [
            'key'     => 'book_languages',
            'value'   => 'ingles',
            'compare' => 'LIKE',
         ],
      ],
   ];

La relación OR permite mostrar los libros que contengan cualquiera de los idiomas utilizados en la consulta.


   $args = [
      'post_type'      => 'libro',
      'post_status'    => 'publish',
      'posts_per_page' => 5,
      'paged'          => $paged,

      'meta_query' => [
         'relation' => 'OR',

         [
            'key'     => 'book_languages',
            'value'   => 'espanol',
            'compare' => 'LIKE',
         ],

         [
            'key'     => 'book_languages',
            'value'   => 'ingles',
            'compare' => 'LIKE',
         ],
      ],
   ];

La relación AND permite mostrar únicamente los libros que contengan ambos idiomas utilizados en la consulta.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_query' => [
         'relation' => 'AND',

         [
            'key' => 'book_languages',
            'value' => 'espanol',
            'compare' => 'LIKE',
         ],

         [
            'key' => 'book_languages',
            'value' => 'catalan',
            'compare' => 'LIKE',
         ],
      ],
   ];

Por defecto WordPress guarda los campos personalizados como texto.

Es decir, cualquier valor numérico que pongamos será considerado texto

Con meta_value_num le decimos que los convierta en números.

Por eso cuando trabajamos con precios, cantidades, edades o cualquier dato numérico debemos utilizar:
‘orderby’  => ‘meta_value_num’.


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_key' => 'book_price',
      'orderby' => 'meta_value_num',
      'order' => 'ASC',
   ];


   $args = [
      'post_type' => 'libro',
      'post_status' => 'publish',
      'posts_per_page' => 5,
      'paged' => $paged,

      'meta_key' => 'book_featured',
      'orderby' => 'meta_value_num',
      'order' => 'DESC',
   ];

book_featured contiene como valor 0 o 1, ya sabemos que WordPress guarda los números como cadenas de texto, así que los convertimos en números meta_value_num con para realizar una ordenación numérica correcta.

Puedes ampliar conocimientos visitando: