Using Ajax in your WordPress plugins

Ernest Marcinko Tutorials, Uncategorized, Wordpress 2 Comments

Tutorial level

beginner

WordPress provides a very convenient way to make ajax calls with action hooks and jQuery. There is a well known formal way of doing so, in this short article I will show you how.

Let’s create a simple plugin that retrieves a random post title & URL

Basic Plugin file

Let’s take a look at this code. It’s a basic plugin file with functions which I already added, without their bodies.

<?php
/*
Plugin Name: Get random post title plugin
Plugin URI: http://wp-dreams.com
Description: A simple tutorial plugin for demonstrating the usage of Ajax in WordPress.
Version: 1.0
Author: Ernest Marcinko
Author URI: http://wp-dreams.com
*/
?>
<?php

  define( 'GET_RPT_PATH', plugin_dir_path(__FILE__) );
  define( 'GET_RPT__DIR', 'related-posts-pro');
  define( 'GET_RPT_DEBUG', 0);

  $functions = new GetRPTWrapper();

  add_action( 'admin_menu', array($functions, 'navigation_menu') );
  register_activation_hook( __FILE__, array($functions, 'plugin_activate') );
  add_action('wp_print_styles', array($functions, 'styles'));
  add_action('wp_enqueue_scripts', array($functions, 'scripts'));
  add_action('wp_footer', array($functions, 'footer'));  

  /**
   *  A wrapper to wrap all the functions related with plugin activation,
   *  scripts, styles, administrator menu and site footer   
   */     
  class GetRPTWrapper {

    function plugin_activate() {
      //Things to do when activating the plugin            
    }

    function navigation_menu() {
      // The navigation menu
      if (current_user_can('manage_options'))  {

      }          
    }

    function styles() {
      //Register and enqueue styles here
    }

    function scripts() {
      //Register and enqueue scripts here
      wp_enqueue_script('jquery');
    } 

    function footer() {
      //Print some stuff into the footer if needed
    }  
  }

  /**
   * This is the part where the ajax handling is happening. The magic is, that
   * you can fire an ajax event with your javascript code. It is possible to 
   * define handlers for your events in your plugin php code. 
   * Usually simple functions are used to handle these events.
   * 
   * There are two separate event handlers:
   *  1. wp_ajax_YOUR-ACTION-NAME   -> for non-logged in users   
   *  2. wp_ajax_nopriv_YOUR-ACTION-NAME -> for logged in users          
   *
   */        

  add_action( 'wp_ajax_get_random_post_tu', 'get_random_post_tu' );
  add_action( 'wp_ajax_nopriv_get_random_post_tu', 'get_random_post_tu' );

  /**
   * So if the "get_random_post_title" action is defined in an ajax request, the
   * get_random_post_title() function will be called, because we told this to
   * WordPress in the upper two lines of code.      
   */     

  function get_random_post_tu() {
  	global $wpdb; // this is how you get access to the database

    /* The actual code goes here later */

  	die(); // this is required to return a proper result
  }
?>

Ok. This might seem a little too complicated for the first look, but it’s not. The actual code, that is interesting for us is lines 68-83. There we define two actions and a corresponding function to those two actions. When either of those actions are fired the function we defined will be called and the result is returned to the javascript handler. In other words:

  • We make an ajax call with the frontend javascript code
  • If the ajax parameters are correct, then the corresponding actions are fired by wordpress
  • If we hooked a handler function to those actions, then that function will be called and this function has access:
    • Every wordpress function and variable
    • All the request variables passed by the javascript code (_POST, _GET, _REQUEST)
  • This action handler does things/prints data and exits – this data is passed back to the javascript ajax handler

So basically at this point we have a classic ajax handler with some extra functions available. The picture below demonstrates a flow of an ajax call in WordPress.

ajax

Getting the random post & URL

At this point I guess you figured, that the “get_random_post_tu()” is going to do the work for us. All it is missing is everything. After some googling you may find some information about how to get a random post from the wordpress database. I will save you some time, here is the function:

function get_random_post_title() {
  // Simple as that, get a random post
  $posts = get_posts('orderby=rand&numberposts=1');
  /**
   * This actually gives us an array of post objects, so we should double check 
   * if there is indeed a post in there.
   */
  if (is_array($posts) && isset($posts[0])) {
      $data = array();
      $data['link'] = get_permalink($posts[0]->ID);
      $data['title'] = get_the_title($posts[0]->ID);
      /**
       *  Making a structure like this will make your work in the javascript
       *  a lot easier when you want to get the title and link from the respons
       *  data.
       *  The JSON format is always good for passing structured data (like objects
       *  or arrays) to a javascript function.                     
       */             
      print_r(json_encode($data));
  } else {
      // If there is nothing in there, print a 0
      print 0;
  }    
	die(); // this is required to return a proper result
}

This function will return a JSON encoded array of a post, including it’s title and url.

Creating the Layout

Ok, now we have the server side functionality, but nothing else. We need a basic layout and to inject this layout somewhere. The best way to do this is by creating a shortcode. A shortcode can be inserted anywhere into a post/page/widgetized area or template part.

For a shortcode we need a function and one extra line of PHP code to tell WordPress to register our shortcode with our function:

add_shortcode( 'get_random_post_tu', 'get_random_post_tu_shortcode' ); 

function get_random_post_tu_shortcode( $atts ){
   ob_start();
	 ?>
     <div class='grp_container'>
         <button class='grp_getnew'>Give me a random post!</button>
         <span class='grp_content'></span>
     </div>
   <?php
   $out = ob_get_clean();
   return $out;
}

So, in this case we register the “get_random_post_tu” shortcode and associate it with the get_random_post_shortcode function, so this function is called when the shortcode is parsed on the page. As you can see the HTML code is only a simple container with a button and a span element.

Javascript

So far we have a layout and a server side script, but there is no connection between these two. This is where Javascript enters the scene. By adding attaching an event listener function to the button click event, we can initiate an ajax call to our desired server side script – to return us a JSON object with a random post title and url. The good thing is, that jQuery offers a nice way to do this, the handling of the response is very easy:

jQuery(document).ready(function($) {
  $('.grp_getnew').on('click', function(){
  	var data = {
  		action: 'get_random_post_tu'
  	};

  	$.post(ajax_object.ajax_url, data, function(response) {
  	  if (response!=0) {
            var $link = $("<a href='" + response.link + "'>" + response.title + "</a>");
            $('.grp_content').html($link);
          }
  	}, "json");
  });
});

There is not much to tell about this function. The second line defines the click handler for the button, the data object’s action property holds the action name. This is very important – it must be defined, otherwise the ajax result will always be 0.

I have used a simple POST method, but we could have used a GET as well. It wouldn’t make any difference in this case, because none of these variables were used in the php handler function.

The result

Just add the “[get_random_post_tu]” shortcode to a post/page widget and enjoy!

ajax2After clicking  the “GIVE ME A RANDOM POST!” button you should see a link appear under (or next) to it after 1-2 seconds.

That’s it! You have done it!

Grab the plugin!

Download

Comments 2

  1. Kirrus

    Please be aware, using AJAX is awesome for some things, but effectively is un-cacheable under normal circumstances. Using it on busy websites is dangerous.

    1. Ernest Marcinko Post
      Author

Leave a Reply

Your email address will not be published.