0

I have two loops in home page (index.php)

<?php
    $args = array(
      'post_type'      => 'post',
      'posts_per_page' => 3,
    );

    $another_query = new WP_Query($args);
    if( $another_query->have_posts() ) {
      $i = 0;
      while ($another_query->have_posts()) : $another_query->the_post(); ?>
        <?php if($i == 0) { ?>
          <div class="col s8">
            <?php get_template_part( 'template-parts/content-magazine-grid-big', get_post_format() ); ?>
          </div>
        <?php } ?>

        <?php if($i == 1 || $i == 2) { ?>
          <div class="col s4">
            <?php get_template_part( 'template-parts/content-magazine-grid-small', get_post_format() ); ?>
          </div>
        <?php } ?>

       <?php $i++;
        if($i != 0) { ?>

          <?php
        } ?>

        <?php
      endwhile;

    }

    wp_reset_postdata();
    ?>

And another one

 <?php

    $args = array(
      'post_type' => 'post',
      'paged'     => $paged,
      'posts_per_page' => 2,
      'offset' => 3,
      'orderby'        => 'date',
      'order'          => 'DESC',
    );
    $args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
    $i=0;
    $query = new WP_Query($args);
    $temp_query = $wp_query;
    $wp_query   = NULL;
    $wp_query   = $query;
    while ($query->have_posts()) : $query->the_post(); ?>

          <?php get_template_part( 'template-parts/content-rest', get_post_format() ); ?>

        <?php  $i++; endwhile;    ?>
      <?php previous_posts_link();next_posts_link();
     ?>
    <?php
    // Need this to reset the query
    $wp_query = NULL;
    $wp_query = $temp_query;
    ?>

I want pagination on last loop.. But it's not working...

5
  • 'offset' does not work together with pagination. find a different way to exclude the three first posts; the Codex has examples; codex.wordpress.org/The_Loop#Multiple_Loops_in_Action
    – Michael
    Mar 31, 2016 at 15:22
  • @Michael although you are correct, the page you linked to is a pile of crap. Unfortunately that is just one of those many really poorly written pages in the codex Mar 31, 2016 at 15:26
  • @PieterGoosen - to offset three posts via 'pre_get_posts' will work in this case, as the second query uses the default values for 'orderby' and 'order'. in any other case, for example returning random post in the second query, would imho better work with excluding exact the previously shown posts. - the shown code has other flaws as not using the proper pagination codes, and not taking into account that on paginated pages, the first three posts should possibly also be paginated. unfortunately, the question does not contain any explanation what is really intended with the code.
    – Michael
    Mar 31, 2016 at 18:32
  • @Michael if the first three posts needs to be paginated, then this would be a duplicate of this question ;-) As for random ordering, your method you linked to will not work, paging randomly ordered queries is a mess. IMHO, it still stays bad practice to just simply skip posts in the loop. Much better to remove posts through the post__not_in parameter through pre_get_posts. Mar 31, 2016 at 18:50
  • @PieterGoosen - I totally agree to your remarks.
    – Michael
    Mar 31, 2016 at 19:27

2 Answers 2

1

You do need to run a custom query for your second loop. You can simply adjust the main query to your needs. It is always never a good idea to run custom queries in place of the main query. One big issue is always pagination, WordPress disregards all other queries, and only focus on the main query when it comes to page functionality. I have done a quite extensive post on this, so be sure to check it out here

We can drop the second query, and just use pre_get_posts to alter the main query. Because we use offset here, we need to manually calculate pagination as we are breaking WP_Query's process which calculates pagination

add_action( 'pre_get_posts', function ( $q )
{
    if (    $q->is_home()       // Only target the home page
         && $q->is_main_query() // Only target the main query
    ) {
        // Get the current page number
        $current_page = get_query_var( 'paged', 1 );
        // Set offset
        $offset = 3;
        // Set posts per page
        $ppp = 2;

        if ( !$q->is_paged() ) {
            // Set page one offset
            $q->set( 'offset',         $offset );
            $q->set( 'posts_per_page', $ppp    );
        } else {
            // Handle pagination for paged pages
            $offset = $offset + ( ( $current_page - 1 ) * $ppp );
            $q->set( 'offset',         $offset );
            $q->set( 'posts_per_page', $ppp    );
        }
    }
});

You should now have your main query correctly paginated with one problem, the last page might, depending on the amount of posts, 404'ing. To adjust for that, we need to adjust the $found_posts property of the main query.

add_filter( 'found_posts', function ( $found_posts, $q ) 
{
    $offset = 3;

    if(    $q->is_home() 
        && $q->is_main_query() 
    ) {
        $found_posts = $found_posts - $offset;
    }

    return $found_posts;
}, 10, 2 );

Needless to say, your main loop on your homepage should now just be as follow

if ( have_posts() ) :
    while ( have_posts()) : 
        the_post(); 

        get_template_part( 'template-parts/content-rest', get_post_format() );

    endwhile;
    previous_posts_link();
    next_posts_link();
endif;
0
0

I have not tried it, but I think it should be like this:

$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$args = array(
  'post_type'       => 'post',
  'paged'           => $paged,
  'posts_per_page'  => 2,
  'offset'          => 3,
  'orderby'         => 'date',
  'order'           => 'DESC'
);
1
  • Unfortunately this won't work. offset breaks pagination, so you would need to manually recalculate pagination and offset for each and every page. It is quite a messy process ;-) Mar 31, 2016 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.