it-swarm.dev

Paginazione/scorrimento infinito con WP_Query e loop multipli

Ho bisogno che la pagina principale del mio sito abbia 3 colonne: - La prima con i 5 post più visti; - Il secondo con i prossimi 5 post più visti; - Il terzo con i post più recenti.

Non voglio che i post vengano mai ripetuti nella stessa colonna o in un'altra colonna, quindi sto usando wp_query per ottenere i post che voglio, nel numero che voglio. Ecco cosa succede quando carico la seconda pagina, usando l'impaginazione semplice o lo scroll infinito:

  • Il primo ciclo carica i 5-10 post più visti, che erano già visualizzati alla prima esecuzione del secondo ciclo;
  • Il secondo ciclo carica i prossimi 5 post più visti, alcuni dei quali sono già stati caricati sul terzo ciclo quando è stato eseguito la prima volta;
  • Il terzo ciclo carica i post più recenti e non è stato caricato sul primo o sul secondo anello.

Mentre carico ancora le pagine successive, i cicli caricano i rispettivi post fino a quando non ottengo alcun post sul terzo ciclo, quindi non ho post nel secondo ciclo e tutti i post sono caricati nel primo ciclo.

Ecco il codice che sto usando:

<div id="content">

<div class="recentColumn">
<div class="columnContent">

<?

$hotArgs =  array(
    'post__not_in' => $loaded,
    'meta_key' => 'wpb_post_views_count', // Pega o número de visitas do post.
    'orderby' => 'meta_value_num', // Ordena do mais visitado para o menos visitado.
    'posts_per_page' => '2',
    'paged' => $paged
    );
$hot = new WP_Query( $hotArgs );


if ($hot->have_posts()) : while ($hot->have_posts()) : $hot->the_post();
$loaded[] = $post->ID;
?>

<div class="articleContent">
<article class="recent" role="article">

    <a href="<?php the_permalink();?>" title="<?php the_title();?>"><?php the_category();?>

    <header>
    <h1><a href="<?php the_permalink(); ?>" title="<?php the_title();?>"><?php the_title(); ?></a></h1>
    <?php the_excerpt(); ?>
    </header>

</article>
</div>

<?php endwhile; endif; ?>

</div>
</div>




<div class="popularColumn">
<div class="columnContent">

<?
$nextArgs =  array(
    'post__not_in' => $loaded,
    'meta_key' => 'wpb_post_views_count', // Pega o número de visitas do post.
    'orderby' => 'meta_value_num', // Ordena do mais visitado para o menos visitado.
    'posts_per_page' => '3',
    'paged' => $paged
    );
 $next = new WP_Query( $nextArgs );

if ($next->have_posts()) : while ($next->have_posts()) : $next->the_post();
$loaded[] = $post->ID; 
?>

<div class="articleContent">
<article class="popular" role="article">
        <a href="<?php the_permalink();?>" title="<?php the_title();?>"><?php the_category();?>

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

</article>
</div>

<?php endwhile; endif; ?>

</div>
</div> 



<div class="randomColumn">
<div class="columnContent">

<?  
$recentsArgs =  array(
    'post__not_in' => $loaded,
    'posts_per_page' => '3',
    'paged' => $paged
    );
 $recents = new WP_Query( $recentsArgs );

if ($recents->have_posts()) : while ($recents->have_posts()) : $recents->the_post();
$loaded[] = $post->ID;
?>


<div class="articleContent">
<article class="random" role="article">
        <header>
        <h1><a href="<?php the_permalink(); ?>" title="<?php the_title();?>"><?php the_title(); ?></a></h1>
        </header>

</article>
</div>

<?php endwhile; endif; ?>

</div>
</div>

Penso che la soluzione potrebbe essere utilizzare una sessione php o una variabile che memorizza l'id dei post che sono già stati caricati, e nei loop controlla se i post sono stati caricati o meno prima di continuare. Ho provato a farlo ma non ha funzionato. Ho troppe competenze su php e forse qualcuno potrebbe avere un'idea migliore su come farlo funzionare.

Apprezzo qualsiasi aiuto. Grazie.

3

Questo potrebbe non risolvere il tuo problema, ma ti aiuterà in futuro a creare query personalizzate. L'impaginazione di più di una query può diventare estremamente complicata. Di default la compilazione in paginazione in Wordpress non ha questa logica per impaginare più query. Dovrai eseguire più query e unirle in qualche modo.

OK, ora a quello che vorrei sottolineare. Dovresti dare uno sguardo a WP_Query nel codice per vedere come creare correttamente una query personalizzata. Il tuo problema qui è che stai eseguendo tre query personalizzate senza reimpostarle. Ciò interromperà qualsiasi altra query che segue quella precedente

È di fondamentale importanza ripristinare tutte le query personalizzate create. TuHAVE TOfallo. È possibile farlo semplicemente chiamando wp_reset_postdata(); dopo ogni query per ripristinare la variabile $post. Guarda gli esempi nei link forniti

1
Pieter Goosen

È possibile ricreare l'array $loaded dal database:

$hot_ppp = 3;
$next_ppp = 3;
$recents_ppp = 3;

if ( $paged > 1 ) {
    $prev_hot_next_loaded = $wpdb->get_col( $wpdb->prepare(
        'SELECT ID FROM ' . $wpdb->posts . ' p JOIN ' . $wpdb->postmeta . ' pm ON pm.post_id = p.ID AND pm.meta_key = %s'
        . ' WHERE p.post_type = %s AND p.post_status = %s ORDER BY pm.meta_value+0 DESC LIMIT %d',
        'wpb_post_views_count', 'post', 'publish', ( $hot_ppp + $next_ppp ) * ( $paged - 1 )
    ) );
    $prev_recents_loaded = $wpdb->get_col( $wpdb->prepare(
        'SELECT ID FROM ' . $wpdb->posts . ' WHERE ID NOT IN (' . implode(',', $prev_hot_next_loaded ) . ')'
        . ' AND post_type = %s AND post_status = %s ORDER BY post_date DESC LIMIT %d',
        'post', 'publish', $recents_ppp * ( $paged - 1 )
    ) );

    $loaded = $prev_hot_next_loaded + $prev_recents_loaded;
}
0
bonger