10 Must-Know Skills for a WordPress Plugin Developer

WordPress is the most powerful CMS framework available at the moment. It can be used to create highly flexible and extendable websites with very little work. I believe that the Plugins and Themes structure is the main reason behind its success as a CMS. There are around 21,000 plugins available for free on the official WordPress website.

I always prefer creating my own plugins whenever possible. I recommend you learn plugin development; you’ll be able to customize your site very easily and earn good money as a WordPress developer. In this article, I am going to discuss the most essential things you need to know about WordPress plugin development; I am assuming you have a basic knowledge of the WordPress folder structure here.

1. Creating a Plugin

The first step will be creating your own plugin folder in the /wp-content/plugins folder. Once the folder is created you should place your plugin files inside that folder. You should have a main file for your plugin. Files should be named in simple letters with hyphens (-) for separating words.

  • Sample file name: wp-multi-slider.php

Inside your main file you should have the following comment structure in order for WordPress to identify your plugin.

 
<?php 

/* Plugin Name:  Sample Name 
Plugin URI: http://www.sitepoint.com/tutorials/wordpress-plugin-url 
Description: Get email notifications when your favorite author publishes a post. 
Version: 1.0 
Author URI: http://www.sitepoint.com 
Author: Rakhitha Nimesh 
License: GPL2 
*/ 

You will be able to see the plugin in the Dashboard Plugins section, as shown below.

2. Plugin Activation/Deactivation

Plugins can be activated by clicking Activate Link in the plugin list. In a simple plugin you don’t need to do anything on activation. But an advanced plugin will require tasks like initializing plugin options, creating plugin tables, etc. So let’s see how we can handle plugin activation and deactivation.

Plugin Activation Hook

WordPress provides a function called register_activation_hook which will be triggered on plugin activation. We can add a custom function to execute on plugin activation using this method as shown below.

 
function wp_sample_activation() { 
} 
register_activation_hook(__FILE__, 'wp_sample_activation'); 

You have to pass the path of the file that contains the activation function as the first parameter and the function name as the second parameter.

If the activation function is inside the main plugin file you can use __FILE__  as shown in the above code. You can do tasks like validations, initializations and table creations inside the activation function.

Plugin Deactivation Hook

We can handle the deactivation of a plugin with register_deactivation_hook, using similar syntax as with activation. You can clean up the plugin resources, options and tables inside the deactivation function.

 

function wp_sample_deactivation() { 

} 

register_deactivation_hook(__FILE__, 'wp_sample_deactivation'); 

3. Creating Custom Tables

The WordPress database table structure is very flexible and you can implement most of the custom functionalities using the available tables. But there may be occasions where you wish to include more advanced systems like shopping carts, task management systems, or booking systems.

In these cases, you need to know how and when to create custom tables. First, consider the requirements of your projects and try to use wp_options table and meta tables to store your project specific data. If you feel that the above tables are not structured enough to implement the required functionality, create custom tables using the following method.

 
global $wpdb; 
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}sample_table"); 
$sql1 = "CREATE TABLE {$wpdb->prefix}sample_table ( id int(11) NOT NULL AUTO_INCREMENT, 
                                                       activation_code varchar(255) NOT NULL, 
                                                       email varchar(75) NOT NULL, 
                                                       status int(11) NOT NULL, PRIMARY KEY  (id) ) 
         ENGINE=InnoDB AUTO_INCREMENT=1;"; 

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

First, check if the table exists before creating it. You can decide to drop and create the table on activation based on your requirements. You can see that I have used {$wpdb->prefix} before the table name. Generally, WordPress tables are prefixed with wp_. . This can be changed when you install the database; so you should not hardcode wp_ as a prefix to provide increased flexibility.

{$wpdb->prefix} will you give you the prefix defined for the current installation. So always use that syntax before the new table name you are creating.

Even though you can use the $wpdb->query function to create tables, it is recommended to use the dbDelta function as it compares the current table structure. It’s not loaded by default, so you need to include the file first.

4. Including Scripts and Styles

Even though you can just echo the scripts and styles anywhere, it is recommended to add scripts using the wp_enqueue_script function. This function checks if the files are already available and also the dependencies with other scripts. The following example illustrates the effective use of wp_enque_script.

 
add_action('wp_enqueue_scripts', 'sample_scripts'); 

function sample_scripts() { 
  wp_enqueue_script('jquery'); 
  wp_register_style('sample_style', plugins_url('styles.css', __FILE__)); 
  wp_enqueue_style('sample_style'); 
  wp_register_script('jqueryUICore', plugins_url('ui/jquery.ui.core.js', __FILE__),array(“jQuery”)); 
  wp_enqueue_script('jqueryUICore'); 
  $config_array = array(“sample_name”=>”sample_value”]); 
  wp_localize_script('jqueryUICore', 'sampleData', $config_array); 
} 

You can first use wp_register_style to register the style file and wp_enqueue_style to include the file. A unique identifier and path to the style file has to be provided. Then include scripts using the wp_enqueue_script function. If it depends on other scripts, you can mention it as the third parameter. I have used jQuery as a dependency.

Finally, you can add data to be used inside specific scripts by using the wp_localize_script function. You can include the scripts whenever you prefer, but always use the wp_enqueue_scripts and wp_enqueue_styles functions.

Make sure to use the admin_enqueue_script action instead of wp_enqueue_script for the admin side.

5. Creating Shortcodes

Shortcodes are predefined blocks of codes which you can use anywhere. It is vital to learn about shortcodes as a plugin developer, since you can add dynamic behavior to custom pages with them.

You can create shortcodes using following syntax.

 
add_shortcode("shortcode_name", "shortcode_function"); 
function shortcode_function() { 
  return “<input type=’button’ value=’Share’ /> “; 
}

Assign a shortcode name and function to the add_shortcode function. Then return the type of content you want to display in the browser inside the function. The above shortcode creates a simple HTML button.

Use the shortcode in pages, posts or plugins to display the button using the following syntax:

[shortcode_name/]

6. Filtering Content

It is essential to consider how to filter post or page content when you develop a blog-related plugin. Consider the example below.

 
function sample_content_filter($content) { 
  $banners = “HTML for banners”; 
  $author = “HTML for author info”; 
  return $banners.$content.$author; 
} 
add_filter( 'the_content', 'sample_content_filter' ); 

Every time a page or post is viewed, the content will be passed to the function. You can modify, add or remove content as I have shown above.

You can also use WordPress conditional tags to filter the content for specific pages. The following code filters the content on a post detail page.

 

function sample_content_filter($content) {
  if(is_single()){ 
  return $banners.$content.$author; 
  } 
} 

7. Working with Ajax

Ideally, you should know how to use Ajax in WordPress to provide interactive content for users. jQuery’s Ajax functionality is an easy way of mastering this.

 

$.post("admin-ajax.php", { action:"sample_ajax_action" }, 
function(result, textStatus) { 
}, "json");

The most important thing in the above Ajax request is the action. It will be used in the WordPress code to identify the request. Also, all the Ajax requests should be sent to the admin-ajax.php file.

 

function sample_ajax_action() { 
echo json_encode($your_result_array); exit; 
} 
add_action('wp_ajax_nopriv_sample_ajax_action', 'sample_ajax_action'); 
add_action('wp_ajax_sample_ajax_action', 'sample_ajax_action');
 

You can see the same action name used in Ajax is used here with wp_ajax_nopriv_ and wp_ajax_ prefixes. wp_ajax_ is used for logged-in users, and wp_ajax_nopriv_ is used for users who are not logged in.

8. Writing SQL Queries

In WordPress, we have to consider the security of our queries in order to prevent SQL injections. We can use the prepare method to filter the user data before applying it to the query. Always filter user-submitted data with the following code before processing.

 
$wpdb->query($wpdb->prepare("update wp_sample_table set status=1 where activation_code=%s and status=%d",$activationCode,$status)); 

As shown above, always assign escape characters to the SQL and variable values at the end to filter the data before executing in SQL.

9. Adding Option Boxes

WordPress provides a default set of fields such as title, content, image, and excerpt in the content creation screen. We need custom fields to add additional behavior. Even though we can use the custom fields section, it provides text boxes only. We need to add separate fields if we require checkboxes, radio buttons, drop downs and the like.

We can easily create option boxes to provide additional fields, as shown below.

 

add_action('add_meta_boxes', 'add_custom_fields_box'); 
function add_custom_fields_box() { 
  add_meta_box('custom_fields_box_id', 'Custom Info', 'display_custom_info_box', 'post', 'normal', 'high'); 
} 

function display_custom_info_box() { 
global $post; 
$html = "<table><tr><td>Custom Checkbox</td><td><input id='custom_checkbox' type='checkbox' name='custom_checkbox'  /></td></tr> <tr><td>Custom Selecy</td><td><select name='custom_select'  > <option>Option 1</option> </select></td></tr> <tr><td>Custom Upload</td><td><input id='custom_file' type='file' name='custom_file'  /></td></tr></table>"; 

echo $html; 

} 

Values of the fields will be saved to the wp_options table as custom fields. You should prefix your option field names with an underscore to prevent duplication with the custom fields section.

10. Using Nonces for Plugin Security

Security is major concern in creating WordPress plugins. You should not trust data provided by users, and you always need to validate data before executing. WordPress provides a concept called a nonce which creates a nonce value, or arbitrary number used only once, when a form is generated. Then we can check for the same nonce value once the form is submitted to ensure it is a valid request — or otherwise.

You can create a nonce value using the following code:

 

wp_nonce_field('sample_frm_nonce', 'sample_frm_nonce'); 

The first parameter is a unique identifier and the second parameter will be used as hidden form field name. Once the form is submitted, you can validate the nonce value using the code below.

 
if (!isset($_POST['sample_frm_nonce']) || !wp_verify_nonce($_POST['sample_frm_nonce'], 'sample_frm_nonce')){
  return; 
} 

If the nonce is not validated, the request is not processed further.

The WordPress Plugin API is huge, and it is not easy to to cover everything it involves. What I’ve gone through here are just the 10 most common things you might need in the act of plugin creation. Feel free to suggest more concepts you might want to take into account as a plugin developer.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.lakeside.com.np Lakeside Technologies

    Great help for a #Wordpress newbie like me. Bookmarked for my reference.

  • http://www.workbench.no Bjarne

    Thanks for this great summary :)

  • http://www.mikehealy.com.au Mike Healy

    A good, succinct overview of the process—thanks.

  • Dino

    Really great, straighforward summary. Thanks a lot!

  • http://www.amcoitsystems.com khan

    That`s a nice work you done thats a great summary to how we use wordpress thanks

  • http://www.crunch42.com Julian

    More please! Top 100 code snippets…in fact if you write an ebook I’ll buy it.

    • http://www.innovativephp.com Rakhitha Nimesh

      Thanks for the comment. I have plansof creating an ebook. Just needs more experience :)

  • http://blog.igeek.info/ amit

    The activation/deactivation hooks doesn’t really need to be used. Wrote my thoughts on it here. More downsides to using them than upsides imho. :)

    • http://www.innovativephp.com Rakhitha Nimesh

      I have to agree with you in the given scenario. But generally developers have the access to plugin activation and deactivation. Also the init will execute on every request.

      • http://blog.igeek.info/ amit

        Never said that the activation/deactivation hooks aren’t available, I just said that not relying on them will result in a plugin that is usable everywhere! And yes the init() executes on every request thats why a version check is at the top to exit if no install/upgrade needed. The option value is loaded by WordPress among other options so no special DB hit for it. In all, no performance hit! :)

        • http://www.innovativephp.com Rakhitha Nimesh

          Hi Amit

          Thanks for the detailed clarifications. I agree with you on this point. As you mentioned we can remove dependencies in certain situations using this method.

  • http://bluejprojects.com Joanne

    You for got adding the automatic update notification feature.

    • http://www.innovativephp.com Rakhitha Nimesh

      Ya I could have added that one. Since I am limiting it to 10 I had to go for the most essential ones.

      Thanks for the suggestions

  • http://infusedmj.com Mark

    Great just what I need. This summarizes everything…

  • Simone

    All is good execept the fact WordPress isn’t a CMS framework.
    Sorry but a true CMS is a fairly different story.

  • http://ylefebvre.ca Yannick Lefebvre

    Interesting choice of skills for your article. For one, I find it a bit dangerous to talk about custom database table creating in your third point. I would have talked much more about custom post types than custom tables, since CPTs come with a lot of built-in tools to manage the custom data while you need to build everything from scratch when you make new tables.

    I am also perplexed by your statement that fields contained in new meta boxes (point 9) will automatically get saved in the site’s options table. That is inaccurate. These fields will not get saved unless you implement an action hook function that will process the post data and store it in the appropriate table (options, post meta, or otherwise).

    If you’re interested in learning more about plugin development, I suggest taking a look at my book on the topic: WordPress Plugin Development Cookbook by Packt Publishing. You can see a preview of a lot of the contents on Amazon.com (http://www.amazon.com/WordPress-Development-Cookbook-Yannick-Lefebvre/dp/1849517681/ref=sr_1_1?ie=UTF8&qid=1349442118&sr=8-1&keywords=wordpress+plugin+development+cookbook)

    • http://www.innovativephp.com Rakhitha Nimesh

      Hi Yannick

      I agree with your first point regarding custom tables. Creating custom tables will limit us the built in features provided by WordPress. But what if the table structure and fields are not enough to handle our application data ? Specially like creating shopping cart or a job search site. We cant create all the fields in options table.

      Please explain as you are an expert of WordPress

      In the second point I haven’t mentioned that meta boxes will automatically saved to database. I mentioned that it will be stored on options table to let the users know how it is stored. I haven’t included any saving parts because of article length constraints. Definitely users will have to write the saving code.

      Thanks for you suggestions and I’ll definitely read your book on plugin development.

  • http://travelondesigns.com taiger

    “the most powerful CMS framework” is not WordPress. Sorry.
    I think you mean to say the most popular CMS-like blogging software out there.
    Drupal wins as most powerful. However, it much more complex to get up to speed then with WordPress.

    • http://www.innovativephp.com Rakhitha Nimesh

      Hi taiger

      Thanks for your comment.

      Its your personal preference. :) I know that drupal is powerful as well. But my preference will be WordPress.

  • http://converthtmltowordpress.com html to wordpress

    This looks like a nice article written on plugin development in WordPress.
    Really liked the idea of using nonces for plugin security.

    Alan

  • Alex Barylski

    – WordPress is the most powerful CMS framework available at the moment.

    That is a highly subjective opinion to kick start an article. :)

  • http://virtual-web-solutions.com Virtual Web Solutions

    Really good to know about this must know skills. Thanks for providing this. I am a Thesis Developer and the above post will definitely help me. Thanks once again.