WordPress AJAX tutorial – how to use AJAX in a WordPress theme or template

Posted on June 19, 2016 in Web Dev

Edit: the output of this tutorial can be seen with the ‘agree’ and ‘disagree’ buttons here: http://www.youthenme.com/sites/review/

I’m fairly experienced with using AJAX and its various jQuery shorthand implementations, but having never implemented AJAX into a WordPress theme I’ve had to do quite a bit of Googling.

I’m writing this post to show how I’ve implemented AJAX into WordPress this time around, and also to highlight some of the quirks and things to look out for while using AJAX in a WordPress theme.

How AJAX works in WordPress

It’s quite simple, but there’s an added layer compared to how you’d usually implement it. All AJAX calls get routed through the following URL:

 wp-admin/admin-ajax.php 

The way WordPress knows where to direct your AJAX call is via the ‘action’ parameter that your pass into the call. Here’s what that looks like:


$.ajax({
 type:"POST",
 url: ajaxurl,
 data: {
  action: "review_vote_ajax_request",
 },
 success:function(data){
  alert(data);
 },
 error: function(errorThrown){
  alert(errorThrown);
 }
});

You will notice that the ‘url’ parameter contains a variable called ‘ajaxurl’. This is globally set in my header.php file. It’s set there because this allows me to define the variable globally using a WordPress function via PHP. So in my header.php file I have this:


<script type="text/javascript">
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
</script>

All this looks like then when it echoes out is:

 var ajaxurl = "my-website.com/wp-admin/admin-ajax.php" 

So the AJAX call gets sent to /wp-admin/admin-ajax.php, and then the appropriate function gets called based on the ‘action’ parameter that you pass through via AJAX. In the case above, on the server side I want to process the AJAX call via a function called ‘review_vote_ajax_request’.

Because I envisage myself doing quite a few different AJAX calls in this particular theme, and because it’s best practice regardless, I decided to put the PHP processing function into its own file called /inc/ajax.php. Then I include this into my functions.php file. I do this to keep everything more organised, otherwise, as with most WordPress stuff that I see, my project ends up being a bunch of functional spaghetti code!

Warning

One extremely silly error I made here though, which is not related to WordPress but to my own stupidity and tiredness while coding, was that I actually forgot to include my ajax.php file into my functions.php file. This meant that the server side function associated with my AJAX call actually never existed. It took 2 hours of debugging until I realised – what a nightmare!

The reason I’m adding this warning into this article, is because it actually forced me to learn a subtle nuance of WordPress’ AJAx implementation. The function essentially didn’t exist, but WordPress was returning ‘0’ to the AJAX call response. It didn’t return anything like ‘function doesn’t exist’ etc. – it simply returned an integer of 0. This is the reason it took me so long to debug – it wasn’t immediately obvious that my function wasn’t even included as it would be if this wasn’t an AJAX call.

The server side code

There are a few things to watch out for in your PHP function that takes the AJAX call.

Logged in or logged out

As a security precaution, WordPress requires you to explicitly make the AJAX function accessible to non-authenticated users. To enable the AJAX call to non-auth users, you must include the following action:


add_action( 'wp_ajax_nopriv_review_vote_ajax_request', 'review_vote_ajax_request' );

Don’t forget to replace ‘_review_vote_ajax_request’ with your own function name.

You also need to include the action to explicitly enable this for authenticated users:


add_action( 'wp_ajax_review_vote_ajax_request', 'review_vote_ajax_request' );

Kill the function

You must include the following at the end of your PHP AJAX function:


wp_die();

Echo not return

I’m used to returning my AJAX responses from the server in Laravael where I’ll ‘return’ the response. However you must echo out your response back to AJAX, instead of returning it.

The final code

Here’s my javascript:


jQuery(function($) {

$('body').on('click', '.review-helpful-answer', function(e) {
e.preventDefault();

var $reviewId = $(this).attr('data-review-id');

var post_id = $(this).data('id');
$.ajax({
type:"POST",
url: ajaxurl,
data: {
action: "review_vote_ajax_request",
post_id: post_id
},
success:function(data){
alert(data);
},
error: function(errorThrown){
alert(errorThrown);
}
});

})

});

And the PHP function:


function review_vote_ajax_request() {

// do what you want with the variables passed through here

$post_id = $_REQUEST['post_id'];

echo $post_id;

wp_die();
}

add_action( 'wp_ajax_nopriv_review_vote_ajax_request', 'review_vote_ajax_request' );
add_action( 'wp_ajax_review_vote_ajax_request', 'review_vote_ajax_request' );

 

Leave a comment

Was this helpful? Did I miss something? Do you have a question? Get in touch, or tell me below.