¿Cómo arreglar la paginación para bucles personalizados?

He añadido una consulta personalizada, secundario a una plantilla de página personalizada archivo de plantilla; ¿Cómo puedo hacer WordPress utilice mi consulta personalizada para la paginación, en lugar de utilizar la paginación del bucle de la consulta principal? He modificado la consulta bucle principal mediante adenda
query_posts()
. ¿Por qué no funciona la paginación, y ¿cómo lo soluciono?.


Solución

El problema

De forma predeterminada, en cualquier contexto determinado, WordPress utiliza la consulta principal para determinar la paginación. El objeto principal de la consulta se almacena en el
$wp_query
global, que también se utiliza para la salida del bucle de consulta principal:
if ( have_posts() ) : while ( have_posts() ) : the_post();
Cuando usted use a custom query, crear un objeto de consulta totalmente independientes:
$custom_query = new WP_Query( $custom_query_args );
Y que la consulta se emite mediante un bucle totalmente independiente:
if ( $custom_query->have_posts() ) : 
    while ( $custom_query->have_posts() ) : 
        $custom_query->the_post();
Pero etiquetas de plantilla de paginación, incluidas previous_posts_link(), next_posts_link(), posts_nav_link(), y paginate_links(), basar su producción en el objeto de la consulta principal,
previous_posts_link()
. Esa consulta principal puede o no puede ser paginada.

Si el contexto actual es una plantilla de página personalizada, por ejemplo, los principales
next_posts_link()
objeto consistirá solamente un solo puesto de la ID de la página a la que se asigna la plantilla de página personalizado. Si el contexto actual es un índice de archivo de algún tipo, los principales
posts_nav_link()
puede consistir en suficientes puestos para causar la paginación, que conduce a la siguiente parte del problema: para el principal
paginate_links()
objeto, WordPress pasará un
$wp_query
parámetro de la consulta, basada en el
$wp_query
Variable de URL de la consulta.

Cuando se recupera la consulta,
$wp_query
parámetro se utilizará para determinar qué conjunto de mensajes paginados para volver. Si se hace clic en un enlace de paginación se muestra, y la siguiente página cargada, la consulta personalizada no tendrá ninguna forma de saber que ha cambiado la paginación.

La solución

Paso correcto paginado parámetro en la consulta personalizada

Suponiendo que la consulta personalizada utiliza una matriz de args:
$wp_query
Tendrá que pasar el correcto
paged
parámetro a la matriz.

Puede hacerlo por ir a buscar la variable de consulta URL utilizada para determinar la página actual, mediante
paged
:

paged
Luego, se puede añadir paremeter a su matriz args consulta personalizada:
$custom_query_args = array(
    // Custom query parameters go here
);
Ahora, cuando la consulta personalizada es feteched, se devolverá el conjunto correcto de mensajes paginados.

Con objeto de consulta personalizada para las funciones de paginación

En orden para las funciones de paginación producir la salida correcta es decir, anterior/siguiente/página enlaces relativos a la consulta personalizada WordPress tiene que verse obligado a reconocer la consulta personalizada. Esto requiere un poco de un 'hack': reemplazo de la cañería
paged
objeto con el objeto de consulta personalizada,
get_query_var()
:

Hackear el objeto de la consulta principal respaldo el objeto principal de la consulta:
get_query_var( 'paged' );
El objeto de consulta principal null:
$custom_query_args['paged'] = get_query_var( 'paged' ) 
    ? get_query_var( 'paged' ) 
    : 1;
Cambiar la consulta personalizada en el objeto de la consulta principal:
$wp_query
$custom_query
Este 'hack' debe hacerse antes de llamar a cualquier función de paginación restablecer la consulta principal objeto una vez que la paginación funciones han sido salida, restablecer el objeto de la consulta principal:
$temp_query = $wp_query

Correcciones de la función de paginación

El
$wp_query = NULL;
función funcionará normalmente, independientemente de la paginación.

Simplemente determina la página actual y luego salidas el enlace para
$wp_query = $custom_query;
. Sin embargo, se exige una solución
$temp_query = $wp_query;
$wp_query   = NULL;
$wp_query   = $custom_query;
a la salida correctamente.

Esto es porque
$wp_query = NULL;
$wp_query = $temp_query;
utiliza el
previous_posts_link()
parámetro:
page - 1
Al igual que con otros parámetros de consulta, por defecto la función usará
next_posts_link()
para el principal
next_posts_link()
objeto. Con el fin de forzar
max_num_pages
para tener en cuenta la
<?php next_posts_link( $label , $max_pages ); ?>
objeto, tendrá que pasar el
max_num_pages
a la función.

Podrás recoger este valor de la
$wp_query
objeto:
next_posts_link()
:

$custom_query

Juntándolo todo

La siguiente es una estructura básica de un bucle de consultas personalizadas con funcionamiento correctamente las funciones de paginación:
max_num_pages

Apéndice: Qué pasa con query_posts()?

query_posts() para los bucles secundarios

Si estás usando query_posts() a la salida de un bucle personalizado, prefiero entonces crear instancias de un objeto independiente para la consulta personalizada vía
$custom_query
, Entonces eres
$custom_query->max_num_pages
, y se topará con varios problemas (no el menor de los cuales serán temas de paginación). Será el primer paso para resolver esos problemas convertir el uso indebido de
<?php next_posts_link( 'Older Posts' , $custom_query->max_num_pages ); ?>
para una adecuada
// Define custom query parameters
$custom_query_args = array( /* Parameters go here */ );

// Get current page and append to custom query parameters array
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

// Instantiate custom query
$custom_query = new WP_Query( $custom_query_args );

// Pagination fix
$temp_query = $wp_query;
$wp_query   = NULL;
$wp_query   = $custom_query;

// Output custom query loop
if ( $custom_query->have_posts() ) :
    while ( $custom_query->( have_posts() ) :
        $custom_query->the_post();
        // Loop output goes here
    endwhile;
endif;
// Reset postdata
wp_reset_postdata();

// Custom query loop pagination
previous_posts_link( 'Older Posts' );
next_posts_link( 'Newer Posts', $custom_query->max_num_pages );

// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
llamada.

Utilizando query_posts() para modificar el bucle principal

Si sólo desea modificar los parámetros para la consulta de bucle principal como el cambio de los postes por página, o excluyendo una categoría puede ser tentado a utilizar
query_posts()
.

Pero todavía no. Cuando se utiliza
query_posts()
, fuerzas WordPress para reemplazar el objeto de consulta principal.

(WordPress en realidad hace una segunda consulta y sobrescribe
query_posts()
.) Sin embargo, el problema es que hace este reemplazo demasiado tarde en el proceso de actualizar la paginación. La solución consiste en filtrar la consulta principal antes de que los mensajes se obtienen, mediante la
WP_Query()
gancho.

En lugar de agregar esto en el archivo de plantilla de categoría (
_doing_it_wrong()
):

query_posts()
Agregue lo siguiente a
WP_Query()
:

query_posts()
En lugar de agregar esto al blog posts índice archivo de plantilla (
query_posts()
):

query_posts()
Agregue lo siguiente a
$wp_query
:

pre_get_posts
De esa manera, WordPress utilizará ya modificado
category.php
objeto determinar la paginación, sin ninguna modificación de la plantilla necesaria.

Cuándo utilizar qué función

Investigación this question and answer y this question and answer para entender cómo y cuándo usar
query_posts( array(
    'posts_per_page' => 5
) );
,
functions.php
, y
function wpse120407_pre_get_posts( $query ) {
    // Test for category archive index
    // and ensure that the query is the main query
    // and not a secondary query (such as a nav menu
    // or recent posts widget output, etc.
    if ( is_category() && $query->is_main_query() ) {
        // Modify posts per page
        $query->set( 'posts_per_page', 5 ); 
    }
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
.

function wpse120407_pre_get_posts( $query ) {
    // Test for category archive index
    // and ensure that the query is the main query
    // and not a secondary query (such as a nav menu
    // or recent posts widget output, etc.
    if ( is_category() && $query->is_main_query() ) {
        // Modify posts per page
        $query->set( 'posts_per_page', 5 ); 
    }
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
.

.




Problemas relacionados

Paginación cuando se utilizan varios bucles

WP_Query paginación usando sólo números en lugar de \/page\/1 en la URL

¿Resultados de alguna manera de incluir los campos personalizados en WP_Query?

Paginación personalizada Post tipo & mensajes duplicados

Convertir varios bucles en un solo lazo con paginación

Paginación para tipos de correos personalizados

Bucles encontrándonos

Correos personalizados tipo paginación no funciona en Wordpress 3.4

Paginación de comentarios como una lista desordenada

¿Cómo mostrar varios tipos de correos en archivo de taxonomía?

Paginación no funciona con el lazo personalizado

Múltiples lazos misma página independiente paginación

Source: Stack Exchange Inc; License: cc by-sa 3.0 Contacto / Contact