We cover a lot of topics on this blog - anything ranging from something as simple as how to include and require template files in WordPress projects to something such as an entire series on the Settings API, but I think there's always room to cover a straightforward How-To that covers a single, specific task within the context of WordPress.
So, in this two-part series, we're going to take a look at how to introduce a jQuery date picker into our post editor so that we can associate a date with a given post.
About the Plugin
We'll be doing all of this within the context of a plugin so that the source code will be easily downloadable via GitHub and will provide a working example of the tutorial.
The first thing to note is that incorporating the jQuery date picker is not meant to replace the publish date of the post. Instead, it's meant to provide an easy way to select a date, save it in the post meta data, and then display it for another purpose such as, say, when an event is going to occur.
Planning the Plugin
For anyone that's read any of my previous posts, you know that I'm a fan of planning the project from the outset, then implementing each step at a time to make sure we're clear on everything that's happening.
So let's do that now:
- We'll provide the skeleton class for the plugin
- We'll write the code responsible for generating the post meta box that allows the user to select the date
- We'll implement the jQuery date picker so users can actually select a date
- We'll save the data when the post is published and/or updated
- We'll display the date on the front end of the post
Straightforward, right? With that said, let's get started.
Building the Plugin
At the end of this article, the entire plugin will be available in this GitHub repository, but I highly recommend following along and writing the code yourself to make sure you follow everything that we're doing.
The code will be commented so it should be easy to follow. If not, always feel free to leave comments after the post.
1. Stub Out the Plugin Class
Assuming that you've already created the WordPress-jQuery-Date-Picker directory in your wp-content/plugins directory, go ahead and create two files:
- plugin.php
- README.txt
We'll revisit the README file in a bit, but let's go ahead and stub out the class that serves as our plugin.
Here's the code with more explanations after the snippet:
<?php /* Plugin Name: WordPress jQuery Date Picker Plugin URI: https://github.com/tommcfarlin/WordPress-jQuery-Date-Picker/ Description: A sample plugin used to demonstrate how to include the jQuery Date Picker into the post editor. Version: 1.0 Author: Tom McFarlin Author URI: http://tommcfarlin.com/ Author Email: [email protected] License: Copyright 2013 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 WordPress_jQuery_Date_Picker { /*--------------------------------------------* * Constructor *--------------------------------------------*/ function __construct() { } // end __construct /*---------------------------------------------* * Localization, JavaScripts, Stylesheets, etc. *---------------------------------------------*/ /*---------------------------------------------* * Core Functions *---------------------------------------------*/ /*---------------------------------------------* * Helper Functions *---------------------------------------------*/ } // end class new WordPress_jQuery_Date_Picker();
Obviously, there's not much to it, yet. We've simply defined the class, set an empty constructor, and instantiated the plugin outside the class.
Before we move any further, let's go ahead and prepare the plugin for localization. To do this, we need to do several things:
- Introduce a lang directory
- Add lang/plugin.po
- Set the text domain for the plugin within the constructor
Remember that localization is used to be sure that translators can make our plugin compatible with other languages, and that Poedit is the tool of choice.
The plugin.po file should contain something like the following (yours will obviously be different based on the date, the time, and the configuration of Poedit):
msgid "" msgstr "" "Project-Id-Version: WordPress jQuery Date Picker 1.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-02-07 13:36-0500\n" "PO-Revision-Date: 2013-02-07 13:36-0500\n" "Last-Translator: Tom McFarlin <[email protected]>\n" "Language-Team: Tom McFarlin <[email protected]>\n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-KeywordsList: __;_e\n" "X-Poedit-Basepath: .\n" "X-Generator: Poedit 1.5.5\n" "X-Poedit-SearchPath-0: ..\n"
Next, we need to set the text domain in the constructor. First, include the following line in your constructor:
// Load plugin text domain add_action( 'init', array( $this, 'plugin_textdomain' ) );
Next, add the following function to your file:
/** * Loads the plugin text domain for translation * * @version 1.0 * @since 1.0 */ public function plugin_textdomain() { load_plugin_textdomain( 'wp-jquery-date-picker', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); } // end plugin_textdomain
The most significant thing to note here is the use of the wp-jquery-date-picker
key as this is what we'll be using to localize the strings throughout the remainder of the plugin.
Finally, we'll revisit this along with the README file later in the tutorial.
2. Create the Meta Box
At this point, we're ready to define the code that will render the meta box. This consists of several steps:
- Defining the hook in the constructor
- Register the meta box with WordPress
- Defining a function used to render the actual meta box
In the constructor, add the following line of code. This is what we'll be using to register our post meta box:
add_action( 'add_meta_boxes', array( $this, 'add_date_meta_box' ) );
In the function above, we're telling WordPress to look for our date meta box in a function called add_date_meta_box
, so we need to define that now.
Within your class, add the following code:
/** * Registers the meta box for displaying the 'Date' option in the post editor. * * @version 1.0 * @since 1.0 */ public function add_date_meta_box() { add_meta_box( 'the_date', __( 'The Date', 'wp-jquery-date-picker' ), array( $this, 'the_date_display' ), 'post', 'side', 'low' ); } // end add_date_meta_box
We've covered meta boxes in depth in various tutorials and the WordPress Codex has a terrific article explaining what each parameter does, so I don't want to belabor the point here.
That said, there's one specific thing that we need to notice in the call above. Note that the meta box is looking to register its display using a function called the_date_display
.
As such, we need to define this function. Luckily, the meta box can be very simple: In order to trigger the date picker, we only need a single element. Since we're going to be rendering the date, let's opt to use a simple input box.
Next, add the following function to your class:
/** * Renders the user interface for completing the project in its associated meta box. * * @version 1.0 * @since 1.0 */ public function the_date_display( $post ) { wp_nonce_field( plugin_basename( __FILE__ ), 'wp-jquery-date-picker-nonce' ); echo '<input id="datepicker" type="text" name="the_date" value="' . get_post_meta( $post->ID, 'the_date', true ) . '" />'; } // end the_date_display
Easy to understand, right?
We define a nonce value for security purposes giving us the security features we need to make sure that the user has permissions to save values for this field, and then we render an input element to the screen.
Note that the input
element includes an ID of "datepicker" and a name of "the date." This will be imported later, but for now save your work.
If you activate the plugin right now, you should see something like the following:
Obviously, this needs some light styling to make it look just a little bit better. So, let's do the following:
- Create a css directory
- Add a css/admin.css file
In the file, include the following code:
#datepicker { width: 100%; }
Then, in the constructor, add this line:
add_action( 'admin_print_styles', array( $this, 'register_admin_styles' ) );
After that, add this function to your plugin:
/** * Registers and enqueues admin-specific styles. * * @version 1.0 * @since 1.0 */ public function register_admin_styles() { wp_enqueue_style( 'wp-jquery-date-picker', plugins_url( 'WordPress-jQuery-Date-Picker/css/admin.css' ) ); } // end register_admin_styles
At this point, the width of the input box for the date picker should span the width of the meta box's container. Makes it look just a little bit nicer, in my opinion.
3. Save the Date
Before we actually begin implementing the date picker, let's go ahead and make sure that our new post meta box can properly save information. Right now, it's not possible because we haven't written the code for it.
This particular step will entail the following:
- Defining a function for saving the data
- Making sure that the user has the ability to save the data
- Actually saving the data
First, we need to define the hook for saving the data. To this, add the following line to your constructor directly under the line where we defined the hook for creating the meta box:
add_action( 'save_post', array( $this, 'save_project_date' ) ); [php] Next, we need to actually define the <code>save_project_date</code> function. This function is going to be responsible for making sure that the user has permission to save the data and then will actually save the contents of the input field in the post meta for the associated post. So, add the following function to your plugin: [php] /** * Saves the project completion data for the incoming post ID. * * @param int The current Post ID. * @version 1.0 * @since 1.0 */ public function save_the_date( $post_id ) { // If the user has permission to save the meta data... if( $this->user_can_save( $post_id, 'wp-jquery-date-picker-nonce' ) ) { // Delete any existing meta data for the owner if( get_post_meta( $post_id, 'the_date' ) ) { delete_post_meta( $post_id, 'the_date' ); } // end if update_post_meta( $post_id, 'the_date', strip_tags( $_POST[ 'the_date' ] ) ); } // end if } // end save_the_date
This function works by basically checking to see if this user can save. If so, then it will delete any existing post meta so as not to clutter the database, then add the date specified to this post.
But there's a catch: We're making a call to a function called user_can_save
. This particular function is a helper function that we need to define as it simplifies a lot of the boilerplate code necessary for making sure the user has permission to save the file.
So in the "Helper Functions" area of your class, add the following function:
/** * Determines whether or not the current user has the ability to save meta data associated with this post. * * @param int $post_id The ID of the post being save * @param bool Whether or not the user has the ability to save this post. * @version 1.0 * @since 1.0 */ private function user_can_save( $post_id, $nonce ) { $is_autosave = wp_is_post_autosave( $post_id ); $is_revision = wp_is_post_revision( $post_id ); $is_valid_nonce = ( isset( $_POST[ $nonce ] ) && wp_verify_nonce( $_POST[ $nonce ], plugin_basename( __FILE__ ) ) ) ? true : false; // Return true if the user is able to save; otherwise, false. return ! ( $is_autosave || $is_revision) && $is_valid_nonce; } // end user_can_save
Notice that this function takes in the current Post ID and the nonce value (which we set earlier in this post). Finally, this function returns true if this is not an autosave, a post revision, and that the nonce is valid.
If it's true, then the user has permission to save.
Conclusion
At this point, let's try out what we have. Activate the plugin, and you should see the meta box on the Post Editor dashboard. Right now, you should be able to save any value that you'd like in that particular field.
You can grab a copy of the plugin in its current version for this post using this link.
In the next article, we're going to take a look at actually implementing the date picker. This will include importing the necessary JavaScript dependencies, writing a little bit of our own JavaScript, and then rendering the date on the front end of the post.
Finally, we'll prepare the plugin for release by generating the localization files and then preparing the README.
Comments