WordPress Plugin Development Tutorial Manual - JavaScript, Ajax and jQuery
JavaScript is an important part of many WordPress plugins, Wordpress built-in a number of commonly used JavaScript libraries to help us reduce the workload, the most commonly used is jQuery, we can use jQuery in the WordPress plugin to deal with DOM objects, perform Ajax operations and so on.
jQuery
Using jQuery
Once the WordPress page is loaded, jQuery will run in the user's browser. A basic jQuery statement consists of two parts, a selector that determines which HTML elements the code will be applied to, and an action or event that determines the action that executes the code and the reaction to the action. jQuery's basic statement is as follows:
jQuery.(selector).event(function);
The callback function defined inside the last set of parentheses is executed when an event (such as a mouse click) occurs on the HTML element selected by the selector.
The following sample code is part of the source code for an HTML page, assuming it is a WordPress backend page defined by the file myplugin_settings.php, which contains a form with a radio button next to each heading.
<form id="radioform">
<table>
<tbody>
<tr>
<td><input class="pref" checked="checked" name="book" type="radio" value="Sycamore" row />Sycamore Row</td>
<td>John Grisham</td>
</tr>
<tr>
<td><input class="pref" name="book" type="radio" value="Dark" witch />Dark Witch</td>
<td>Nora Roberts</td>
</tr>
</tbody>
</table>
<input type="hidden" name="trp-form-language" value="en"/></form>
On the page, the output of the above code should look something like the image below.
In the article introducing Ajax, we'll build an Ajax request that saves the user's selected options in user_meta and adds the number of posts containing the selected tags. This example doesn't make a lot of sense, but it illustrates the important steps in performing an Ajax operation. The jQuery code can be included in an external file or written directly into a block inside the page. In the example below, we've put the code in an external file, but if we had put it in a PHP page, it would have been very easy to make a mistake when passing variables from PHP. If you prefer to put the code directly into the page, the effect is the same.
Selectors and Events
The jQuery selector is similar to the CSS selector, containing a .class or #id or other jQuery Selector, but we'll use these two most often, in our example we'll use the .pref class selector. jQuery events are also plentiful, the one we'll use the most is the "click", in our example we'll use the "change " event to capture the user's click on the radio button. Note that the naming convention for jQuery events is usually different from JavaScript, and so far in the examples we've added an empty anonymous function.
$.(.pref).change(function(){
/*do stuff*/
});
This code will "perform some action" when any of the "pref" classes change.
Ajax
What is Ajax?
Ajax stands for Asynchronous JavaScript And XML. XML is a data exchange format, and Ajax is an Internet communication technology that allows a user to request specific information from a server on a single page, and then update some of the information on the page without having to refresh the entire page. Imagine all the ways in which Ajax can enhance the user experience.
XML is one of the more traditional data exchange formats, and virtually any format can be exchanged through Ajax. When developing pages in PHP, many developers prefer JSON because it is a simple and convenient data format, and the conversion between PHP and JSON is very easy.
If you want to experience Ajax for yourself, you can open a WordPress category management page, add a category, the newly added category immediately appears in the right category list, and the whole process, the page is not refreshed.Ajax does not even require user action to work, we edit WordPress posts or pages, do not have to click on the Save button, every Every few minutes, the page will be saved automatically.
Why use Ajax?
Obviously, Ajax improves the user experience, Ajax helps us to provide the user with a timely response to the dynamic page to the user, rather than presenting a boring static page. When the user performs some operation on the page, they can get timely feedback on what the result of the operation is and whether the operation is correct or not. Important form fields can be validated as they are typed, or suggestions can be provided based on the user's input, so that when the user fills out the form, they don't have to submit the entire form to know if each field was typed correctly.
Ajax can significantly reduce the amount of data transferred, and only the necessary data will be transferred without having to reload the entire page and transfer all the content on the page.
in particularDeveloping WordPress PluginsAjax is a good way to interact with content. If we have written PHP before, we may need to submit the content to an external PHP page and interact with the content through the external page. The problem with this is that we can't access WordPress functionality through this external PHP page. If you really want to do this, you can include the core WordPress bootstrap file wp-load.php in the external PHP to access the core WordPress functionality.
The architecture of WordPress is now flexible enough to allow us to move the wp-content directory to another location, in which case we may not know the exact path to wp-load.php. In contrast, we can know exactly where to send the Ajax request because it is defined in the global JavaScript variable. Developing an Ajax handler in PHP is actually mounting the handler on an Action hook, so we can use all the functionality of WordPress through the Ajax handler, unlike an external PHP file.
How to use Ajax?
If we're new to WordPress but have experience using Ajax in other environments, we'll need to relearn a few new things. The way WordPress implements Ajax may be different than what we're used to, but if we're new to Ajax development, we won't have that problem. We'll learn the basics here, and once we've developed a basic Ajax handler, it's a simple matter of expanding on that and developing a killer application with a great interface.
Any Ajax handler in WordPress has two main components, the client-side JavaScript and the server-side PHP handler, and all Ajax handlers follow the following two steps.
- A page event fires a JavaScript function that collects some data from the page and sends it to the server via an HTTP request. It's a bit tricky to handle HTTP requests directly with JavaScript code, so WordPress comes bundled with the jQuery library, so we can use the Ajax methods provided by jQuery to implement HTTP requests directly. Of course, if we are a JavaScript expert, we can also use native JavaScript code to send HTTP requests.
- When the server receives a request, it will do some processing of the data and then send the result of the processing to the client browser in the form of an HTTP response. It is not necessary to return the result, but it is a common practice to do so in order to let the user know the result of the processing.
- The jQuery function that sends the Ajax request receives a response from the server and performs actions such as updating content on the page or otherwise providing notification messages to the user.
Using Ajax with jQuery
Now, we will develop the "do_stuff" function from the previous code, and we will send the data using the $.post method, which has three parameters: the URL to send the POST request to, the data that needs to be sent, and the name of the callback function that will handle the data returned from the server side. Before we do this, there are a few things we need to take care of ahead of time. We'll define a variable as follows, which will make the following callback section easier to understand.
var this2 = this;
URL
All WordPress Ajax requests must be sent to wp-admin/admin-ajax.php, the correct and complete URL requires PHP to output a value, jQuery has no way of determining this value on its own, so we can't write this value to death in jQuery, and we don't want other people sending Ajax requests to your own site via plugins. If the page sending the Ajax request is a back-end page, WordPress has already set the correct ajaxurl for us via a JavaScript global variable, but if the page is coming from the front-end, we'll need to use the wp_localize_script() Setting the value of the ajaxurl global variable yourself is covered in more detail in the PHP section. For now, all we need to know is that the correct Ajax URL is a Javascript global variable that we can define and enter via PHP. This is how we use this variable in jQuery.
my_ajax_obj.ajax_url
digital
All of the data that needs to be sent to the server is contained in a JavaScript array, and in addition, we need to send an action parameter to help server-side PHP determine which Action mounted on which Ajax hook to use to process the data. For requests that may result in changes to the database, we also need to send a random number so that the server can verify that the request is coming from a legitimate source. An example of the data passed to the $.post() method is shown below.
{
_ajax_nonce: my_ajax_obj.nonce, //nonce
action: my_tag_count, //action
title: this.value //data
}
Let's take a look at those numbers below.
Nonce Random numbers
Nonce is an abbreviation for "Number used ONCE". It is essentially a unique hexadecimal sequence number that can be assigned to any kind of instance. Nonce is built using PHP and is passed to jQuery as a property of the global object in the same way as the Ajax URL, so the way we use Nonce in Ajax is my_ajax_obj.nonce.
Action
All WordPress Ajax requests must include an action parameter in the data, this value can be any string, it needs to be the same as the name of the hook used by the PHP backend to mount the Ajax handler, the name of the value is suggested to be a simple description of the purpose of the Ajax operation, here we use "my_tag_ count" as the value of the action.
action: my_tag_count
Other data
In addition to the above two special data, the server needs to complete the Ajax operation of other data is also included in this JavaScript array, if we need to transfer a lot of fields, you can use XML or JSON format to merge these fields into a single one, in WordPress, we use more is the JSON format.
In our example, the server only needs one value, a string for the name of the selection. we'll use "title" as the name of the value. in jQuery, the object that triggers the event is always contained in the variable this, so the value of the selected element is this.value. our declaration of this value is as follows is declared as follows.
title: this.value
pull back (of a key (in music)
A callback handler is a function that receives the server's response parameters and processes them after a request has been made. Callback functions are usually anonymous functions that receive a response value of yes or no or larger JSON or XML data. In our example, we use the data returned by the server to replace the text behind the radio button. Here is our callback function.
function(data) {
this2.nextSibling.remove();
$(this2).after(data);
}
data contains the returned data from the server. Above, we assigned this2 the object that triggers the change event, because this can only be used outside of an anonymous function, where this is invalid, so we're going to use this2 instead of this.
The server response can be any format of data, if the server response has a large amount of data, it is recommended to use the XML maybe JSON One of these two data formats.
XML
XML is the classic data exchange format when developing AJAX. After all, the "X" in AJAX refers to XML, but processing XML with PHP is a bit tricky, so many PHP programmers prefer JSON exchange format.
JSON
JSON is lightweight and easy to use, so it is popular among programmers. We can use eval()to parse JSON, but don't do that! Use the eval() willposes a significant security risk. It is recommended to use a dedicated JSON parser. When using a parser, it is important to first make sure that we have introduced this parser into the page. More information on introducing JavaScript libraries to the page is provided later in the Introduced in the PHP sectionThe
(sth. or sb) else
We can use this data format as long as it can be harmonized between JavaScript and PHP.
wrap-up
Now that we've added the anonymous callback function as the final parameter to the $.post method, we've completed the sample jQuery Ajax script, and all the parts put together look impactful like the following.
jQuery(document).ready(function($) { //wrapper
$(.pref).change(function() { //event
var this2 = this; //use in callback
$.post(my_ajax_obj.ajax_url, { //POST request
_ajax_nonce: my_ajax_obj.nonce, //nonce
action: my_tag_count, //action
title: this.value //data
}, function(data) { //callback
this2.nextSibling.remove(); //remove current title
$(this2).after(data); //insert server response
}); //insert server response.
}); //insert server response }); });
}).
The above script can be output to any part of the web page or placed in an external js file, we can place the js file anywhere as long as it can be accessed via a url, most plugin developers prefer to place the js file in the /js/ subdirectory of the plugin's home directory, unless you have a reason not to do so, it is a good choice to follow the convention, for the purposes of this example, we have named our In this case, we'll name our js file myjquery.js.
Server-side PHP and injection of front-end files
In order to handle Ajax requests on the server side, we need to do two things in PHP, one is to bring jQuery to the front end and add global JavaScript variables to the page that convert PHP variables to JS data. The other is to write the function that handles the Ajax request.
Injecting JavaScript Scripts
This section describes two features of Ajax in WordPress that can be confusing to seasoned developers, one is the injection of script in the form of meta links in the section of the page, and the other is that all Ajax requests are sent to wp-admin/admin-ajax.php, and that you should never send the request directly Never send requests directly to the plugin page.
pour into
In WordPress, we use wp_enqueue_script() function in the head of the page to insert a meta js link, do not write these links in the head of the dead, the development of plug-ins, we generally do not need to modify the theme of the head part, but still want to mention this rule.
The wp_enqueue_script() function takes 3 arguments, the first is the name of the JS to reference in other functions. The second is the URL of the JS, we can use the plugins_url() function to construct the correct URL, if we need to inject a JS outside of the plugin, make sure we have the correct URL. The third parameter is an array of names of other JSs that the JS depends on. Since we're using jQuery to send Ajax requests, please list at least 'jquery' in the array, even if there's only one dependency. An example is shown below:
wp_enqueue_script( 'ajax-script', plugins_url( '/js/myjquery.js', __FILE__ ), array('jquery') ).
When WordPress loads, we have to inject the scripts into the page from several Action hooks, which one to use depends on the page the scripts need to be injected into, for backend pages, use the admin_enqueue_scripts hook, for frontend pages, use the wp_enqueue_scripts, and for logon pages, use the login_ enqueue_scripts hook for login pages.
The admin_enqueue_scripts hook passes the filename of the current page to our callback, and we can use this information to inject our JS only where we need it. wp_enqueue_scripts hook doesn't pass any variables to our callback function, but we can use the template judgment function to make sure that we inject our JS only where we need it. Our JS, for example, looks like this.
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' ! = $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
);
}
Registration VS Injection
We may have seen in other tutorials wp_register_script()
which is a nice way to handle this, after registering, we also need to inject the scripts into the frontend using the wp_enqueue_scripts function. Why is this redundant? Because registering a script gives us a script name that we can inject elsewhere. jQuery, which is bundled with WordPress, is a pre-registered script in the WordPress kernel, so we can introduce it directly by using the name "jQuery", and the same is true for our own registered scripts. Of course, if we only need to introduce the script file in our own plugin, we can completely omit the step of registering the script.
Nonce Random numbers
We need to create a random number so that we can verify that the request sent by jQuery Ajax is not legitimate, only PHP and jQuery scripts can fetch this random number, after receiving the request we can verify that the random number is the same as the value we created, we created a random number using the following example.
$title_nonce = wp_create_nonce( 'title_example' );
The parameter title_example can be any string, it is recommended to follow the semanticization principle, by which you can see what this random number is used for.
Converting PHP variables to JavaScript global variables
Thinking back to the previous section on jQuery, the data created by PHP for use by jQuery is passed into a global object named my_ajax_obj. In our case, this data is a random number and the full URL of admin-ajax.php. The process of assigning object properties and creating a global JavaScript object, which we'll call localization, is illustrated in the following example of how we use the wp_localize_script() Sample code for localization code.
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce, // It is common practice to comma after
) );
Note how our code handles ajax-script, the object is global to our script, not to all scripts. Localization can also be called from the same hook in the injected script. The same goes for creating random numbers, although this particular function can be called from anywhere. The code to do all the processing in one hook is as follows:
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' ! = $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
).
$title_nonce = wp_create_nonce( 'title_example' );
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
) );
}
Ajax Action
The other major component of server-side PHP code is the program that handles Ajax submissions. This handler takes POST data, performs certain actions, and then returns the results to the browser. Which hook the function is mounted on determines whether the Ajax request handler asks the user to log in or not, and which program is used to handle the Ajax request depends on what value is passed to the action parameter of the jQuery script.
Because our Ajax interaction is used on the plugin's settings page, we must require the user to be logged in before we can send an Ajax request. Recall from the previous jQuery section that the value action for Ajax is "my_tag_action", then our back-end processing of the Ajax request's The hook tag for our backend to handle the Ajax request would be wp_ajax_my_tag_count. If our Ajax interaction could allow users who are not logged in, the hook tag would be wp_ajax_nopriv_my_tag_count, as shown in the following example.
add_action( 'wp_ajax_my_tag_count', 'my_ajax_handler' );
function my_ajax_handler() {
// Handle the ajax request
wp_die(); // All ajax handlers die when finished
}
The first thing our Ajax handler needs to do is use the check_ajax_referer()
The function verifies that the random number sent by the Ajax request is the value of the random number we created above.
check_ajax_referer( 'title_example' ).
The argument to the above function must be the same as the argument to wp_create_nonce, if the nonce does not match, the handler will automatically terminate, and if this is a true random number, the validation here will fail. We could create a new random number and send it to the callback script to use in the next request, but since the random number is valid for 24 hours, we don't need to do that, just perform a check.
digital
After the random number validation, the next step is to process the $_POST['title'] data sent by jQuery, which we can do using the update_user_meta() function is saved as the user's metadata.
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
Then, we create a query to get the number of articles labeled with the selected title.
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
Great, we can finally send the response back to the jQuery script, we have a couple of ways to transfer the data, let's take a look at the formats.
XML
PHP's support for the XML format is not good enough; fortunately, WordPress provides theWP_Ajax_Response
class to make our job a little easier.WP_Ajax_Response An XML formatted response will be generated, setting the correct content type for the header, outputting the XML, and then ending, ensuring a correct XML response.
JSON
This format is lightweight and easy to use, WordPress provides the wp_send_json function to help us convert the data to JSON, send it to the client and call it a day. This function effectively replaces WP_Ajax_response, and WordPress also provides the wp_send_json_success
respond in singing wp_send_json_error
function that allows us to trigger the appropriate done() and fail() callbacks in JS.
(sth. or sb) else
We can also return data in any other format as long as it can be processed by client-side jQuery, such as comma-separated data or a string of HTML.
echo $_POST['title'].' ('.$the_query->post_count.') ';
In a real application, we have to consider the possibility that the operation will fail for some reason. The server-side response should take this eventuality into account, and jQuery should be able to handle it correctly, prompting the user when needed.
close
When the handler has finished processing all the tasks, we need to end the program, if we send the response using the WP_Ajax_Response or wp_send_json functions, the program will be automatically result, if not, we need to use the wp_die() The function ends manually.
Ajax Handler Summary
A complete Ajax handler should look like the following.
//JSON
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tags' => $_POST['title'],
);
$the_query = new WP_Query( $args );
wp_send_json( $_POST['title'] . ' (' . $the_query->post_count . ') ' );
}
//Other
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tags' => $_POST['title'],
);
$the_query = new WP_Query( $args );
echo $_POST['title'].' ('.$the_query->post_count.') ';
wp_die(); // All ajax handlers should die when finished
}
Heartbeat API
The Heartbeat API is a server polling API built into WordPress that allows us to update the front-end in near real-time.
How the Heartbeat API works
When the page loads, the client-side heartbeat code sets a time interval (called a "tick") and runs every 15-60 seconds. At runtime, the heartbeat API collects data and sends it to the server via jQuery events, then waits for the server to respond. On the server side, the ajax-admin handler takes the value data passed by jQuery, processes it, and returns it in JSON format. When the client receives the data returned by the handler, it triggers a jQuery event to indicate that the data has been received.
The basic process of customizing heartbeat events is:
- Add extra fields to the data to be sent (JS)
heartbeat-send
(Event ) - Detect the sent field in PHP and add additional response fields (
heartbeat_received
filter hooks) - In JS (JS)
heartbeat-tick
) in processing the return data.
We can optionally use one or both of these events, depending on the functionality we need.
Using the Heartbeat API
Using the Heartbeat API requires two separate functions: sending and receiving callbacks in JavaScript, and server-side Filter hooks in PHP to handle the passed data.
Send data to the server
When the heartbeat sends data to the server, it can contain custom data in any format, or boolean values indicating that we need the data.
jQuery( document ).on( 'heartbeat-send', function ( event, data ) {
// Add additional data to the heartbeat data
data.myplugin_customfield = 'some_data'; }); }
});
Getting data on the server and returning a response
On the server side, we can get this data and add other data to the response.
// Add a Filter to the receive hook
add_filter( 'heartbeat_received', 'myplugin_receive_heartbeat', 10, 2 );
/**
* Get the heartbeat data and return the response
*
* @param array $response Heartbeat response data to pass back to front end.
* @param array $data Data received from the front end (unslashed).
*/
function myplugin_receive_heartbeat( $response, $data ) {
// If no data is received, return the original response directly
if ( empty( $data['myplugin_customfield'] ) ) {
return $response;
}
// Process the data and append it to the response
$received_data = $data['myplugin_customfield'];
$response['myplugin_customfield_hashed'] = sha1( $received_data );
return $response;
}
Processing server responses
Back on the front end, we can receive and process the response data returned from the server.
jQuery( document ).on( 'heartbeat-tick', function ( event, data ) {
// Check for our data, and use it.
if ( ! data.myplugin_customfield_hashed ) {
return; }
}
c-alert( 'The hash is ' + data.myplugin_customfield_hashed );
}).
Not every function requires all three steps, for example, if we don't need to send any data to the server, we can just use the last two steps.
summarize
Here's a summary of all the sample code snippets we discussed earlier, one for jQuery and one for PHP.
php
The following code should be located in one of the plugin's PHP files.
admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
));
}
add_action('wp_ajax_my_tag_count', 'my_ajax_handler');
function my_ajax_handler() {
check_ajax_referer('title_example');
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title']);
$args = array(
'tags' => $_POST['title'],
);
$the_query = new WP_Query( $args );
echo $_POST['title'].' ('.$the_query->post_count.') ';
wp_die(); // all ajax handlers should die when finished
}
jQuery
The following code is located in the file js/myjquery.js in the plugins folder.
jQuery(document).ready(function($) { //wrapper
$(.pref).change(function() { //event
var this2 = this; //use in callback
$.post(my_ajax_obj.ajax_url, { //POST request
_ajax_nonce: my_ajax_obj.nonce, //nonce
action: my_tag_count, //action
title: this.value //data
}, function(data) { //callback
this2.nextSibling.remove(); //remove the current title
$(this2).after(data); //insert server response
}); //insert server response.
}); //insert server response }); });
}); }).