Eroare 404 la paginarea unei interogări personalizate

9 iun. 2014, 23:56:12
Vizualizări: 14.2K
Voturi: 0

Problema principală este că fiecare pagină de blog paginată returnează eroare 404. /page/2/, /page/3/, etc. Funcționa corect anterior, dar acum nu mai merge. Cred că actualizarea la versiunea 3.9 a provocat problema.

Iată câteva din multele încercări făcute pentru remediere. Rezultatul final a fost același - linkurile paginate returnau 404.

  • dezactivat toate pluginurile
  • șters și resetat structura de legături permanente de mai multe ori
  • încercat structura de legături permanente implicită în loc de /nume-post
  • Verificat setările de Citire > Pagini blog afișează cel mult același număr ca bucla mea (precum și valori mai mari/mici pentru test)
  • Testat două pluginuri separate de navigare și paginarea implicită WordPress (postări mai vechi) - mereu eroare 404
  • încercat parse_query
  • încercat paginate_links

Iată codul meu (sau linkuri către el):

home.php

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

blog-page.php

<?php
/*
Șablon: Pagină Blog - Personalizat
*/

get_header(); ?>

<---COD PERSONALIZAT--->

<?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(); ?>

<---COD PERSONALIZAT--->


   endwhile;

wp_reset_postdata();?>

<div class="nav-previous alignleft"><?php next_posts_link( 'Postări mai vechi' ); ?></div>
<div class="nav-next alignright"><?php previous_posts_link( 'Postări mai noi' ); ?></div>
<?php  endif; wp_reset_query();

Dacă ajută, iată un site de test configurat cu pagina în cauză. Am lăsat-o cu paginarea implicită WordPress.

Am epuizat toate opțiunile. Orice sugestie este binevenită.

3
Comentarii

Am încercat și această opțiune aici, dar nu am putut posta linkul. Am încercat această opțiune aici: http://wordpress.stackexchange.com/questions/54509/query-with-pre-get-posts-to-get-pagination

jphogan jphogan
9 iun. 2014 23:56:53

de ce creezi o nouă interogare în șablonul tău și nu folosești interogarea principală implicită?

Milo Milo
10 iun. 2014 00:20:01

Nu vei avea o paginare fiabilă prin suprascrierea interogării principale în șablon. Niciodată. Serios.

Rarst Rarst
10 iun. 2014 00:52:52
Toate răspunsurile la întrebare 2
3

Sunt câteva lucruri pe care nu le înțeleg aici, dar voi încerca să răspund pe măsură ce avansez.

Ai un fișier home.php, pe care presupun că este pagina ta principală implicită. Ai o singură linie de cod acolo, și anume pentru a apela un alt șablon de pagină. Iată codul tău:

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

În blog-page.php ai șablonul complet al paginii. Întrebarea mea este, de ce faci asta. De ce nu pur și simplu adaugi conținutul din blog-page.php în home.php? Ar avea mai mult sens.

Nu folosești interogarea principală pentru a rula bucla ta, ci una personalizată, ceea ce nu înțeleg nici eu, deoarece interogarea ta personalizată face exact același lucru ca și interogarea principală, cu excepția postărilor pe pagină. Această întreagă interogare personalizată poate fi evitată prin utilizarea pre_get_posts pentru a seta un număr personalizat de postări pe pagina ta principală.

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' );

Poți adăuga pur și simplu acest cod în functions.php, care va seta numărul de postări pe pagina ta principală la 5, iar apoi poți înlocui interogarea personalizată cu o buclă normală.

Un lucru de reținut aici, oricând rulezi o interogare personalizată, paginarea va eșua, așa cum este menționat în comentarii.

Va trebui să te uiți la parametrii de paginare ai WP_Qeury.

paged (int) - numărul paginii. Afișează postările care ar apărea în mod normal doar pe pagina X atunci când utilizați linkul "Articole mai vechi".

page (int) - numărul paginii pentru o pagină principală statică. Afișează postările care ar apărea în mod normal doar pe pagina X a unei Pagini Principale Statice.

Deci, interogarea ta ar trebui să arate astfel pentru paginile normale

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

Și astfel pentru paginile statice

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

De asemenea, resetezi datele postării tale de două ori. Ar trebui să faci asta doar o dată. Apropo, wp_reset_query(); este greșit, este folosit doar pentru query_posts, care nu ar trebui utilizat. Ar trebui să folosești wp_reset_postdata();.

În cele din urmă, când folosești o interogare personalizată, trebuie să specifici numărul maxim de pagini pentru next_posts_link utilizând parametrul $max_pages, altfel va eșua.

 next_posts_link( 'Articole mai vechi', $the_query->max_num_pages );

Iată un exemplu de interogare personalizată funcțională corectă, conform codex-ului

<?php
// setează parametrul "paged" (folosește 'page' dacă interogarea este pe o pagină principală statică)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

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

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

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

<?php

// utilizarea next_posts_link() cu max_num_pages
next_posts_link( 'Articole mai vechi', $the_query->max_num_pages );
previous_posts_link( 'Articole mai noi' );
?>

<?php 
// curăță după interogarea noastră
wp_reset_postdata(); 
?>

<?php else:  ?>
   <p><?php _e( 'Ne pare rău, nicio postare nu corespunde criteriilor tale.' ); ?></p>
<?php endif; ?>

Sper că acest lucru va clarifica problema ta

10 iun. 2014 10:16:18
Comentarii

Mulțumesc din suflet pentru timpul acordat și pentru răspunsul atât de detaliat. Am încercat atâtea variante, cred că am ajuns să am o mare mizerie. Cu siguranță voi salva ce ai scris, pentru că mă va ajuta de multe ori în viitor. Am copiat codul din blog-page.php și l-am mutat în home.php. Am schimbat la interogarea implicită. Apoi am adăugat acea funcție pentru a limita numărul de articole. Aveam setat în Setări de citire, dar pagina ignora asta chiar și după mutarea în home.php. Ai vreo idee de ce s-ar întâmpla asta? Oricum, acum funcționează perfect. Nu pot să-ți mulțumesc suficient pentru ajutor.

jphogan jphogan
10 iun. 2014 20:44:57

Ai setat o pagină de start în "Setări de citire >> Afișare pagină frontală"? Dacă nu, editează-ți întrebarea și adaugă codul care se află acum în home.php ca să pot arunca rapid o privire :)

Pieter Goosen Pieter Goosen
10 iun. 2014 20:57:07

Da, am setat asta. Vezi aici: http://imgur.com/n8YINbI Iată noul meu home.php http://pastebin.com/bTHRMFqT Dacă elimin funcția pe care mi-ai dat-o, toate articolele sunt afișate și nu există paginare. Dacă adaug funcția, atunci se afișează cantitatea corectă și funcționează așa cum ar trebui.

jphogan jphogan
10 iun. 2014 23:20:17
0

Am întârziat la petrecere, dar niciuna dintre soluțiile de mai sus nu m-a ajutat. Am reușit să găsesc o mică soluție pentru această situație enervantă.

  1. Analizează URL-ul
  2. Dacă /page/2 este prezent, scrie o regulă de redirecționare pentru a adăuga un query string la URL
  3. Folosește acel query în paginarea ta.

//Setează segmentele URL ca variabilă globală (functions.php)
global $segments;
$segments = explode('/', $_SERVER['REQUEST_URI']);
$segments = array_filter($segments);
$segments['classes'] = implode(' ', $segments);

//Adaugă această rescriere în functions.php pentru a adăuga un query string la țintă
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>';
    }
}

// În loc de funcția de paginare standard, afișează asta:
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