Codex tools: Log in / create account
Languages: English • 日本語 • (Add your language)
Contents |
Ajax (Asynchronous JavaScript And XML) is a technology that allows a web page to update some of its information without a full page reload. It is used in the Administration sections of WordPress for auto-save of post edits, adding new categories, and other purposes. Some WordPress Plugins also use AJAX for things like voting on post ratings and map refreshes.
This article, aimed at plugin developers, describes how to add Ajax to a plugin. Before reading this article, you should be familiar with the following:
It turns out that the techniques for adding Ajax to a plugin are quite different, depending on whether you want the Ajax functionality to be part of the WordPress administration screens, or to appear on the viewer-facing side of WordPress. So, this article treats those two possibilities separately (after discussing common considerations).
There are three steps in an Ajax request, in general:
Unfortunately, much of Ajax is JavaScript, which runs in the user's web browser, and the different web browsers have not all implemented the Ajax calls and responses in the same manner. So, to make things easier, most Ajax developers choose to use a tested cross-browser library that wraps the particular browser idiosyncracies in a standard class with a documented API. In this article, we'll use one such library, SACK (Simple Ajax Code-Kit), which is included in WordPress. The Further Reading section (see bottom of page) has several references for how to use JQuery to do AJAX -- JQuery is another library included in WordPress, and the concepts are pretty much the same, but the syntax is a bit different.
So, we'll need to make sure both the SACK library and the JavaScript functions that compose the Ajax request get included in the HTML head section of the web page where the Ajax request will take place; the sections below will show how to do that for both the administration and viewer-facing sides of WordPress.
When creating an Ajax request using the SACK library, we'll need to supply the following information; the sections below will fill in the details of what this information should be for the administration side and the viewer-facing side:
By default, SACK assumes that the returned information from the server is JavaScript code, which is executed when it comes in (asynchronously). In the examples below, we'll use this default behavior, so the PHP functions that are processing Ajax requests will need to compose their results into JavaScript commands. If you want to do something else with the returned information in your plugin, you might want to visit the SACK Project Home Page, download the zip file, and read the documentation, because there are definitely other possibilities.
One other detail is that the PHP function that processes the Ajax request should use the PHP die function at the end.
Since Ajax is already built into the core WordPress administration screens, adding more administration-side Ajax functionality to your plugin is fairly straightforward, and this section describes how to do it. As mentioned above, if you want to use Ajax on the blog-viewer-facing side of WordPress, you can completely skip this section of the article.
Here's a short example. All this will be in one file.
First, add some javascript that will trigger the AJAX request:
<?php
add_action('admin_head', 'my_action_javascript');
function my_action_javascript() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
var data = {
action: 'my_special_action',
whatever: 1234
};
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
jQuery.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
});
});
</script>
<?php
}
Then, set up a PHP function that will handle that request:
<?php
add_action('wp_ajax_my_special_action', 'my_action_callback');
function my_action_callback() {
global $wpdb; // this is how you get access to the database
$whatever = $_POST['whatever'];
$whatever += 10;
echo $whatever;
die();
}
That's it! You will need to add a few details, such as error checking and verifying that the request came from the right place ( using check_ajax_referer() ), but hopefully the example above will be enough to get you started on your own administration-side Ajax plugin.
As of WordPress 2.8, there is a new hook similar to 'wp_ajax_my_action':
'wp_ajax_nopriv_my_action' executes for users that are not logged in.
So, if you want it to fire for both visitors and logged-in users, you can do this:
add_action('wp_ajax_my_action', 'my_action_callback');
add_action('wp_ajax_nopriv_my_action', 'my_action_callback');
Note: In WP 2.8, if a user is not logged in ('wp_ajax_nopriv_my_action'), then GET requests are ignored (and return -1). This bug was fixed in WP 2.9.
Note 2: Unlike on the admin side, the "ajaxurl" javascript variable does not get automatically defined for you. Use this PHP code to generate the URL you need to call instead:echo admin_url('admin-ajax.php');
Implementing Ajax on the viewer-facing side in older versions of Wordpress is slightly more ad-hoc than doing Ajax on the administration side and this section describes how to do it.
As an example, let's consider a plugin that allows a blog viewer to vote on or rate something (which could be a generic poll plugin, a post rating plugin, or something else like that). When the blog viewer submits a vote, we want the submission to go via Ajax, so that the viewer doesn't have to wait for the page to refresh; after the vote is registered, we'll want to update the running vote total display. For this example, we'll assume the voting and display are text-based, for simplicity, and we'll assume you've either edited the theme or used a Wordpress filter or action to add HTML to the appropriate Wordpress viewer-facing screen. The added HTML will look something like this: </p>
<form> Your vote: <input type="text" name="uservote" /> <input type="button" value="Vote!" onclick="myplugin_cast_vote(this.form.uservote,'voteresults');" /> <div id="voteresults"> (previous results output from your PHP function) </div> </form>
Next, we need to define the JavaScript function myplugin_cast_vote, the onClick action for the button, which will read the information the user entered, compose a request with SACK, and send it to the plugin for processing. As mentioned in the introductory section, this JavaScript function and the SACK library need to get added to the HTML head section of the web page the user is viewing. One way to do that is to add it to all viewer-facing screens using the wp_head action (you could also be a little more selective by using some of the is_xyz() <a href="/Conditional_Tags" title="Conditional Tags">Conditional Tags</a> tests). Let's drop this in a plugin file myplugin.php:
add_action('wp_head', 'myplugin_js_header' );
function myplugin_js_header() // this is a PHP function
{
// use JavaScript SACK library for Ajax
wp_print_scripts( array( 'sack' ));
// Define custom JavaScript function
?>
<script type="text/javascript">
//<![CDATA[
function myplugin_cast_vote( vote_field, results_div )
{
// function body defined below
} // end of JavaScript function myplugin_cast_vote
//]]>
</script>
<?php
} // end of PHP function myplugin_js_header
Next activate the plugin and reload the HTML where the form is. By looking at the HTML source you should see the SACK Javascript library being loaded:
<script type='text/javascript' src='http://wordpress/wp-includes/js/tw-sack.js?ver=1.6.1'></script>
The next step is to fill in the body of the myplugin_cast_vote JavaScript function, which is supposed to read the vote from the form field, compose an Ajax request with SACK, and send the request to the server. Given the list of generic SACK information from the introductory section, here is what we need to set up for this example:
Putting this together, the body of the JavaScript function becomes:
function myplugin_cast_vote( vote_field, results_div )
{
var mysack = new sack(
"<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php" );
mysack.execute = 1;
mysack.method = 'POST';
mysack.setVar( "action", "my_special_action" );
mysack.setVar( "vote", vote_field.value );
mysack.setVar( "results_div_id", results_div );
mysack.onError = function() { alert('Ajax error in voting' )};
mysack.runAJAX();
return true;
} // end of JavaScript function myplugin_cast_vote
add_action('wp_ajax_my_special_action', 'my_action_callback');
add_action('wp_ajax_nopriv_my_special_action', 'my_action_callback');
Take special note of the Javascript code which has an "action" variable. Also take note that it is calling the admin-ajax.php file. Then note that my_special_action is part of the first parameter in the add_action call (wp_ajax_my_special_action). These are all significant.
The final step in this example is to define my_action_callback, which is what gets called when the Ajax request gets to the server. This will need to read the posted information, verify that the vote is valid, add the vote to the database, figure out what the new running totals are, and send that back to the browser. Leaving aside all the details of processing the vote, here's what needs to go into the file:
<?php
function my_action_callback() {
// Check request came from valid source here
// TO DO!
// read submitted information
$vote = $_POST['vote'];
$results_id = $_POST['results_div_id'];
// Put your vote processing code here
// In this example, assume
// a) The processing code sets global
// variable $error to a message if there is an error
// b) If there is no error, $results contains
// the HTML to put into the results DIV on the screen
// Here you can even access the database by using the
// global $wpdb
$error = "";
$results = "HTML to put into the results DIV on the screen";
if( $error ) {
die( "alert('$error')" );
}
// Compose JavaScript for return
die( "document.getElementById('$results_id').innerHTML = '$results'" );
}
?>
That's it! You will need to add a few details, such as error checking, escaping quotes, processing the vote, and verifying that the request came from the right place, but hopefully the example above will be enough to get you started on your own viewer-side Ajax plugin.