0

I'm currently working on calling the next page of posts through ajax. I'm making my request with jQuery, building a custom query in my php handler function, looping through it and then sending back the HTML. This is my loop:

  $args = $_REQUEST['query'];

  $request_query = new WP_Query($args);

  if ($request_query->have_posts()) {
      while ($request_query->have_posts()) {
          $request_query->the_post();

          if ($post->post_type == 'foo') {
              get_template_part('/parts/thumbnail-templates/foo');
          } else if ($post->post_type == 'bar') {
              get_template_part('/parts/thumbnail-templates/bar');
          } else {
              get_template_part('/parts/thumbnail-templates/generic');
          }
      }
  }

Everything works correctly and the loop runs as expected, except that I get an error that states $post is undefined, so my two ifs fail, as well as some lines inside my templates which call metadata like this $post->the_meta_key.

I figure the reason this happens is that there's some other wp magic that runs behind the scenes and makes $post available in template files, but not in ajax. Hence, I added global $post; just before my if statements and now it works as expected.

The question

Is it okay to call global $post; inside the loop in ajax or is there a better way to access the current post object? Also, if there are any general best practice suggestions for changes in my approach, please let me know.

1 Answer 1

0

Is it okay to call global $post; inside the loop in ajax or is there a better way to access the current post object?

I'd do it outside the loop but in the same scope to avoid duplication, but otherwise the answer is:

If it works, then it works, don't stress about it, there is no canonical one way to rule them all for this.

global $post; works, and there is another option of $post = get_post(); but it's rare. Most people just do global $post; out of habit.

You can also avoid it entirely by doing this:

if ( get_post_type() === 'foo' ) {

I figure the reason this happens is that there's some other wp magic that runs behind the scenes and makes $post available in template files, but not in ajax. Hence, I added global $post; just before my if statements and now it works as expected.

Nope, this theory is incorrect, post loops work the same in AJAX handlers

$args = $_REQUEST['query'];
$request_query = new WP_Query($args);

This should be considered a major security hole, as now anybody can query for anything, and they can trigger super expensive queries that will hammer your database aka resource exhaustion attacks. Whitelist the arguments you allow and their valid values!

2
  • Thanks for the security tip as well! Any recommendation on where to read more about common attacks so I can check my code more thoroughly?
    – Nasif
    Commented May 26, 2021 at 13:15
  • The WordPress PHPCS tool and its documentation will help there
    – Tom J Nowell
    Commented May 26, 2021 at 14:10

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.