Seleccionar página

Consultas personalizadas en WordPress; wp_query, get_posts, pre_get_post

por | Oct 7, 2016 | Wordpress

Índice de contenidos

Funciones para consultas personalizadas en WordPress:

En WordPress puedes crear loops, bucles o consultas personalizadas de 5 maneras diferentes. Las consultas personalizadas en WordPress nos ayudan a mostrar distintos contenidos en las páginas de nuestro sitio.

Lista de las 5 funciones de WP para consultas personalizadas

Para crear tus propias consultas personalizadas puedes utilizar funciones, hooks o el objeto wp_query.

  1. wp_query – objeto
  2. pre_get_post – hook
  3. get_posts() – función
  4. get_pages() – función
  5. query_posts() – la explicaremos pero NO SE RECOMIENDA SU USO

En este artículo explicaremos; pre_get_post, get_posts(), get_pages() y query_posts(). 

Toda la información sobre wp_query está disponible en el artículo:

>> Cómo crear bucles personalizados con wp_query en WordPress

Hook pre_get_post (trabaja sobre el bucle principal modificándolo)

Se trata de un filtro que modifica la consulta principal, no se puede utilizar para crear una consulta nueva sólo la utilizaremos para realizar algún cambio en la consulta o loop principal. No puedes utilizarla en templates del theme tipo archive.php… porque se ejecuta antes de la carga de la plantilla, hay que utilizarla en el archivo function.php o similar.

Por ejemplo vamos a modificar la consulta principal para que en la página de inicio o home sólo muestre los post  o entradas cuya categoría tenga el ID=123. 

function my_home_category( $query ) {
    //compruebo que la página es la home y la consulta la principal
    if ( $query->is_home() && $query->is_main_query() ) {
        //de la consulta principal selecciono los post con categoría ID=123
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'my_home_category' );

Te dejo este enlace a la página del codex de WP donde puedes ampliar información.

Función get_posts()

get_posts() es una función la encontrarás dentro de la carpeta wp-includes en el archivo post.php.

Función get_posts() en el archivo post.php

function get_posts( $args = null ) {
	$defaults = array(
		'numberposts' => 5,
		'category' => 0, 'orderby' => 'date',
		'order' => 'DESC', 'include' => array(),
		'exclude' => array(), 'meta_key' => '',
		'meta_value' =>'', 'post_type' => 'post',
		'suppress_filters' => true
	);

	$r = wp_parse_args( $args, $defaults );
	if ( empty( $r['post_status'] ) )
		$r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
	if ( ! empty($r['numberposts']) && empty($r['posts_per_page']) )
		$r['posts_per_page'] = $r['numberposts'];
	if ( ! empty($r['category']) )
		$r['cat'] = $r['category'];
	if ( ! empty($r['include']) ) {
		$incposts = wp_parse_id_list( $r['include'] );
		$r['posts_per_page'] = count($incposts);  // only the number of posts included
		$r['post__in'] = $incposts;
	} elseif ( ! empty($r['exclude']) )
		$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );

	$r['ignore_sticky_posts'] = true;
	$r['no_found_rows'] = true;

	$get_posts = new WP_Query;
	return $get_posts->query($r);

}

Lista de Parámetros permitidos al usar get_posts()

Las consultas personalizadas con get_posts() permiten los siguientes parámetros:

<?php $args = array(
	'posts_per_page'   => 5,
	'offset'           => 0,
	'category'         => '',
	'orderby'          => 'post_date',
	'order'            => 'DESC',
	'include'          => '',
	'exclude'          => '',
	'meta_key'         => '',
	'meta_value'       => '',
	'post_type'        => 'post',
	'post_mime_type'   => '',
	'post_parent'      => '',
	'post_status'      => 'publish',
	'suppress_filters' => true ); ?>

La función get_posts() se ejecuta más rápidamente y requiere menos recursos que wp_query , esto se debe a únicamente realiza una consulta a base de datos para extraer los datos del post. WP_QUERY además de los datos del post realiza varias consultas a la base de datos para meta datos, datos de autor , datos de comentarios… por lo tanto emplea más recursos.

La lista de parámetros hace referencia a los post, si necesitas filtrar una consulta por ejemplo por autor del post no puedes utilizar get_posts().

El array devuelto por get_posts()

Otra diferencia importante de la función get_post() es que nos devuelve un array con los datos de los post según los filtros que hemos creado. En una consulta realizada con get_post() nunca encontrarás el loop o bucle de wp_query:

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

tendrás que ir recorriendo los elementos del array con un foreach.

foreach( $entradas_seleccionadas as $lospost ) :

Función setup_postdata()

Cuando utilizas get_posts() debes utilizar la función setup_postdata() de wp_query (la encontrarás en el archivo query.php) después del foreach y antes de utilizar las Template Tags (su título, enlace…) de los post, ya que esta función es la que te permite utilizar las Template Tags (the_title(), the_permalink()..) al extraer información de cada elemento del array.

foreach ( $mis_envios as $envio ) : 
setup_postdata( $envio ); ?>
	<li>
		<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	</li> 

Cómo realizar una consulta personalizada usando la función get_posts()

Voy a explicar el código línea por línea.

1- Crear el array con los filtros, ejemplo:

$args = array(
    'category_name' => 'noticias',
    'order' => 'DESC',
    'orderby' => 'date',
    'posts_per_page' => -1
);

2- llamar a la función get_posts()

$mis_post_de_noticias = get_posts( $args );

3- recorrer el array $mis_post_de_noticias

foreach($mis_post_de_noticias as $post ) :

4- usar la función  setup_postdata() para cada post que devuelve el foreach y así poder extraer las Template Tags

setup_postdata( $post ); 

5- extraer de cada post la información que desee, en este caso título, enlace y contenido

<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php
  the_content(); ?>

6- Terminar el bucle

<?php endforeach;?>

7- Resetear la consulta

<?php wp_reset_postdata();?>

Código completo ejemplo get_posts()

<?php
$args = array(
    'category_name' => 'noticias',
    'order' => 'DESC',
    'orderby' => 'date',
    'posts_per_page' => -1
);
$mis_post_de_noticias = get_posts( $args );

foreach($mis_post_de_noticias as $post ) :
setup_postdata( $post ); ?> 
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php the_content(); 
endforeach;
wp_reset_postdata();?>

Función get_pages()

Aunque es similar a get_post(), los parámetros y los valores son diferentes, get_pages() devuelve una lista de las páginas que tienes implementadas en tu blog según los valores definidos en los parámetros de la función. Normalmente get_pages se usa para obtener páginas determinadas

Encontrarás la función get_pages() dentro de la carpeta wp-includes en el archivo post.php

Parámetros de la función get_pages()

<?php $args = array(
	'sort_order' => 'asc',
	'sort_column' => 'post_title',
	'hierarchical' => 1,
	'exclude' => '',
	'include' => '',
	'meta_key' => '',
	'meta_value' => '',
	'authors' => '',
	'child_of' => 0,
	'parent' => -1,
	'exclude_tree' => '',
	'number' => '',
	'offset' => 0,
	'post_type' => 'page',
	'post_status' => 'publish'
); 
$pages = get_pages($args); 
?>

Uno de los parámetros interesantes es sort_column: ordena la lista de páginas de diferentes maneras, por defecto está configurada para ordenarlas alfabéticamente por título, pero admite; por orden según el menú, por fecha, por ID… (similar al orderby de get_post)

Si necesitas información sobre el significado de los parámetros y los distintos valores permitidos aquí tienes el enlace al codex de WP.

WordPress implementa una función similar que devuelve un listado de páginas de tu blog tipo lista (li), la función es wp_list_pages()

Función query_posts()

No se recomienda su uso, desde el codex de WordPress nos avisan:

Nota: Esta función anula por completo la consulta principal y no se puede utilizar en plugins o temas. Su enfoque excesivamente simplista a la modificación de la consulta principal puede ser problemático y debe evitarse siempre que sea posible.En la mayoría de los casos, hay mejores opciones, con más prestaciones para la modificación de la consulta principal, como a través de la  pre_get_posts acción dentro WP_Query .

El problema principal de la función query_post() es que no evita que se cargue una y otra vez la consulta principal, es decir WordPress emplea trabajo y recursos en la llamada al bucle principal, cuando WordPress termina entonces query_post() obliga a que se vuelva a realizar todo el trabajo en base a distintos parámetros, por lo tanto estamos obligando a WordPress a emplear recursos a lo tonto y puede ser muy perjudicial en webs con tráfico considerable. Cómo tienes más opciones para modificar la consulta principal mejor no utilices query_post().

OBSERVACIONES: 

  • en versiones antiguas de WordPress se utilizaba get_posts() y query_posts()
  • Hoy en día se recomienda trabajar con wp_query.
  • Si vas a realizar consultas anidadas debes emplear wp_query
  • Debes evitar el uso de query_posts()
  • si sólo necesitas modificar el bucle principal en algunas páginas usa el hook pre_get_posts

Enlaces de interés

>> WordPress Recursos para Desarrolladores, información pre_get_posts

>> Codex WordPress información get_posts()

>> Codex WordPress información get_pages()

>> Cómo crear bucles personalizados con wp_query en WordPress

0 comentarios

Enviar un comentario

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