0

I can't seem to find an answer/solution to this. If there is one out there, please post a link.

My understanding is that in a wp_query, offset refers to the results of the query. So if I set 'offset' => 4, it will ignore the first 4 posts that match the arguments.

What I'm interested in is ignoring the most recent - let's say - 4 posts and only run the query and check for posts that match the arguments starting with the 5th post.

Is this even possible?

Thank you

EDIT:

Let's say I have 10 posts (from newest to oldest):

  • Post 10
  • Post 9
  • Post 8
  • Post 7
  • Post 6
  • Post 5
  • Post 4
  • Post 3
  • Post 2
  • Post 1

Let's assume my query WITHOUT ANY OFFSETTING generates a list of 5 posts:

  • Post 9
  • Post 6
  • Post 4
  • Post 3
  • Post 1

Regardless of how I order my results, if I offset them by 4 (again, based on my understanding of how offset works), I am now left with 1 post. Let's say I leave them ordered by default. Offsetting them gives me a list with only Post 1.

However, if I manage to skip the very first 4 posts before I even "run" the query (that would be Post 10, Post 9, Post 8, and Post 7) and only after that run the query and not offset the results at all (all other arguments remaining the same), I now get a list of 4 posts: Post 6, Post 4, Post 3, and Post 1.

And this is what I'd like to accomplish.

5
  • Think I get it. Some context would be useful though. What's the function or condition that will allow you to skip the first 4 posts in the second case? Or you just want to arbitrarily skip the 4 newest posts regardless of how old they are or whether or not they match the thing you're searching for?
    – mozboz
    Jun 22, 2020 at 21:41
  • Exactly. I want to skip the absolute 4 (or any other number) newest posts on the blog (regardless of absolutely anything else: date, category, tags, etc.), and once those have been ignored and are completely out of the picture, it is then and only then that the query would run for the remaining posts. If the entire blog has a grand total of 100 posts, I want to ignore the 4 most recent ones and run the query for the remaining 96 posts.
    – tzucu79
    Jun 22, 2020 at 21:48
  • gotcha. i was just thinking about it, and it does require two queries. you need one query to find the first 4 ones you want to ignore, then the second query with whatever your matching condition is for that, then you need to run through the second query excluding anything if it's in the results from the first query. That's probably achievable by running WP_Query twice, but I don't think it would be possible with just one call. I'll update the answer with how you could do this if you want to run it twice
    – mozboz
    Jun 22, 2020 at 21:51
  • In my case I'm already dealing with 2 nested queries. Unless I'm misunderstanding you, this would add a third query into the mix, and I'd rather not. I was hoping for a simple, quick, and more straightforward solution. You can edit your answer, and - unless someone else provides the kind of answer I'm looking for - I'll accept it since it would solve the problem as asked initially.
    – tzucu79
    Jun 22, 2020 at 22:01
  • probably without going to SQL there's no neat way to do this, and even with SQL it would require a sub-select I think. i'll add the answer as it's not super complicated
    – mozboz
    Jun 22, 2020 at 22:04

2 Answers 2

1

Sure! There are tons of parameters for WP-Query that can probably do what you want.

Offset is usually used when your data is ordered. So if you want to ignore the two most recent ones you need to order it by date descending first, then set offset = 2. It doesn't matter if you apply any other query parameters you have before or after the date thing - you don't need to do the offset first and then do a second query with other parameters.

You can also add other arguments to the same query if you want it to do something more complicated at the same time, which will apply to all of the results (before and after the offset, which is ok). E.g. search for a search time or choose something in particular category or anything else. But ordering by date is what will help you skip past e.g. the 2 most recent.

Here's how you do that:

$args = array(
    // order by date
    'orderby' => 'date',
    'order'   => 'DESC',  // descending dates will give you most recent first

    // any extra stuff you want, e.g. search for posts with 'car' but not 'red'
    's' => 'car -red',

    // display posts from the 3rd one onwards, so with date order this will skip two most recent
    'offset' => 2
);

$query = new WP_Query( $args );

If you have a more complicated query you want to do please post more details!

1
  • Thank you for your time mozboz. However, your response is not what I'm looking for. Offsetting the results of my query is exactly what I'm trying to avoid (regardless of how I order them). Please see edited question.
    – tzucu79
    Jun 22, 2020 at 19:58
0

So adding another answer now I understand your case better. There may be a way to do this with SQL, but probably with WP_Query is neater and inside WP way of doing things:

$excludeArgs = array(
    'orderby' => 'date',
    'order'   => 'DESC',  // descending dates will give you most recent first       
);

$queryExclude = new WP_Query( $excludeArgs );
$excludeThisMany = 4;
$countExclusions = 0;

$excludeIDs = [];

while ($queryExclude->havePosts() && ($countExclusions < $excludeThisMany)) {
    $queryExclude->thePost();
    $excludeIDs[] = the_ID();
    $countExclusions++;
}

$matchArgs = array(
    // whatever you want to match on
    s => 'unicorns -rainbows'
);

$queryMatch = new WP_Query( $matchArgs );

while ($queryMatch->havePosts()) {
     $queryMatch->thePost();
     if (!in_array(the_ID(), $excludeIDs)) {
           // only get here if it's not one of the first exclusions
           // render this stuff
     }
}

That will do it. I can't test this, but hopefully you get the idea and can fix it if it's not exactly right for you. Remember to add a wp_reset_postdata(); after if you need it to get back to the main post's data.

Your Answer

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

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