1

I have really been struggling with getting the main loop for the index.php to work properly with WP_Query functions. I need the grid array of 6 featured images at the top to not be offset at all, while offsetting the main posts loop below it by 6 posts.

Anything involving query_posts() inevitably ends up breaking the pagination. Using a single loop fixes the pagination issue, but undesirably applies the offset to the featured grid section. I have managed to get the pagination main loop to work using WordPress codex's recommended fix of pre_get_posts https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination. However, this fix overwrites the featured posts loop settings by 6 as well.

The offset/pagination dilemma seems to be a well known issue to WordPress developers, and I've browsed dozens of articles, forums, and tutorials but I can't find much documentation on what to do when the pre_get_posts fix overrides other custom loop settings on the index. The pre_get_posts works to a degree, I just want the formatting to only apply to the main posts loop on the home page, not the top 6 posts.

Here is the code. Thanks for taking the time to read this.

index.php:

<?php get_header(); 
do_shortcode( '[mg-masonry_js]' );
$options = get_option('mg_options');
$option_cats = $options['mg-posts-categories'];
$option_pg_number = $options['mg-posts-post-per-page'];
$args = array(
    'post_type' => 'post',
    'post_status' => array( 'publish' ),
    'posts_per_page' => $option_pg_number,
    'orderby' => 'date',
    'order' => 'DESC',
    'cat' => $option_cats,
    'offset' => 0,
);
?>

<div id="all-content-wrapper">
<div id="home-content" >
<div id="grid">

<?php if ($paged < 1 ) {
    $paged = get_query_var('paged'); ?>

<?php  // initialize main loop  ?>      

<?php   $grid_query = new WP_Query( $args );

    if ( $grid_query->have_posts() ) : 
        while ( $grid_query->have_posts()) : $grid_query->the_post(); 
?>

        <?php   switch ( $grid_query->current_post ) {
                case 0 :
        ?>
            <?php  // First featured image code here    ?>
            <?php   echo get_template_part('grid_featured');    ?>

                <?php break; ?>

            <?php  // Grid image array code here    ?>  
            <?php default : ?>
            <?php   echo get_template_part('grid'); ?>

        <?php } ?>  <?php  // end switch ?> 

    <?php endwhile; 

wp_reset_postdata(); 
rewind_posts();
else : ?>
        <h2><?php _e('No posts.', 'news portal' ); ?></h2>
        <br><br><p class="lead"><?php _e('No posts to display.', 'news portal' ); ?></p>
<?php endif; ?> 

<?php  }    // end paged switch ?> 
</div>   <?php // end grid ?> 

<div id="primary" class="content-area">
    <main id="main" class="site-main" role="main"> 

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

<?/* Start the Loop */?>
    <? $main_query = new WP_Query( $args ); 
    if ( have_posts() ) :

        while ( have_posts() ) : the_post();

            get_template_part( 'template-parts/blog', get_post_format() );

        endwhile;

        echo regular_pagination();

    else :

        get_template_part( 'template-parts/content', 'none' );

    endif; ?>

</main><!-- #main -->
</div><!-- #primary -->

<?php news_portal_get_sidebar();?>

</div><!-- #all_content_wrapper -->

<?php get_footer();?>

functions.php:

/*--Offset Pre_Get_Posts pagination fix--*/
add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

if ( ! $query->is_home() ) {
    return;
}

$offset = 6;

$ppp = get_option('posts_per_page');

if ( $query->is_paged ) {

    $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );

    $query->set('offset', $page_offset );

}
else {

    $query->set('offset',$offset);

}
}

add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {

$offset = 6;

if ( $query->is_home() ) {
    return $found_posts - $offset;
}
return $found_posts;
}
2

I messed around with the code some more, and my particular issue actually ended up relating to the original if statement parameters. Changing the condition to check the home page for queries to

if ( $query->is_home() && ! $query->is_main_query() ) {
    return;
} 

and

else {
    //This is the first page. Just use the offset...
    if ( $query->is_home() && $query->is_main_query()) {
    $query->set('offset',$offset);
}
}
}

made it so that the existing offset and posts per page arguments would be true for the main query loop, with the default else conditions declared in the index.php file applying to the secondary grid loop as desired. The second if statement condition needed to be added since without it there was a weird theme breaking bug that kept removing the first six items from the media library and posts.

These links might help clear up similar issues:

https://wordpress.stackexchange.com/questions/tagged/pre-get-posts

What is "main query"?

https://wpshout.com/practical-uses-pre_get_posts/

https://www.billerickson.net/customize-the-wordpress-query/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.