Paginación devuelve error 404 en consulta personalizada

9 jun 2014, 23:56:12
Vistas: 14.2K
Votos: 0

El problema básico es que cada página paginada de mi blog va a una página 404. /page/2/, /page/3/, etc. Antes funcionaba bien, pero ahora no. Creo que quizás el cambio a la versión 3.9 lo causó.

Estas son algunas de las muchas cosas que he intentado para solucionarlo. El resultado final de todas fue el mismo: los enlaces de paginación devolvían 404.

  • Desactivé todos los plugins
  • Eliminé y restablecí los enlaces permanentes múltiples veces
  • Probé los enlaces permanentes como predeterminados en lugar de /nombre-del-post
  • Aseguré que en Ajustes de lectura > Las páginas de blog muestran como máximo estaba configurado con el mismo número que mi bucle (y también probé con más y menos)
  • Probé dos plugins de navegación diferentes y la paginación predeterminada de WordPress (entradas antiguas) y siempre devuelve 404.
  • Intenté usar parse_query
  • Intenté usar paginate_links

Aquí está mi código (o enlaces a mi código):

home.php

    <?php require dirname( __FILE__ ) . '/blog-page.php';

blog-page.php

<?php
/*
Plantilla: Página de Blog - Personalizada
*/

get_header(); ?>

<---CÓDIGO PERSONALIZADO--->

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
   $args = array(
       'posts_per_page' => 5,
       'post_type' => 'post',
       'paged' => $paged
   );

$wp_query = new WP_Query($args);

if($wp_query->have_posts()) : 

   while($wp_query->have_posts()) : $wp_query->the_post(); ?>

<---CÓDIGO PERSONALIZADO--->


   endwhile;

wp_reset_postdata();?>

<div class="nav-previous alignleft"><?php next_posts_link( 'Entradas antiguas' ); ?></div>
<div class="nav-next alignright"><?php previous_posts_link( 'Entradas recientes' ); ?></div>
<?php  endif; wp_reset_query();

Si ayuda, aquí hay un sitio de prueba que he configurado con la página en cuestión. Lo he dejado con la paginación predeterminada de WordPress.

Me he quedado sin cosas que probar. Cualquier sugerencia sería apreciada.

3
Comentarios

También probé esta opción aquí, pero no pude publicar el enlace. Intenté esta opción: http://wordpress.stackexchange.com/questions/54509/query-with-pre-get-posts-to-get-pagination

jphogan jphogan
9 jun 2014 23:56:53

¿Por qué estás creando una nueva consulta en tu plantilla en lugar de usar la consulta principal predeterminada?

Milo Milo
10 jun 2014 00:20:01

No vas a tener una paginación confiable sobrescribiendo la consulta principal en la plantilla. Nunca. En serio.

Rarst Rarst
10 jun 2014 00:52:52
Todas las respuestas a la pregunta 2
3

Hay un par de cosas que no entiendo aquí, pero intentaré responderlas sobre la marcha.

Tienes un home.php, que asumo es tu página de inicio por defecto. Tienes una línea de código ahí, y es para llamar a otra plantilla de página. Aquí está tu código:

  <?php require dirname( __FILE__ ) . '/blog-page.php'; 

En blog-page.php tienes la plantilla de página completa. Mi pregunta es, ¿por qué estás haciendo esto? ¿Por qué no simplemente añadir el contenido de blog-page.php en home.php? Tendría más sentido.

No estás usando la consulta principal para ejecutar tu bucle, sino una personalizada, lo cual tampoco entiendo, ya que tu consulta personalizada hace exactamente lo mismo que la consulta principal, excepto por los posts por página. Toda esta consulta personalizada puede evitarse simplemente usando pre_get_posts para establecer un número personalizado de posts en tu página de inicio.

function posts_on_homepage( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', '5' );
    }
}
add_action( 'pre_get_posts', 'posts_on_homepage' );

Puedes simplemente añadir esto en functions.php lo cual establecerá tu cantidad de posts en la página de inicio a 5, y luego puedes reemplazar la consulta personalizada con un bucle normal.

Una cosa a tener en cuenta aquí, cada vez que ejecutas una consulta personalizada, la paginación fallará como se indica en los comentarios.

Necesitarás echar un vistazo a los parámetros de paginación de WP_Qeury.

paged (int) - número de página. Muestra los posts que normalmente aparecerían solo en la página X cuando se usa el enlace "Entradas más antiguas".

page (int) - número de página para una página frontal estática. Muestra los posts que normalmente aparecerían solo en la página X de una Página Frontal Estática.

Así que tu consulta debería verse así para páginas normales:

$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

Y así para páginas estáticas:

$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

También estás reiniciando tus datos de post dos veces. Solo deberías hacerlo una vez. Por cierto, wp_reset_query(); está mal, solo se usa para query_posts que no debería usarse. Deberías usar wp_reset_postdata();

Por último, al usar una consulta personalizada, debes especificar el número máximo de páginas para next_posts_link usando el parámetro $max_pages, de lo contrario fallará.

 next_posts_link( 'Entradas más antiguas', $the_query->max_num_pages );

Aquí hay un ejemplo de una consulta personalizada correctamente funcionando según el codex:

<?php
// establece el parámetro "paged" (usa 'page' si la consulta está en una página frontal estática)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

// la consulta
$the_query = new WP_Query( 'cat=1&paged=' . $paged ); 
?>

<?php if ( $the_query->have_posts() ) : ?>

<?php
// el bucle
while ( $the_query->have_posts() ) : $the_query->the_post(); 
?>
   <?php the_title(); ?>
<?php endwhile; ?>

<?php

// uso de next_posts_link() con max_num_pages
next_posts_link( 'Entradas más antiguas', $the_query->max_num_pages );
previous_posts_link( 'Entradas más nuevas' );
?>

<?php 
// limpieza después de nuestra consulta
wp_reset_postdata(); 
?>

<?php else:  ?>
   <p><?php _e( 'Lo siento, no hay posts que coincidan con tus criterios.' ); ?></p>
<?php endif; ?>

Espero que esto arroje algo de luz sobre tu problema.

10 jun 2014 10:16:18
Comentarios

Muchísimas gracias por tomarte el tiempo de escribir una respuesta tan detallada. He probado tantas opciones que creo que terminé con un lío. Definitivamente guardaré lo que escribiste, ya que me ayudará muchas veces en el futuro. Copié mi código de blog-page.php y lo moví a home.php. Cambié a solo la consulta predeterminada. Luego agregué esa función para limitar el número de publicaciones. Lo tenía configurado en Ajustes de lectura, pero la página lo ignoraba incluso después de moverlo a home.php. ¿Alguna idea de por qué sucedería eso? De cualquier manera, ahora funciona perfectamente. No puedo agradecerte lo suficiente por tu ayuda.

jphogan jphogan
10 jun 2014 20:44:57

¿Configuraste una página de inicio en "Ajustes de lectura >> Página frontal muestra"? Si no es así, edita tu pregunta y agrega el código que está actualmente en home.php para que pueda echarle un vistazo rápidamente :)

Pieter Goosen Pieter Goosen
10 jun 2014 20:57:07

Sí, lo tengo configurado. Mira aquí: http://imgur.com/n8YINbI Aquí está mi nuevo home.php http://pastebin.com/bTHRMFqT Si elimino la función que me diste, se muestran todas las publicaciones y no hay paginación. Si agrego la función, entonces se muestra la cantidad correcta y funciona como debería.

jphogan jphogan
10 jun 2014 23:20:17
0

Llegué tarde a la fiesta, pero ninguna de las soluciones anteriores me ayudó. Pude escribir una pequeña solución alternativa para esta situación tan molesta.

  1. Examinar la URL
  2. Si /page/2 está presente, escribir una regla de redirección para añadir una cadena de consulta a la URL
  3. Utilizar esa consulta en tu paginación.

//Establecer segmentos de URL como Global (functions.php)
global $segments;
$segments = explode('/', $_SERVER['REQUEST_URI']);
$segments = array_filter($segments);
$segments['classes'] = implode(' ', $segments);

//Añadir esta reescritura en tu functions.php para agregar una cadena de consulta al objetivo
add_action( 'init', 'forum_paging_redirect', 10 );
function forum_paging_redirect( $redirect_url ) {
    global $segments;

    if($segments[1] === 'forum' && $segments[2] === 'page') {
        echo '<script>window.location = "/forum?topics_page='.$segments[3].'";</script>';
    }
}

// En lugar de la función de paginación nativa, imprime este pequeño:
if(!empty($query_topics)) {
    $total = $query_topics->max_num_pages;
    $page = $_GET['topics_page'];

    for($i = 1; $i < $total +1; $i++) {
        if($i == $page) {
            echo '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
        } else {
            echo '<a class="page-numbers" href="/forum/?topics_page='.$i.'">'.$i.'</a>';
        }
    }   
} 
28 sept 2018 21:11:35