WordPress.org

Ready to get started?Download WordPress

Forums

Offset and Pagination with a Custom Query (5 posts)

  1. Adam
    Member
    Posted 1 year ago #

    I've been trying to get "offset" to work with pagination. Using this page from the WordPress.org Docs, I've tried to get offset to work with my posts query. For whatever reason, the code doesn't do anything except to make my pagination links (Page 1 of 2, 1, 2, 3, 4, >, etc.) disappear.

    I've got a custom post type that I'm querying, and want to leave out just the first post because I am going to style just the first post differently from the rest of the posts that are listed. Here's what I've got so far:

    <!--  begin WordPress' code  -->
    <?php 
    
    add_action('pre_get_posts', 'query_offset', 1 );
    function query_offset(&$query) {
    
        //Before anything else, make sure this is the right query...
        if ( ! $query->is_posts_page ) {
            return;
        }
    
        //First, define your desired offset...
        $offset = 1;
    
        //Next, determine how many posts per page you want (we'll use WordPress's settings)
        $ppp = get_option('posts_per_page');
    
        //Next, detect and handle pagination...
        if ( $query->is_paged ) {
    
            //Manually determine page query offset (offset + current page (minus one) x posts per page)
            $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
    
            //Apply adjust page offset
            $query->set('offset', $page_offset );
    
        }
        else {
    
            //This is the first page. Just use the offset...
            $query->set('offset',$offset);
    
        }
    }
    
    add_filter('found_posts', 'adjust_offset_pagination', 1, 2 );
    function adjust_offset_pagination($found_posts, $query) {
    
        //Define our offset again...
        $offset = 1;
    
        //Ensure we're modifying the right query object...
        if ( $query->is_posts_page ) {
            //Reduce WordPress's found_posts count by the offset...
            return $found_posts - $offset;
        }
    }
    
    ?>
    <!--  end WordPress' code  -->
    
    <!--  begin my code  -->
    <?php
    query_posts(array(
    	'post_type' => 'post_type_name',
    	'posts_per_page' => 8,
    	'orderby'=> 'date',
    	'order' => 'DESC',
    	'paged' => $paged
    ));
    ?>
    
    <?php if(have_posts()) : while(have_posts()) : the_post(); ?>
    
    	<?php the_title(); ?>
    
    <?php endwhile; ?>
    
    	<?php wp_pagenavi(); ?>
    
    <?php endif; wp_reset_query(); ?>
    <!--  end my code  -->

    Any ideas how to work WP's code with my query? Thanks in advance!

  2. mkokes
    Member
    Posted 1 year ago #

    I'm running into this same problem, where you able to find a solution?

  3. Adam
    Member
    Posted 1 year ago #

    @mkokes - I haven't been able to solve this one yet. If I do, I'll post back. As I'm not a PHP programmer, I'm hoping someone else knows how to get this to work. :(

  4. mwarner1
    Member
    Posted 7 months ago #

    FWIW, I solved this problem today using a different method.

    My task was to make sure my category page skipped the first three posts in that category:

    // Get IDs of first three items in "news" category (category 1), which will be skipped
    
    $skipIDs = '';
    $query2 = new WP_Query( 'cat=1&posts_per_page=3' );
    if ( $query2->have_posts() ) {
    	while ($query2->have_posts()) {
    		$query2->the_post();
    		$skipIDs[]=$post->ID;
    	}
    }
    
    wp_reset_postdata();	
    
    // now on to the Loop
    
    	while ( have_posts() ) : the_post();
    		if ( in_array($post->ID, $skipIDs) ) { continue; }

    And then the Loop continues as normal.

  5. mwarner1
    Member
    Posted 7 months ago #

    Just as a followup to my previous post, I think I found a better way. The problem with the previous post is that the preference for posts per page is overridden; so, for example, if in your settings you said to post 10 posts and then the "continue" method I just outlined, you would only get 7 posts on the first page.

    So, in my new and improved method, I passed the $skipIDs array into WP_Query as a post_not_in argument, and also passed in a $paged variable to get the correct posts. Here's the code I'm working with now:

    // Get IDs of first three items in "news" category (category 1), which will be skipped
    	$skipIDs = '';
    	$query2 = new WP_Query( 'cat=1&posts_per_page=3' );
    	if ( $query2->have_posts() ) {
    		while ($query2->have_posts()) {
    			$query2->the_post();
    			$skipIDs[]=$post->ID;
    		}
    	}
    	wp_reset_postdata();	
    
    	$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;	
    
    	$args = array(
    		'cat' => 1,
    		'post__not_in' => $skipIDs,
    		'paged' => $paged
    	);
    	$query = new WP_Query($args);
    	if ( $query->have_posts() ) {
    		while ($query->have_posts()) {
    		// post content
    			$query->the_post();
    			the_title();
    			echo '<p>&nbsp;</p>';
    		}

Topic Closed

This topic has been closed to new replies.

About this Topic