Consultas personalizadas de WordPress: uso de la clase WP_Query

Publicado: 2021-02-06

WordPress ofrece una amplia gama de funciones listas para usar que, en la mayoría de los casos, pueden recuperar la información necesaria de la base de datos. Pero cuando se desarrolla un sitio web de WordPress, existen numerosos escenarios en los que un filtro o una acción no son suficientes para lograr el resultado deseado. En estos casos. WordPress ofrece una solución en forma de la clase WP_Query .

¡Echemos un vistazo a cómo se puede usar la clase WP_Query !

Casos de consulta personalizados

NOTA: Este artículo asume que tiene algún conocimiento de PHP y MySQL/MariaDB, además está familiarizado con WordPress.

Independientemente de la página que visite, WordPress ejecuta lo que se denomina una "consulta principal" para mostrar el contenido. Entonces, cuando visita una página como una vista de categoría, por ejemplo, se crea un objeto WP_Query detrás de escena y recupera todos los datos necesarios de la base de datos para mostrar la página.

Lo que básicamente hace WP_Query es ofrecerle la capacidad de recuperar contenido de la base de datos de su sitio web sin tener que utilizar consultas SQL.

Para hacer esto, todo lo que necesitamos hacer es definir los argumentos correspondientes a nuestras necesidades y se creará un nuevo objeto WP_Query y se traducirá a una consulta SQL.

Un ejemplo usando WP_Query

Si queremos mostrar publicaciones de una categoría específica, dentro de otra plantilla de categoría, entonces es necesario crear un nuevo objeto de consulta.

A los efectos de este ejemplo, activamos el tema Twenty Twenty y creamos 2 publicaciones en una categoría denominada 'Categoría 1' y 2 publicaciones en una categoría denominada 'Servicios'.

Además, creamos una plantilla de vista de categoría personalizada para las publicaciones de 'Categoría 1'. El slug de esta categoría es 'category-1', por lo tanto, el archivo en la carpeta del tema debe ser category-CATEGORYSLUG.php que en nuestro caso es category-category-1.php .

Pegue lo siguiente en el archivo category-category-1.php .

 <?php /*** Custom Category 1 Template */ get_header(); ?> <main role="main"> <section class="site-content"> <div role="main"> <?php if ( have_posts() ) : ?> <header class="archive-header"> <h3 class="archive-title">Category: <?php single_cat_title( '', true ); ?></h3> </header> <?php while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; endif; ?> </div> </section> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>

Antes del ciclo, usamos el método have_posts para determinar si hay más publicaciones disponibles en el ciclo.

the_post() es necesario para que el bucle itere las publicaciones y le diga a WordPress que pase a la siguiente publicación de la matriz de publicaciones.

En este punto, nuestra vista frontal de la categoría ( https://mycompanyname.com/category/category-1/ ) será algo como esto:

Sé que al usar este fragmento de código nos hemos olvidado de incluir mucha información de las publicaciones, pero por el bien de este ejemplo, es mejor mantenerlo simple y mostrar solo los títulos de las publicaciones.

Para ver las propiedades del objeto de consulta que WordPress creó para esta vista, simplemente podemos agregar esta línea en nuestro código después del endif; declaración.

 var_dump ( $wp_query->query_vars );

Ahora, si actualiza su página, verá esta información en la lista de publicaciones:

 array(63) { ["category_name"]=> string(10) "category-1" ["error"]=> string(0) "" ["m"]=> string(0) "" ["p"]=> int(0) ["post_parent"]=> string(0) "" ["subpost"]=> string(0) "" ["subpost_id"]=> string(0) "" ["attachment"]=> string(0) "" ["attachment_id"]=> int(0) ["name"]=> string(0) "" ["pagename"]=> string(0) "" ["page_id"]=> int(0) ["second"]=> string(0) "" ["minute"]=> string(0) "" ["hour"]=> string(0) "" ["day"]=> int(0) ["monthnum"]=> int(0) ["year"]=> int(0) ["w"]=> int(0) ["tag"]=> string(0) "" ["cat"]=> int(16) ["tag_id"]=> string(0) "" ["author"]=> string(0) "" ["author_name"]=> string(0) "" ["feed"]=> string(0) "" ["tb"]=> string(0) "" ["paged"]=> int(0) ["meta_key"]=> string(0) "" ["meta_value"]=> string(0) "" ["preview"]=> string(0) "" ["s"]=> string(0) "" ["sentence"]=> string(0) "" ["title"]=> string(0) "" ["fields"]=> string(0) "" ["menu_order"]=> string(0) "" ["embed"]=> string(0) "" ["category__in"]=> array(0) { } ["category__not_in"]=> array(0) { } ["category__and"]=> array(0) { } ["post__in"]=> array(0) { } ["post__not_in"]=> array(0) { } ["post_name__in"]=> array(0) { } ["tag__in"]=> array(0) { } ["tag__not_in"]=> array(0) { } ["tag__and"]=> array(0) { } ["tag_slug__in"]=> array(0) { } ["tag_slug__and"]=> array(0) { } ["post_parent__in"]=> array(0) { } ["post_parent__not_in"]=> array(0) { } ["author__in"]=> array(0) { } ["author__not_in"]=> array(0) { } ["ignore_sticky_posts"]=> bool(false) ["suppress_filters"]=> bool(false) ["cache_results"]=> bool(true) ["update_post_term_cache"]=> bool(true) ["lazy_load_term_meta"]=> bool(true) ["update_post_meta_cache"]=> bool(true) ["post_type"]=> string(0) "" ["posts_per_page"]=> int(10) ["nopaging"]=> bool(false) ["comments_per_page"]=> string(2) "50" ["no_found_rows"]=> bool(false) ["order"]=> string(4) "DESC" }

Digamos que queremos mostrar la lista de publicaciones que pertenecen a la categoría 'Servicios' debajo de las publicaciones que se muestran arriba. Dado que la página ya ha creado un objeto de consulta para la categoría actual, tendremos que solucionar esto manipulando los argumentos de consulta principales existentes.

Echemos un vistazo a las formas en que WordPress nos permite lograr esto.

La función query_posts

La función query_posts() es una forma de modificar la consulta principal que usa WordPress para mostrar las publicaciones. Lo hace poniendo la consulta principal a un lado y reemplazándola con una nueva consulta. Puede verlo usted mismo en el archivo wp-includes/query.php donde se presenta.

 function &query_posts($query) { unset($GLOBALS['wp_query']); $GLOBALS['wp_query'] =& new WP_Query(); return $GLOBALS['wp_query']->query($query); }

Intentaremos agregar otro ciclo para mostrar las publicaciones de 'Servicios' agregando las siguientes líneas debajo del endwhile; del bucle estándar actual.

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile;

Y ahí vas:

Sin embargo, existe un inconveniente en este método. Si intentamos imprimir la categoría incluida en el objeto de consulta notaremos que está alterada.

Intente insertar var_dump ( $wp_query->query_vars["category_name"] ); después de la consulta de Servicios y actualice la página. Deberías ver este resultado:

 string(8) "services"

Esto sucedió porque la consulta se modificó pero nunca se revirtió. Este enfoque puede causar muchos problemas con el contenido que sigue a nuestras consultas.

Para evitar estos conflictos y limpiar después de una llamada a query_posts , haga una llamada a wp_reset_query() y se restaurará la consulta principal original. Así que tu código debería verse así:

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; wp_reset_query(); var_dump ( $wp_query->query_vars["category_name"] );

Al actualizar su página, ahora verá que la categoría de la página inicial está nuevamente en la consulta.

 string(10) "category-1"

Por último, debemos mencionar que se deben evitar query_posts , ya que agrega una sobrecarga a su consulta, ya que en realidad hace que la consulta principal se ejecute nuevamente.

La función get_posts()

Se puede lograr el mismo resultado con el uso de la función get_posts() para recuperar una matriz de publicaciones que coincidan con los criterios dados.

Reemplace el bucle de servicios que se muestra a continuación...

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; wp_reset_query(); var_dump ( $wp_query->query_vars["category_name"] );

…Con este:

 $my_query = get_posts( array ( 'category' => 17 ) ); foreach($my_query as $post) : setup_postdata($post); the_title( '<h4 class="example"></h4>' ); endforeach; var_dump ( $wp_query->query_vars["category_name"] );

Como puede ver, esta vez tuvimos que trabajar con la identificación de la categoría en lugar del nombre de la categoría, de acuerdo con los argumentos get_posts() definidos por WordPress.

Otra cosa importante a tener en cuenta aquí es que aunque no restablecimos la consulta, la salida var_dump de la categoría de consulta aún estaba intacta y no cambió a 'servicios'. Esto se debe a que get_posts() por sí solo no altera la consulta principal. Acabamos de usar una nueva variable ' $my_query ' para crear una nueva instancia del objeto de consulta sin reemplazarlo.

La función get_posts() utiliza los mismos parámetros que query_posts() y se recomienda su uso cuando desee agregar bucles personalizados estáticos en cualquier lugar de su plantilla, ya que es seguro y fácil de usar.

Crear un nuevo objeto WP_Query

$wp_query es un objeto de la clase WP_Query y recupera el contenido de la base de datos necesario para la página actual. Anular esta clase es nuestra forma de personalizar los resultados y mostrar contenido diferente.

Este es el fragmento de código que usaremos:

 $services_query = new WP_Query( 'category_name=services' ); if ( $services_query->have_posts() ) { while ( $services_query->have_posts() ) : $services_query->the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; } wp_reset_postdata(); var_dump ( $wp_query->query_vars["category_name"] );

Usamos el argumento 'category_name' para definir el slug de la categoría en la que queremos que se muestren sus publicaciones.

Guardamos el nuevo objeto new WP_Query( 'category_name=services' ); en la variable $services_query .

Luego usamos un ciclo while para mostrar el contenido y luego reiniciamos el ciclo con wp_reset_postdata(); para restaurar los datos originales de la consulta principal.

Si desea experimentar con otros argumentos de la clase de WordPress WP_Query, puede encontrar la lista completa en su página de WordPress Codex.