At the end of this tutorial you will know how to code:

  • Functional WordPress widget.
  • Functional WordPress plugin.
  • Display some content on the home page through a widget.
  • Make Ajax calls from the home page.
  • Use jQuery with WordPress.
  • Create your own custom database tables with a plugin.

I assume you have a functional WordPress site running, with you having access to the plugin folder. All the code below was tested on a site running WordPress mu, but it should work with a single user WordPress. If you find any discrepancies please let me know.

We will be building a WordPress widget/plugin which will display an empty text box in the home page were users can input some text. Once the input text is submitted, it will be stored in our custom table.

Time to get our hands dirty. Let us first start with the plugin part. First step towards writing a plugin, is to enable WordPress to display the plugin in it’s plugin configuration page, so that the admin can activate the plugin. Create a folder called my-plugin inside the WordPress plugin folder. Inside my-plugin create a file called my-plugin.php and add the following to the header.

Plugin Name: My Plugin
Plugin URI: {URI where you plan to host your plugin file}
Description: A plugin built as part of WordPress plugin tutorial.
Version: 1
Author: {Your name}
Author URI: {Your home page}

Now go to WordPress plugin configuration page and you should see “My Plugin” displayed as one of the plugins along with all other plugins that you have.

Now let us spice it up. This plugin once activated will create a custom table in WordPress DB to store the user text. Create a function that has to be run when an user activates the plugin.

Add the below to my-plugin.php

register_activation_hook( __FILE__, 'my_plugin_install' );

my_plugin_install() {

Above, we have created a function called my_plugin_install which we have registered with WordPress. Now when an user activates “My Plugin”, my_plugin_install function will be run.

Now, let us add some code to create our table.

global $my_plugin_table;
global $my_plugin_db_version;
global $wpdb;
$my_plugin_table = $wpdb->prefix . 'my_plugin';
$my_plugin_db_version = '1.0';

register_activation_hook( __FILE__,  'my_plugin_install' );

function my_plugin_install() {
  global $wpdb;
  global $my_plugin_table;
  global $my_plugin_db_version;

  if ( $wpdb->get_var( "show tables like '$my_plugin_table'" ) != $my_plugin_table ) {
    $sql = "CREATE TABLE $my_plugin_table (". 
	     "id int NOT NULL AUTO_INCREMENT, ".
	     "user_text text NOT NULL, ".
	     "UNIQUE KEY id (id) ".

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );

    add_option( "my_plugin_db_version", $my_plugin_db_version );

So, what does the above code do?
It checks as to whether there is a table by the name $my_plugin_table. If it is present, then does nothing. If not, creates the table and adds the table version to the options so that we can use it next time in case we want to modify the table in an upcoming release. For a detailed explanation of table creation, check this WordPress documentation. Make sure that all the variables that you have declared outside the install function are global. If they are not global, the function will not be able to read them. Check this out for the reason.

Now, activate the plugin. Once activated, see whether your new table is listed in WordPress DB.

Now for the widget creation part. Add the below code to my_plugin.php file.

class MyWidget extends WP_Widget {
  function MyWidget() {
    parent::WP_Widget( false, $name = 'My Widget' );

  function widget( $args, $instance ) {
    extract( $args );
    $title = apply_filters( 'widget_title', $instance['title'] );

	echo $before_widget;

      if ($title) {
	echo $before_title . $title . $after_title;

    <div class="my_textbox">
      <input type='text' name='my_text' id='my_text_id'/>
      <input type='button' value='Submit' id='my_text_submit_id'/>

       echo $after_widget;

  function update( $new_instance, $old_instance ) {
    return $new_instance;

  function form( $instance ) {
    $title = esc_attr( $instance['title'] );

      <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?>
      <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />

add_action( 'widgets_init', 'MyWidgetInit' );
function MyWidgetInit() {
  register_widget( 'MyWidget' );

I am not going to explain the above, as it is almost a copy past from this.

Now, when you go to your widget addition screen, you should see “My Widget” as one of the widgets. Drag and drop it to the right side bar, give it a title and save it. Go to your home page and you should see your widget in the right side bar.

As of now, our widget does nothing, other than display a text box to the end user. Now comes the part where you send the user input to the back end using AJAX and persist it in the database. This is not properly documented in WordPress and I had a pretty tough time figuring it out.

For AJAX, we will be using jQuery JavaScript framework. We do not have to do anything to include jQuery, as it is already enabled in WordPress. All we have to do is, use jQuery in no conflict mode.

Now we need two functions, one for the JavaScript custom code that has to be included in the home page, the other for the AJAX action.

Let us start off with the back end code.

function my_widget_action() {
  global $wpdb;
  global $my_plugin_table;
  $user_text =  $wpdb->escape( $_POST['user_text'] );
  $query = "INSERT INTO $my_plugin_table (user_text) VALUES ('$user_text')";
  $wpdb->query( $query );
  echo 'success';

The above code, takes the user input text from post and stores it in DB. Now we have to make WordPress aware of the fact that, the above function should be executed for the AJAX request. We do this by adding the below to my_plugin.php file.

add_action( 'wp_ajax_my_widget_action', 'my_widget_action' );
add_action( 'wp_ajax_nopriv_my_widget_action', 'my_widget_action' );

In the above, the part ‘wp_ajax_’ and ‘wp_ajax_nopriv’ have to be named as they. The part after that can be named whatever you want, but has to correspond with your AJAX action parameter. This will become more clear once you see the custom JavaScript code. We have two actions, ‘wp_ajax_’ and ‘wp_ajax_nopriv’, one for the logged in user and the other for the end user.

Now for the custom JavaScript code to be included in the home page.

add_action( 'wp_head', 'my_plugin_js_header' );

function my_plugin_js_header() {
   <script type="text/javascript">
     jQuery(document).ready(function($) {
       jQuery('#my_text_submit_id').click(function(){'<?php echo admin_url( 'admin-ajax.php' ); ?>', { 'action': 'my_widget_action',  'user_text': jQuery('#my_text_id').val() }	);

In the above using the usual jQuery $ will not work.

The most interesting part in the above is this”, { ‘action’: ‘my_widget_action’, ‘user_text’: jQuery(‘#my_text’).val() });

The name admin-ajax.php is misleading, but this is the url you have to use for all AJAX actions, irrespective of whether they are admin actions or end user facing ones. Also, the action should correspond to the part following ‘wp_ajax_’ and ‘wp_ajax_nopriv’, that we saw above.

Now when you enter a text in the input box and press submit, it should get persisted in the database.

Download the full code from github.