This weekend I’m giving a talk at WordCamp Victoria about using AJAX in WordPress. The talk uses a couple of code snippets to demonstrate creating a simple plugin that passes some data from the client to the server and then updates the web page using data sent back from the server. Here’s the code for the final, most functional, plugin:
Firstly the PHP that runs on the server:
<?php /* Plugin Name: AJAX Demo 8 Description: A demonstration of how to use AJAX within WordPress Author: Jon Jennings Version: 1.0 Author URI: http://jonjennings.org/ */ class ajax_demo8 { public function __construct() { add_shortcode('ajax-demo8', array($this, 'shortcode_callback')); wp_enqueue_script( 'ajax-demo8', plugin_dir_url( __FILE__ ) . 'ajax-demo.js', array( 'jquery', 'json2' ) ); add_action('wp_ajax_ad_submit8', array($this, 'submit_callback')); add_action('wp_ajax_nopriv_ad_submit8', array($this, 'submit_callback')); add_action('wp_enqueue_scripts', array($this, 'enqueue')); } public function enqueue() { wp_localize_script( 'ajax-demo8', 'ajaxDemoData', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), '_nonce' => wp_create_nonce('ad-nonce') ) ); } public function shortcode_callback($atts) { $ret = '<div id="ajax-demo">'; $ret .= '<div id="ad-form">' . '<input type="button" name="send8" id="send8" value="click me" />' . '</div>'; $ret .= '<div id="ad-wait" style="display:none;">' . 'Please wait' . '</div>'; $ret .= '<div id="ad-output" style="display:none;">' . '</div>'; $ret .= '</div>'; return($ret); } public function submit_callback() { $filename = sanitize_file_name( $_POST['filename'] ); $nonce = $_POST['nonce']; // Warning - kinda dangerous $file = file_get_contents(plugins_url( $filename , __FILE__ )); $file_data = base64_encode($file); if (!wp_verify_nonce($nonce, 'ad-nonce')) { echo json_encode( array( 'result' => 'error' )); } else { echo json_encode( array( 'image' => $file_data ) ); } exit; } } $ajax_demo8 = new ajax_demo8(); ?>
And then the JavaScript that the client runs:
jQuery(document).ready(function ($) { $('#send8').click(function () { $("#ad-form").hide(); $("#ad-wait").show(); // url, data, success_callback // http://localhost/wordcamp/wp-admin/admin-ajax.php?action=ad_submit6&input=12312 $.post( ajaxDemoData.ajaxUrl, { action: 'ad_submit8', filename: 'taf.gif', nonce: ajaxDemoData._nonce }, ad_success ); }); function ad_success(a) { var data = JSON.parse(a); $('#ad-output').html('<img alt="Embedded Image" src="data:image/gif;base64,' + data.image + '" />'); $('#ad-wait').hide(); $('#ad-output').show(); } });
(You’ll need to supply your own GIF though!)
Edit: Note that if you actually just wanted to display the image in the browser, there’s no reason to load the image’s data into the server – all you’d need to do is to send the image’s URL to the client and have the client reference the URL rather than the data. The browser would then be responsible for loading the image from the web server without it ever being loaded into PHP there.
You should also note, as I mentioned in the presentation, that the code I showed live allows a client to request ANY, I repeat ANY, file off your server. So if the client asks for ‘../../../wp-config.php’ then it would give them a copy of your WordPress database details! This is not a good thing. The WordPress function sanitize_file_name() is your friend here – it’ll strip out any dodgy characters, including periods or slashes or asterisks, from a string. This means the client can no longer escape from your plugin’s directory. Just to be safe, I’ve updated the code here to use that. However the client could still request your plugin’s code, so if you needed to do something like this in a production environment you should also take measures to prevent that – eg set a naming strategy for the files you expect to be requested and check that it’s being followed.
Thirdly, Joey pointed out that embedding base64 encoded binary data in the browser is generally a bad thing. Base64 encoding is often used to hide malicious code (I should remember this point – I was hacked once with the code disguised in base64!) and so anything that uses it will be rejected by the WordPress repositories.
My purpose writing this part of the demo wasn’t to show best practices, it was more to show that you can use AJAX to transmit complex data to the client and not just a simple string or integer. That and a cute finish for my talk
Within the next couple of days, I’ll add a post explaining the content in more detail.

[...] Jon Jennings ( @jonjennings ) spoke on AJAX in a session titled "Making Your Plugins Sparkle with AJAX". As a backend developer I love the built-in support for creating AJAX endpoints. Jon gave a very good overview of what AJAX can do and provided some awesome real life examples. He then popped into a live code demo, which I always enjoy, and showed us how to use the AJAX resources available in WordPress. His slides are available at http://www.topdownview.com/2013/01/adding-ajax-to-your-wordpress-plugins/ [...]
[...] Making Your Plugins Sparkle with AJAX, by Jon Jennings [...]
[...] head and even in that one I learned something. Aside from our own session, I learned about plugins, AJAX, search, and, social media planning (I took away lots of stats from that session — no slides [...]
[...] Making Your Plugins Sparkle with AJAX, by Jon Jennings [...]