0

At the bottom of my page I am trying to display some recent projects based on a pre-selected list of post IDs.

I have built a custom query to try and retrieve the 3 specific posts (WHERE custom_post_type = project) at the bottom of my page

$projectIDs = array( [0] => 79, [1] => 98, [2] => 108 );

$args = array( 'post_type' => 'projects', 'post__in ' => $projectIDs, 'posts_per_page' => 3 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
endwhile;

PROBLEM: It is returning 3 completely different posts: 110, 108, 111 - Didn't even return one of them. I can see in the query it filters the post_type but there is no filter for the post__in ...

I don't play with WP Query much so not sure if I'm even calling it correctly BUT, when I analyse the results var_dump($loop) I see the posts aren't even being queried:

object(WP_Query)#9671 (49) {
  ["query"]=>
  array(3) {
    ["post_type"]=>
    string(8) "projects"
    ["post__in "]=>
    array(3) {
      [0]=>
      int(79)
      [1]=>
      int(98)
      [2]=>
      int(108)
    }
    ["posts_per_page"]=>
    int(3)
  }
  ["query_vars"]=>
  array(65) {
    ["post_type"]=>
    string(8) "projects"
    ["post__in "]=>
    array(3) {
      [0]=>
      int(79)
      [1]=>
      int(98)
      [2]=>
      int(108)
    }
    ["posts_per_page"]=>
    int(3)
    ...
  ["request"]=>
  string(276) "SELECT SQL_CALC_FOUND_ROWS  wpKX_posts.ID FROM wpKX_posts  WHERE 1=1  AND wpKX_posts.post_type = 'projects' AND (wpKX_posts.post_status = 'publish' OR wpKX_posts.post_status = 'acf-disabled' OR wpKX_posts.post_status = 'private')  ORDER BY wpKX_posts.post_date DESC LIMIT 0, 3"
  ["posts"]=>
  array(3) {
    [0]=>
    object(WP_Post)#9663 (24) {
      ["ID"]=>
      int(110)
      ...
    }
    [1]=>
    object(WP_Post)#9603 (24) {
      ["ID"]=>
      int(108)
      ...
    }
    [2]=>
    object(WP_Post)#9602 (24) {
      ["ID"]=>
      int(111)
      ...
    }
  }
  ["post_count"]=>
  int(3)

What am I doing wrong?

4
  • 1
    in your array of post ids, check your indexes $projectIDs = array( [0] => 79, [1] => 98, [0] => 108 );, why both 79 and 108 has 0 as index? – Vishwa May 3 '19 at 3:40
  • Because I manually typed them - that's just human error – php-b-grader May 3 '19 at 3:57
  • I'm not judging, just pointing out a possible cause for your problem AIS – Vishwa May 3 '19 at 4:10
  • 1
    @php-b-grader, be sure to read my answer. I'm not asking you to accept it, but it's important for you to understand the actual problem in your code. :) – Sally CJ May 3 '19 at 5:41
2

(Revised to improve the wording)

Actually, you do not have to set the orderby to post__in for post__in query to work. There's no such limitation in WordPress and you'd only need to set 'orderby' => 'post__in' when you want to sort the posts exactly in the same order as the post IDs in the post__in parameter. :)

And the actual problem in your code, is that WordPress (or the WP_Query class) doesn't recognize your post__in parameter because there is a trailing space inside the parameter name — PHP doesn't automatically remove trailing spaces in array keys or even values, and so does WordPress (i.e. the spaces are preserved); so $args['post__in '] (note the space) and $args['post__in'] are two different array items:

$args = array( 'post_type' => 'projects', 'post__in ' => $projectIDs, 'posts_per_page' => 3 );

And even in the var_dump() output, you could quite clearly see the trailing space here:

["post__in "]=>

So the fix is simple: remove the space. And try again with your query, where you should see it now has the proper IN clause:

AND wpKX_posts.ID IN (79,98,108)

And actually, you don't need to manually add the indexes here:

//$projectIDs = array( [0] => 79, [1] => 98, [2] => 108 );
$projectIDs = array( 79, 98, 108 ); // no manual indexes; still would work fine
3
  • Ok, that's it. Last bit - the array is being generated by code - arrays automatically add their own indexes... – php-b-grader May 6 '19 at 1:13
  • Seriously? Tou took time to add that comment? WTF? At no stage did i ask for help with the array ... try and stay on topic. – php-b-grader May 7 '19 at 9:03
  • Actually, if that array help made the answer be disqualified to being accepted, then fine. But you see, when someone helped or even tried to help you, I think it's wiser to say "thank you" than to argue "why did you or you shouldn't help me with that". – Sally CJ May 7 '19 at 10:20
0

In Wordpress 3.5 and up you can use 'orderby'=>'post__in' then you must write this:

<?php
$projectIDs = array(79, 98, 108);
$args = array( 'post_type' => 'projects', 'post__in ' => $projectIDs, 'posts_per_page' => 3, 'orderby'=>'post__in' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
endwhile;
?>
3
  • Thanks. That works... But why is the post__in ignored until I add orderby? I couldn't find anything about that in the doco – php-b-grader May 3 '19 at 3:59
  • @php-b-grader Set orderby to post__in. This preserves post ID order given in the post__in array (available with Version 3.5). And also Using post__in within the orderby value it will honour the order of the array of IDs passed in post__in – Tanmay Patel May 3 '19 at 4:03
  • @php-b-grader Thank you for this. please mark (tick) as green mark of my answer as well as click on up arrow for "This answer is useful" so it can help for someone which is finding like this. – Tanmay Patel May 3 '19 at 4:03

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.