9
22/02/13 A Pr i mer on Aj ax i n the WordPress Frontend: Actual l y Doi ng It | Wptuts+ wp.tutsplus.com/tutori al s/plugi ns/a- primer-on-aj ax-in-the- w ordpr ess- frontend-actually-doing-it/ 1/9 Advertise Here A Primer on Ajax in the WordPress Frontend: Actually Doing It Tom McFarlin on Oct 11th 2012 with 6 Comments and 0 Reactions Tutorial Details Topics: Plugins, Ajax, User Meta Difficulty: Intermediate Estimated Completion Time: 3 hours This entry is part 2 of 2 in t he series A Primer on Ajax in the WordPress Frontend A Primer on Ajax in the WordPress Frontend A Primer on Ajax in the WordPress Frontend: Understanding the Process A Primer on Ajax in the WordPress Frontend: Actually Doing It In this series, we’re discussing how to implement Ajax in the WordPress frontend. In the first post in the series, we reviewed how Ajax works at a high-level, reviewed how to introduce Ajax into the Dashboard of WordPress, and reviewed the two hooks available for incorporating Ajax into WordPress. At this point, it’s time to actually build something that will demonstrate how we can use Ajax in the WordPress frontend. To do this, we’ll be writing our own plugin making sure that we’re following WordPress best practices along the way. By the end of this article, we’ll have a fully working plugin with so urce code publicly available on GitHub. With that said, let’s get started. Planning It Out If you’ve read any of my previous articles, then you know that I always like to begin my projects with planning out what we’re going to do. This project is no different. In this example, we’re going to be introducing a checkbox that allows readers who are logged into a WordPress site to check off blog posts that they’ve read. This way, they’ll only see posts that they’ve yet to read since logging into the site. To build this, we’ll be using a couple of things: A fresh install of WordPress Th e WordP ress Theme Unit Test to provide us with plenty of example content The Twenty Eleven theme (since it’s so widely available) A user account who has the ‘Subscriber’ role Once you have the environment setup, here’s the plan of action that we’ll be following for our plugin: We’ll create a new plugin in the plugins directory called I’ve Read This (in the directory ive-read-this) On each post, we’ll introduce a checkbox and a label that allows users to mark that they’ve read this post Once the post has been marked as read, the option will disappear from view Got it? Go ahead and login as the user that you created with the ‘Subscriber’ role and let’s get started! Building I’ve Rea d This Once you’ve got the test data imported, your setup should look something like this:

A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

Embed Size (px)

Citation preview

Page 1: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 1/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 1/9

Advertise Here

A Primer on Ajax in the WordPress Frontend:

Actually Doing ItTom McFarlin on Oct 11th 2012 with 6 Comments and 0 Reactions

Tutorial Details

Topics: Plugins, Ajax, User Meta

Difficulty: Intermediate

Estimated Completion Time: 3 hours

This entry is part 2 of 2 in the series A Primer on Ajax in the WordPress Frontend

A Primer on Ajax in the WordPress Frontend

A Primer on Ajax in the WordPress Frontend: Understanding the Process

A Primer on Ajax in the WordPress Frontend: Actually Doing It

In this series, we’re discussing how to implement Ajax in the WordPress frontend. In the first post in the series, we reviewed how Ajax works at a high-level, reviewed how to

introduce Ajax into the Dashboard of WordPress, and reviewed the two hooks available for incorporating Ajax into WordPress.

At this point, it’s time to actually build something that will demonstrate how we can use Ajax in the WordPress frontend. To do this, we’ll be writing our own plugin making sure

that we’re following WordPress best practices along the way.

By the end of this article, we’ll have a fully working plugin with source code publicly available on GitHub. With that said, let’s get started.

Planning It Out

If you’ve read any of my previous articles, then you know that I always like to begin my projects with planning out what we’re going to do. This project is no different.

In this example, we’re going to be introducing a checkbox that allows readers who are logged into a WordPress site to check off blog posts that they’ve read. This way, they’ll

only see posts that they’ve yet to read since logging into the site.

To build this, we’ll be using a couple of things:

A fresh install of WordPress

The WordPress Theme Unit Test to provide us with plenty of example content

The Twenty Eleven theme (since it’s so widely available)

A user account who has the ‘Subscriber’ role

Once you have the environment setup, here’s the plan of action that we’ll be following for our plugin:

We’ll create a new plugin in the plugins directory called I’ve Read This (in the directory ive-read-this)

On each post, we’ll introduce a checkbox and a label that allows users to mark that they’ve read this post

Once the post has been marked as read, the option will disappear from view

Got it? Go ahead and login as the user that you created with the ‘Subscriber’ role and let’s get started!

Building I’ve Read This

Once you’ve got the test data imported, your setup should look something like this:

Page 2: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 2/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 2/9

From here, we’re ready to get started writing the plugin.

Stubbing Out the PluginBefore we actually write any code, I like to go ahead and stub out the plugin files. This means that we’ll setup the directory, the basic plugin structure, and any directories that we

may need to use for plugin dependencies.

Since we’ll be providing some light styling as well as JavaScript files for initiating the Ajax request, here’s what the basic directory structure should look like. The lang directory is

optional, though I consider it a best practice:

Page 3: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 3/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 3/9

 Now, let’s stub out the text required for the plugin.php. Note that this will be nothing but a skeleton. It will be primarily responsible for laying the foundation for what we’ll be

 building later in the article:

123456789

1011121314

1516171819202122232425262728293031

323334353637383940414243444546474849

5051525354555657

<?php/*Plugin Name: I've Read ThisPlugin URI: http://github.com/tommcfarlin/ive-read-this/Description: A simple plugin for allowing site members to mark when they've read a post.Version: 1.0Author: Tom McFarlinAuthor URI: http://tommcfarlin.com/Author Email: [email protected]

Copyright 2012 Tom McFarlin ([email protected]

This program is free software; you can redistribute it and/or modify

  it under the terms of the GNU General Public License, version 2, as  published by the Free Software Foundation. 

This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  GNU General Public License for more details. 

You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class IveReadThis { 

/*--------------------------------------------*

  * Constructor  *--------------------------------------------*/ 

/**  * Initializes the plugin by setting localization, filters, and administration functions.  */  function __construct() { 

load_plugin_textdomain( 'ive-read-this', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); 

// Register site styles and scriptsadd_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_styles' ) );add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_scripts' ) );

 } // end constructor

 /**

  * Registers and enqueues plugin-specific styles.

  */  public function register_plugin_styles() { 

wp_register_style( 'ive-read-this', plugins_url( 'ive-read-this/css/plugin.css' ) );wp_enqueue_style( 'ive-read-this' );

 } // end register_plugin_styles

 

Page 4: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 4/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 4/9

At this point, you can actually activate the plugin in the WordPress plugin dashboard, though nothing will actually happen. If you’re up for it, go ahead and do that now – you’ll

 be able to watch the plugin come to life as we work on it.

Introduce a Checkbox on Each Post

Since we’re going to be introducing a checkbox on each post that allows users to toggle whether or not they’ve read the post, we’ll need to account for the following:

We need to make sure that the checkbox is only displayed when the user is logged in

The checkbox should be at the bottom of the post on the single post page since that’s where user’s will mark that they’ve read the post

We can achieve both of these by adding the following function:

Read the comments carefully as they should explain exactly what’s going on; however, if you’re unclear, don’t hesitate to leave a comment.

 Next, we need to add the following line in the constructor so thatthe_content filter is called:

Finally, let’s add a little bit of style just to give the checkbox a slightly unique look and feel within the context of the Twenty Eleven theme. In the plugin’s plugin.css file, add the

following code:

 Now, if you log into the WordPress installation and navigate to the bottom of a single post, you should see something like the following image:

5859606162636465666768697071

  /**  * Registers and enqueues plugin-specific scripts.  */  public function register_plugin_scripts() { 

wp_register_script( 'ive-read-this', plugins_url( 'ive-read-this/js/plugin.js' ), array( 'jquery' ) );wp_enqueue_script( 'ive-read-this' );

 } // end register_plugin_scripts

 } // end class new IveReadThis();?>

123456789

1011121314151617

1819202122232425262728

/** * Adds a checkbox to the end of a post in single view that allows users who are logged in * to mark their post as read. * * @param $content The post content * @return The post content with or without the added checkbox */public function add_checkbox( $content ) { 

// We only want to modify the content if the user is logged in  if( is_user_logged_in() && is_single() ) { 

// Build the element that will be used to mark this post as read  $html = '<div id="ive-read-this-container">';  $html .= '<label for="ive-read-this">';  $html .= '<input type="checkbox" name="ive-read-this" id="ive-read-this" value="0" />';  $html .= __( "I've read this post.", 'ive-read-this' );

  $html .= '</label>';  $html .= '</div><!-- /#ive-read-this-container -->'; 

// Append it to the content  $content .= $html; 

} // end if 

return $content; } // end add_checkbox

12

// Setup the action for rendering the checkboxadd_filter( 'the_content', array( &$this, 'add_checkbox' ) );

123456

#ive-read-this-container {  margin: 1em 0 1em;  background: #eee;  border: 1px solid #ccc;  padding: 0.25em;}

Related Searches: Free WordPres s Video Tutorials | Blogging Platform | WordPress Plugin | Hosted WordPress |Search

Page 5: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 5/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 5/9

At this point, we’re ready to begin writing some JavaScript.

Making a Request: Setup the Click Handler for the Checkbox

The first thing that we need to do is to setup the JavaScript so that it only fires if the “I’ve Read This” container is on the page. There are a variety of ways to do this, but since

we’re loading the JavaScript on every page, then we’ll use JavaScript to check for the presence of the “I’ve Read This” check box that we’re writing out to the page.

To do this, add the following code to plugin.js. The code comments should be self-explanatory. If not, leave a comment!

In the code that you see above, anything that we place within the conditional will only fire if the “I’ve Read This” container element is present.

In this case, we know that we need to send the ID of the post to the server. Since the user is logged in, we’ll be able to get his/her ID on the server side.

So, the next step is to get the ID of the post that we’re on. Luckily, Twenty Eleven stores the number of the post in the article element’s ID. We just need to parse it out.

Let’s do that now:

123456789

(function ($) {$(function () {

 // If the "I've Read This Container" is on this page, let's setup the event handler

  if(1 === $('#ive-read-this-container').length) {} // end if

 });

}(jQuery));

1 // We use the change attribute so that the event handler fires

Page 6: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 6/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 6/9

At this point, we’re ready to setup an Ajax request. We’ll be using jQuery’s $.post method for doing this and we’ll be using WordPress’ standard ajaxurl to handle our response.

Handling the Event: Mark the Post as Read

Let’s go ahead and write the code that will send the ID of the post across. We’ll worry about the response later in this article, hence the “TODO” comment in the code.

At this point in development, the full JavaScript source should look like this:

For those of you who have been working through the example code as you’ve read the article, you’ll immediately notice that your browser throws a console error:

Uncaught ReferenceError: ajaxurl is not defined

Oops! And this is where we need to make sure to properly include WordPress’ Ajax library.

Including WordPress’ Ajax Library on the Frontend

To do this, we’ll need to hook into the wp_head action. Add the following line of code in the constructor of your plugin:

 Next, add the following function. This is what’s actually responsible for including the Ajax library:

23456789

10111213

// whenever the checkbox or its associated label are clicked.$('input[name="ive-read-this"]').change(function (evt) { 

// We can retrieve the ID of this post from the <article>'s ID. This will be required  // so that we can mark that the user has read this particular post and we can hide it.  var sArticleId, iPostId; 

// Get the article ID and split it - the second index is always the post ID in Twenty ElevensArticleId = $("article").attr('id');

  iPostId = parseInt(sArticleId.split('-')[1]); });

12345678

// Initial the request to mark this this particular post as read$.post(ajaxurl, { 

post_id: iPostId }, function (response) {  // TODO});

123456789

101112131415

1617181920212223242526272829303132

33

(function ($) {$(function () {

 // If the "I've Read This Container" is on this page, let's setup the event handler

  if(1 === $('#ive-read-this-container').length) { 

// We use the change attribute so that the event handler fires  // whenever the checkbox or its associated label are clicked.

$('input[name="ive-read-this"]').change(function (evt) { 

// We can retrieve the ID of this post from the <article>'s ID. This will be required  // so that we can mark that the user has read this particular post and we can hide it.  var sArticleId, iPostId; 

// Get the article ID and split it - the second index is always the post ID in Twenty Eleven

sArticleId = $("article").attr('id');  iPostId = parseInt(sArticleId.split('-')[1]); 

// Initialise the request to mark this particular post as read$.post(ajaxurl, {

 post_id: iPostId

 }, function (response) {

  // TODO});

 });

 } // end if

 });

}(jQuery));

12

// Include the Ajax library on the front endadd_action( 'wp_head', array( &$this, 'add_ajax_library' ) );

123456

/** * Adds the WordPress Ajax Library to the frontend. */public function add_ajax_library() { 

$html = '<script type="text/javascript">';

Page 7: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 7/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 7/9

 Now, if you try to execute the code, you should have no problem. At this point, we’re ready to keep going.

Handle the Event: Mark the Post as Read

 Now that we’ve got the request being sent to the server, we can write our server-side event handler. This is how the handler should operate:

Check that the incoming Post ID value is set and that it’s a numeric value (this is very rudimentary spoof protection, but it works for all intents and purposes).

 Next, try to update the current user’s meta using his/her ID and the post ID.

If the update fails, we’ll return -1; otherwise, we’ll return 1. We’ll handle these values in the response handler in the JavaScript.

First, we’ll add the hook in the constructor of the plugin:

 Next, we’ll actually implement the handler:

To that end, let’s revisit the outstanding TODO in the response function of the JavaScript that we were working on. Here’s the full script:

789

101112

  $html .= 'var ajaxurl = "' . admin_url( 'admin-ajax.php' ) . '"';  $html .= '</script>'; 

echo $html; } // end add_ajax_library

12

// Setup the event handler for marking this post as read for the current useradd_action( 'wp_ajax_mark_as_read', array( &amp;$this, 'mark_as_read' ) );

1234

56789

1011121314151617181920

/** * Uses the current user ID and the incoming post ID to mark this post as read * for the current user. *

 * We store this post's ID in the associated user's meta so that we can hide it * from displaying in the list later. */public function mark_as_read() { 

// First, we need to make sure the post ID parameter has been set and that it's a numeric value  if( isset( $_POST['post_id'] ) && is_numeric( $_POST['post_id'] ) ) { 

// If we fail to update the user meta, respond with -1; otherwise, respond with 1.  echo false == update_user_meta( wp_get_current_user()->ID, $_POST['post_id'], 'ive_read_this' ) ? "-1" 

} // end if 

die(); } // end mark_as_read

123456789

101112131415

1617181920212223242526272829303132

3334353637383940

(function ($) {$(function () {

 // If the "I've Read This Container" is on this page, let's setup the event handler

  if(1 === $('#ive-read-this-container').length) { 

// We use the change attribute so that the event handler fires  // whenever the checkbox or its associated label are clicked.

$('input[name="ive-read-this"]').change(function (evt) { 

// We can retrieve the ID of this post from the <article>'s ID. This will be required  // so that we can mark that the user has read this particular post and we can hide it.  var sArticleId, iPostId; 

// Get the article ID and split it - the second index is always the post ID in Twenty Eleven

sArticleId = $("article").attr('id');  iPostId = parseInt(sArticleId.split('-')[1]); 

// Initial the request to mark this this particular post as read  $.post(ajaxurl, { 

action: 'mark_as_read',  post_id: iPostId 

}, function (response) { 

// If the server returns '1', then we can mark this post as read, so we'll hide the checkbo  // container. Next time the user browses the index, this post won't appear  if (1 === parseInt(response)) { 

$('#ive-read-this-container').slideUp('fast'); 

// Otherwise, let's alert the user that there was a problem. In a larger environment, we'd  // want to handle this more gracefully.} else {

 alert("There was an error marking this post as read. Please try again.");

 } // end if/else

 

Page 8: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 8/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp.tutsplus.com/tutorials/plugins/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it/ 8/9

One More Change

If the user happens to find their way to an individual post page (such as being linked to it), we should check to see if they’ve previously marked it to be read.

To do this, we need to refactor the add_checkbox function so that it checks to see if the user is logged in and it reads the user meta to determine if the post has been previously

marked as read:

See It in Action!

At this point, you’ve got a working plugin:

You should be able to navigate to any post

If you’ve not read it, then you should be able to click on the checkbox and have it disappear 

If you reload the page, then you’ll see the notification that the post has been marked as read.

 Not bad, right?

Of course, there’s always room to experiment on your own with this. For example, you could work on excluding these posts from the main loop if they’ve been marked asread. Another option would be to add a custom classname and then styling the post to indicate that the current user has read it.

Finally, remember that you can grab all of the source code in its entirety on GitHub.

4142434445464748

}); 

}); 

} // end if 

});}(jQuery));

123456789

1011

121314151617181920212223242526272829

3031323334353637383940414243444546

4748

/** * Adds a checkbox to the end of a post in single view that allows users who are logged in * to mark their post as read. * * @param $content The post content * @return The post content with or without the added checkbox */public function add_checkbox( $content ) { 

// We only want to modify the content if the user is logged in  if( is_single() ) {

  // If the user is logged in...  if( is_user_logged_in() ) { 

// And if they've previously read this post...  if( 'ive_read_this' == get_user_meta( wp_get_current_user()->ID, get_the_ID(), true ) ) { 

// Build the element to indicate this post has been read  $html = '<div id="ive-read-this-container">';  $html .= '<strong>';  $html .= __( "I've read this post.", 'ive-read-this' );  $html .= '</strong>';  $html .= '</div><!-- /#ive-read-this-container -->'; 

// Otherwise, give them the option to mark this post as read} else {

 // Build the element that will be used to mark this post as read

  $html = '<div id="ive-read-this-container">';  $html .= '<label for="ive-read-this">';  $html .= '<input type="checkbox" name="ive-read-this" id="ive-read-this" value="0" />';  $html .= __( "I've read this post.", 'ive-read-this' );  $html .= '</label>';  $html .= '</div><!-- /#ive-read-this-container -->'; 

} // end if 

// Append it to the content  $content .= $html; 

} // end if 

} // end if 

return $content;

 } // end add_checkbox

Page 9: A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

7/29/2019 A Primer on Ajax in the WordPress Frontend_ Actually Doing It _ Wptuts+

http://slidepdf.com/reader/full/a-primer-on-ajax-in-the-wordpress-frontend-actually-doing-it-wptuts 9/9

22/02/13 A Primer on Ajax in the WordPress Frontend: Actually Doing It | Wptuts+

wp tutsplus com/tutorials/plugins/a primer on ajax in the wordpress frontend actually doing it/ 9/9

Related Reading

Filter Reference

Action Reference

Ajax in Plugins

Update User Meta

Other parts in this series:

A Primer on Ajax in the WordPress Frontend: Understanding the Process

Tags: ajaxfront endplugin development

By Tom McFarlinTom is a self-employed developer who loves writing, building, and sharing WordPress-based projects. He's the lead developer at 8BIT and technical editor of WP Daily. You

can follow him on Twitter .

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more

Like 13 people like this. Be the f irst of your f riends.