1

In wordpress I added a function which sets the offset like so:

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

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

    $offset = 1;
    $ppp = 3;

    if ( $query->is_paged ) {
        $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
        $query->set('offset', $page_offset );
    }
    else {
        $query->set('offset',$offset);
    }
}

What is this function does is add an offset of 1 so that the first post doesn't get displayed. Which works fine perfect.

But of course with '!query->is_home' it litterly cuts every first post from every single query on my website.

What I need to do is apply this function to only one query.

So my question is: how can I select a specific query, is possible even possible do I need to do it some other way?

______________________Solution that worked for me__________________________

I was able to set the 'offset' parameter on the loop on my template page 'page-blog.php' like this without breaking the pagination(in functions.php):

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

        if ( !is_page_template( 'page-blog.php' )  ) {
        return ;
    }

    $offset = 1;
    $ppp = 3;

    if ( $query->is_paged() ) {
        $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
        $query->set('offset', $page_offset );
    }
    else {
        $query->set('offset',$offset);
    }
}

So now it applies the offset parameter to all loops on that page that are paged. To make it only apply to the queries that were paged I had to add the parameter 'posts_per_page'=> -1' to the query that isn't paged and doesn't need an offset. So in my case this was:

$featured_item = array(
    'post_type'=> 'post',
    'status' => 'publish',
    'posts_per_page'=> -1
);

get_posts($featured_item);

This solution allowed to display the latest post separately and of course the all the post with a pagination and offset. Maybe somebody will have use for it.

Many Thanks to s_h_dum, I am forever grateful for your help!

2
  • "What I need to do is apply this function to only one query." -- which query exactly?
    – s_ha_dum
    Nov 2, 2015 at 14:40
  • I edited it in the question
    – Noob17
    Nov 2, 2015 at 14:51

1 Answer 1

2

If you only wish to effect the one, single query then just can pass the offset argument through the arguments array.

$offset = 1;
$ppp = 3;

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

blog_items = array(
    'post_type'=> 'post',
    'paged' => $paged,
    'posts_per_page'=> $ppp,
    'status' => 'publish',
    'offset' => $offset
);

$blogposts = get_posts($blog_items);

But since you are trying to paginate you may still have trouble with that. It may work better to push all of the arguments through pre_get_posts not just some of them:

// in functions.php
add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

    if (is_main_query() || is_page_template( 'page-blog.php' ) ) {

      $offset = 1;
      $ppp = 3;

      if ( $query->is_paged ) {
          $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
          $query->set('offset', $page_offset );
      }
      else {
          $query->set('offset',$offset);
      }

      $query->set('post_type','post');
      $query->set('paged',$paged);
      $query->set('posts_per_page',3);
      $query->set('status','publish');

    }
}

Then a normal loop in the page template should work:

if(have_posts()) {
  while(have_posts()) {
    the_post();

  }
}

Use remove_action('pre_get_posts', 'myprefix_query_offset', 1 ); to remove the action.

9
  • Thanks! The second method works for me without the last 4 lines for some reason. Only problem is that I have another loop on that page where I'm displaying the latest post. Is there any way I can make the function not apply to that loop? Anyway thanks I at least making progress here!
    – Noob17
    Nov 2, 2015 at 18:20
  • Just remove the action after the Loop. See the edit. You aren't trying to paginate two different loops are you?
    – s_ha_dum
    Nov 2, 2015 at 18:30
  • Hey I placed that line after the function but whatever value I put there it still affect both loops on the 'page-blog.php' page. The first loops just obtains the latest post and and the second loop is the one that paginates and brings in all posts. So all I need to do is find a way to let that function not affect the first loop on that page.
    – Noob17
    Nov 2, 2015 at 22:09
  • Is it possible to target one loop on the same page? I have no clue how to do it. Do you know a way?
    – Noob17
    Nov 3, 2015 at 0:39
  • Yes you can but what I told you to do should work. Edit your template cade into the question olease
    – s_ha_dum
    Nov 3, 2015 at 0:42

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.

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