Understanding Plugin Development

WordPress plugin development
WordPress plugin development

WordPress is such a popular platform because it’s such an easy thing to extend functionality using plugins. The plugins can be created without altering anything in the core. Any new functionality is implemented by writing plugins. Plugins provide endless possibilities for WordPress.  When you are developing a plugin you have to follow a standard plugin packaging template. Certain functional and descriptive components exist in all the plugins you write.

Standard plugin folder  structure

The first step in creating a WordPress  plugin is to create a new PHP file for your plugin code. The plugin file name should be descriptive of it’s plugin so it is easy to identify plugin file in the directory. The plugin directory name should be same as plugin PHP file name.  The standard plugin folder structure could be like following. Keeping your plugin code organized make it easier to track the flow of your plugin.

  • /unique-plugin-name
    • unique-plugin-name.php  – Primary plugin PHP file.
    • uninstall.php – The uninstall file for your PHP file
    • /js – Folder for Javascript files
    • /css – Folder for css files
    • /includes – Folder for additional PHP include files
    • /images – Folder for images


Standard plugin header structure

The requirement for a WordPress plugin is a valid plugin header. The plugin header must be defined in your main PHP file . It should be at the top as a PHP comment. Following is a example of a standard plugin header.

The only line required is plugin name.  The rest of the information is optional but highly recommended. The information is used in the manage plugin section of your WordPress dashboard. The plugin information should be accurate and provide good links to plugin URL and author URL for additional information and support regarding your plugin.

When you are planning to release your plugin to public , it is customary to include plugin licence just below the header information as a comment. This is not a requirement , but it’s a good idea to include it.   A license comment block will also state that there is no warranty, which protects you from liability should someone decide your plugin destroyed his or her site. Following is a standard GPL license,
under which most WordPress plugins are released:

To use this licence in your plugin , just fill in the year,  author name, author email in the above comment. This will make you release your plugin under GPL. WordPress is released under GPLv2 software licence. Since plugins are dependent upon WordPress they should be released under GPL or  compatible licence.  For more information on GPL licensing visit http://www.gnu.org/licenses/licenses.html .

Activating and Deactivating functions

The function register_activation_hook() is executed when WordPress plugin is activated in the dashboard. It takes two parameters.  One is path to main plugin file and other is function to execute when plugin is activated. Following is the example for activation hook

One important check usually you do when activating your plugin is to check the version of the WordPress installation is compatible with the plugin.

The above code uses a global variable $wp_version, which stores the currently running version of the WordPress. You can compare versions using version_compare() function.

The function that gets executed when the plugin is deactivated is called register_deactivation_hook(). Following is an example of this function

Remember that deactivation is not uninstalling, it is just to make that your plugin is no longer working in the WordPress.


Internationalization is the process of making your theme and plugins ready for translation. This is the process of marking the strings that can be translated. This isn’t a requirement , but opens up wider audience for your plugin. WordPress features many functions for translation.

The function __() returns the translated string. It takes two parameters, first one is string to be translated and second one is text domain which is used to distinguish between all loaded translations, which should be unique throughout the plugin.

If your code echo the the translated string to your browser, you should use _e() function.

You can also use placeholders while making your plugins internationalized. Following is a example of that.  This is achieved by using printf() function over __() function. Following example explains it.

Plurals need special consideration while translating strings. The _n() function uses the number parameter to determine whether singular or plural string should be returned.

The _x() function allows to have a translation that might have different meanings in different contexts. The second parameter it takes is the context information for the translators.

After you have prepared your plugin for translation you need to load the localization file to do the translation. For the execute load_plugin_textdomain() function.  You should store your localization files in a directory called /localization under your plugin directory.

Determining Paths

When creating WordPress plugins, you’ll need to reference files and folders. You should never use hardcoded paths in your plugins because WordPress allows to move the plugin directory anywhere you want. WordPress has a set of functions to determine the path to the wp_content and plugins directories, as well as directories within plugins.

To determine the local path of the plugin use plugin_dir_path() function

This would return the path /public_html/wp-content/plugins/myplugin.

To determine the URL to any file within your plugin directory use the plugin_url() function.

This will return a full url to your plugins icon.png file

WordPress also featurs many functions to determine URLs.

  • admin_url() – Administration URL
  • site_url()  – Site URL for the current site
  • home_url() – Home URL of the WordPress installation
  • includes_url() – URL for the includes directory
  • content_url() – URL to the content directory
  • wp_upload_dir() – Returns an array with location information on the configured uploads directory.

Plugin Security

One of the important things to consider while creating a plugin is making sure it is secure from hacks and exploits. The security holes in plugin can make whole WordPress website vulnerable to hacking.  WordPress provides some security utilities which you can make use to prevent hackers and make your plugins as secured as possible.  All external data is suspect until it’s proven valid. It’s good practise to validate your data before inserting into database or displaying it on the browser.  This will help you to secure from hacks and exploits.


Nonces stands number used once. These are used in all requests like saving options, form posts, ajax requests etc to stop unauthorised access by generating a secret key. This secret key is used prior to generating a request and the same key is passed to the request to your script and verified before anything else is processed.  The following example shows how to create a nonce field

When creating a nonce field for form, the function wp_nonce_field() must be called withing <form> tags. When this function is called it will generate a secret hidden key and added to a hidden form field and passed with your form data.  The first parameter is action which is descriptive of the action being performed. The second parameter is a unique name of the field.  After your form is posted, the first thing you need to do is check your nonce secret key using wp_verify_nonce() function.

Verifying nonce is valid is simple, call the wp_verify_nonce() function and pass your unique nonce action and name that you defined earlier.  If the nonce secret key doesn’t match the secret key created on your form, WordPress will stop processing the page and issue an error message.

Nonces can also be used on links that perform actions. To achieve this just use the wp_nonce_url() function. Look at the following example to create nonce field in URL

The query string myplugin_nonce_url is added to the url along with unique secret key created by function wp_nonce_url. This will be verified by the following  wp_verify_nonce() function before processing in the action script.

Thus by using nonce in our WordPress we can make security checks to hackers who are trying to exploit our website.

Data Validation and Sanitization

Any data that that comes from external input needs to checked to verify that it’s free from illegal characters and potentially unsafe data. Data validation is essential for security of plugins.  If the data is improperly validated then it might result in SQL injunction attacks, exploits, errors etc. WordPress provides some escaping functions that allow removing unwanted characters from external input.

  • esc_html() – This function escapes data that contains HTML.  It also encodes special characters into normal characters.
  • esc_attr() – This will escape all attributes from HTML blocks
  • esc_tesxtarea() = This function should be used for escaping HTML values from text blocks .
  • esc_url() – This function is used for validating and to scrub URL for illegal characters.
  • esc_js() – This function escapes text strings in javascript
  • esc_sql() – This function escapes data for use in MySQL query.

The optional suffix __  or _e is used with above mentioned functions for translating the escaped data .  WordPress also features some sanitize functions which should be used to sanitize any data prior to saving it in the database.

  • sanitize_text_field() – This function removes all unsafe characters , invalid UTF-8 characters , linebreaks etc to make it safe before storing into the database.
  • sanitize_email() – This function removes all illegal characters and extra spaces from the email address submitted
  • wp_kses() – This function allows only allowed HTML tags to be present in the submitted value and escapes all other things

For knowing more about data validation in WordPress you can visit http://codex.wordpress.org/Data_Validation

Hooks , Actions and Filters

The most important feature extending WordPress is called a hook. Using hooks you can execute functions at specific times in the WordPress process, allowing you to alter how WordPress functions and change expected output. A hook is simply a PHP function call that can be sent and that is the the primary way plugins interact with WordPress content. Two types of hooks are used , actions and filters. Action hooks are triggered by events in WordPress, like new post published, new comment published etc.  Filter hooks are used to modify WordPress content before saving to database or displaying it to the screen. The following is how a filter function looks like

  •  filter_action  – The filter to use
  • custom_filter_function – The custom function to pass the filter through
  • priority – The priority in which this filter should run. When multiple callback functions are attached to same filter , priority decides the execution order
  • accepted_args  –  The number of arguments the function accepts

Following is an example of the_content filter in action

Filter hooks always receive data and filter it and process it and returns filtered content. Here is some of popular filter hooks.

  • the_content – Applied to the content of the post, page or custom post type before displaying
  • the_title – Applied to the post, page, or custom post type title before displaying
  • wp_title – Applied to the page <title> header tag before displaying

To know more filter hooks visit WordPress codex http://codex.wordpress.org/Plugin_API/Filter_Reference

Now take a look at the action hooks . The syntax is similar to filter hooks and takes for parameters

  •  action_hook_name – This is the name of the action hook event
  • custom_action_function –  The custom function name that executes when event is triggered
  • priority – The priority of the function name
  • accepted_args – The number of arguments function takes

Here is some of the popular action hooks

  • publish_post – Triggered when a new post is published
  • create_category – Triggered when a new category is created
  • switch_theme – Triggered when you switch themes
  • admin_head – Triggered in <head> section of the admin dashboard
  • wp_head – Triggered in the <head> section of your theme
  • wp_footer – Triggered in the footer section of your theme , usually directly before <body> tag
  • init – Triggered after WordPress has finished loading , but before any headers are sent.
  • admin_init – Same as init , but only runs in admin dashboard pages
  • user_register – Triggered when a new user is created
  • comment_post – Triggered when a new comment is created

To know more about more actions visit WordPress Codex http://codex.wordpress.org/Plugin_API/Action_Reference.  You can also visit the plugin directory on WordPress.org. It is the best way to figure something out how other developers accomplished a similar task.  Published plugins are perfect place to learn.


Plugin Settings

Most plugins feature a settings page. This allows us to configure the plugins act in different ways without altering the code behind plugins. This allows simple usable interface for developers. WordPress offtes some very easy to use functions like add_optins(), update_options(),delete_options()  to save, update and delete options. Genearlly update_option() is used for both adding and updating options in plugins. This function checks whether the option already first and if not create it. The following is an example

Retrieving of an option is done by get_option() function.

A good rule of thumb while creating options is to prefix your plugin name . This makes your options unique and easily identifiable. You can also store all options in an array too.

When you retrieve myplugin_settings with get_option function it retrieves an array. Parse that array to get option values.


Creating Menu and Submenus

WordPress offers you to create menus either in the top level menu or as a submenu item for an existing menu. Creating a top level menu is by using the function add_menu_page(). These are created in the dashboard

  •  page_title – Text used for HTML title
  • menu_title – Text used for menu name in the dashboard
  • capability – Minimum user capability required to see menu
  • menu_slug – Unique slug name for your menu
  • function – Function to display page content for the menu
  • icon_url – Path to custom icon for menu
  • position – The position in the menu order the menu should appear.

You can also create a submenu item for your menu using add_submenu_page() function

Following is an example of creating men with submenu

The hook admin_menu  is triggered after the basic admin panel menu structure is in place and it is the only hook you should use when registering a custom menu. You can add a custom menu to Settings menu in WordPress using add_options_page().

Here the first parameter is page title, second is menu title, third is capability, fourth is menu slug and fifth is function to show menu page.  There are some other useful functions available for submenus in WordPress.  Each function takes same number of parameters.

  • add_dashboard_page() – Adds submenu items in the Dashboard menu
  • add_posts_page() – Adds submenu items to the Posts menu
  • add_media_page() – Adds a submenu item to the Media menu
  • add_pages_page() – Adds a submenu item to the Pages Menu.
  • add_comments_page() – Adds a submenu item to the Comments Menu
  • add_plugins_page() – Adds a submenu item to the Plugins menu
  • add_theme_page() – Adds a submenu item to the apearence menu
  • add_users_page() – Adds a submenu item to the Users page.
  • add_management_page() – Adds a submenu item to the Tools menu
  • add_options_page() – Adds a submenu item to the settings menu.

Creating an Options Page

WordPress settings API is a powerful tool to store settings for plugins. It handles all the security checks while saving options.  To create an options page, you need to create the menu functions and register the option you are going to offer on your plugin options page.



Using the settings API’s register_settings() function, you define the option you are going to offer on your plugin options page. The first parameter is options group name. The second parameter is actual option name. The third parameter is a callback function to sanitize option values.  Your code for options page will look like following

Inside the form you defined your settings group which establishes the link between your options and their values. Next you displayed existing options value. Finally you need to sanitize your input data before saving into the database .

Like you have created an options page you can also create custom settings section in existing option pages.  Use add_settings_section() function to create your new section. Use add_settings_field() to register individual settings. Look at the following code

In the function add_settings_section() , the first parameter is the unique id for the section, second parameter is the display name output on the page, third parameter is the callback function to display actual section , final parameter is settings page to add your section to. Now to register individual settings you are using add_settings_field() function, the first parameter you are passing is a unique id for the field, second parameter is title displayed on the screen, third parameter is callback function which will display option field, the fourth parameter is settings page and final parameter is name of the section you are adding this field to.  Next register settings field with register_setting() function.  Now we need to create callback functions one by one.

By this way you can successfully create your custom settings section and added it to the Settings->reading screen.

Creating Meta Box

WordPress features many meta boxes on the Add new post or Page screens. These meta boxes are used for adding additional information like category or tags to your posts, pages or content. Meta boxes can be added to WordPress using add_meta_box() function.

  • id – The HTML ID attribute of meta box
  • title – The title displayed in the header of the meta box
  • callback – The custom function to display your meta box information
  • page – The page you want your meta box to display on content type (Ex. ‘post’, ‘page’ etc)
  • context – The part of the page where your meta box is displayed . ( Ex. ‘normal’, ‘advanced’ or ‘side’).
  • priority – The priority within context where meta box should display
  • callback_args – Arguments to pass into callback function

Following code creates a meta box in WordPress

The hook add_meta_box is used to execute your custom function which creates meta box.  Now you need to create your custom myplugin_meta_box function to display your meta box fields

The first step in your custom function is to retrieve the saved values for your meta box. If you are creating a new post there won’t be any saved values. Next you need to display the form elements in your meta box. You don’t need any form <form> tags or a submit button.  To save the value in the meta box , you’ll need to create a custom function to be executed for the save_post action hook.  Following code explains that

Use update_post_meta() to save meta data into the database. Note that meta key is prefixed with _ , this prevents from meta values being listed by  custom fields meta box screen.


Shortcodes are basically text macro codex that can be inserted into a post, page or custom post type. When being displayed, these shortcodes are replaced by some other type of content.

Now if you enter [myname] shortcode in your content, it will displayed as “My name is Mahesh Bhat” . You can also use HTML elements too.  Shortcodes can also be configured to accept attributes. This is very useful for passing arguments to your ustom functions, thereby altering the output of shortcode based on those arguments.

Now the shortcode dctermines its output by some attributes. If you insert a shortcode [myname short=true] then it will insert text as “My name is Mahesh” .  Shortcodes also accept multiple attribues. Shortcodes are among the popular features of WordPres.

 Creating a Widget

Widgets are piece of content that are displayed in the selected areas of page in a WordPress site. Many plugins provide widgets to power your WordPress website. To understand how widgets work, it’s helpful to have an overview of WP_Widget class. It has many functions needed for building a widget. You can create your own widget by extending WP_Widget class.

The first step in creating a widget is to use the widgets_init hook to initialize your widget.

You can register multiple widgets . Each widget type has its own class extending WP_Widget.

The construction function is used to give information about our new widget

Next is you need to create the function to build your widget settings form

Next you need to update your widget settings using update widget function.

Finally you need to display your widget

The first thing to do is extract $args which stores theme global values like $after_widget and before_widget values. By using widget class you can add multiple copies of same widget to different locations of the theme.

Creating dashboard widget

Dashboard widgets are displayed in main dashboard .  To create a custom dashboard you’ll use the wp_add_dashboard_widget() function.

The first parameter is widget slug, second parameter is the display name of your widget, third parameter is the callback function to display your widget.

Creating Custom Tables

Sometimes you might find that your plugin needs a custom table to store plugin data. Allowing to build custom tables helps in handling complex data. Create an installation function and execute this function when the plugin is activated and create your custom tables.  While naming table prefix should be used, and table prefix can be obtained by global $wpdb->prefix. After that build an SQL query for creating a new table. Also it’s good idea to save the version number for your database table structure.

The function dbDelta() checks if tables exist before creating.  If you want to upgrade your table structure for a new version of your plugin , you can just compare the table structure version numbers. To work with custom table once you have created it , you’ll need to use the WordPress database class to access it.

Uninstalling Your Plugin

WordPress offers two ways of uninstalling your plugin, uninstall.php method and uninstall hook. Both gets activated when a deactivated plugin is deleted in the WordPress admin dashboard. In a perfect uninstall scenario there would be no trace of your plugin left over in the database once it had been uninstalled.  Following is the example code to uninstall from uninstall.php.

The second method of uninstall is to execute Uninstall hook. After the hook has been called, your plugins will be deleted.

Uninstalling a plugin should remove every data that plugin has added to your WordPress site.

Publishing your plugin to plugin directory

You can release your plugin to the world, using publicizing it in the WordPress.org . This allows other WordPress users to download and install it. However there are few restrictions exist to submitting your plugin to directory.

  • Plugins must be compatible with GPLv2 or any other later versions
  • Plugin must not do anything illegal or morally offensive
  • Plugin must use  Subversion(SVN) repository to host your plugin.
  • Plugin must not embed external links on user’s site, without asking the plugin user’s permission

Submitting your plugin

  • The first step is to create an account on WordPress.org
  • To submit your plugin visit https://wordpress.org/plugins/add/
  • Enter the required fields
    • Plugin Name – This is also name of the plugin directory in WordPress.
    • Plugin description – This contains detailed descriptions. Clearly state the plugin functionality , the purpose of the plugin and installation instructions
    • Plugin URL- Include a download link to your plugin.  This enables the reviewer of your plugin to download and look at your plugin if needed.
  • Upload your plugin to the subversion repository that has been created for it.

Creating a readme.txt file

One important file in your plugin directory is readme.txt file. This file is used to fill all the plugin information in the plugin detail page in the directory. WordPress has developed the readme file standard and exactly your readme.txt file should be defined. You can validate your readme.txt file using https://wordpress.org/plugins/about/validator/ before submitting it to subversion directory. The readme file has many sections.

The first line lists contributors , a comma separated list of WordPress.org usernames that helped to contribute to the plugin.  Tags are comma separated tags describing your plugin. “Requires atleast” makes sure minimal version of WordPress needed and “Tested up to” ensures latest version plugin is tested. “Stable tag” should be the current version of the plugin, which should match the version number listed in the plugin header. Last line is a short description of the plugin.

The description section feature detailed description it can have HTML markups and links.

Installation section should have specific installation instructions also list the function name and shortcode that can be used with the plugin.

FAQ section helps to answer commonly asked questions and can eliminate many support requests.

List out each screenshot description in an ordered list. Place image files in trunk directory with names matching the listing number, for example screenshot-1.png , screenshot-2.png etc.

ChangeLog section lists out what is being added or fixed for each plugin version.

The Upgrade Notice section allows you to send specific upgrade notice messages to the WordPress user.  This is the final section.  The readme.txt file can also take arbitrary sections in the same format. Arbitrary sections will be displayed below the built in sections described previously.

Setting up SVN

The plugin directory uses Subversion (SVN) for handling plugins. You need to setup SVN client to publish your plugin to the directory. For a list of  SVN clients for different platforms, visit http://subversion.apache.org/. Use SVN client to connect to your plugin repository.

Publishing to the plugin directory

First you need to SVN commit the trunk folder to your SVN repository. Second , you need to tag your plugin release. After these steps your plugin will appear in Plugin Directory within 15 minutes.

Releasing a new Version

To release a new version , make sure you copy the uploaded plugin files to the /trunk directory you setup earlier. Right click the trunk directory and select the SVN commit. The next step is to tag your new version with new branch. After 15 minutes your plugin will appear at the top of recently updated plugins list at WordPress.org

Plugin assets

A plugin can have assets directory which can have plugin header images and plugin icons.


Plugins are very important feature of WordPress that extends functionality using powerful hooks, shortcodes, data validation, setting options etc.

4 Responses

  1. You explained the plugin structure and development process very well. From your article it seems like the guidelines laid down by the WordPress dev team are strict. Thus the plugin should be excellent inorder to be accepted in the WordPress directory.

  2. I am fine with the free setup right now LOL! At one point this wouldn’t have stopped me for a second. I designed websites, but due to cognitive problems this is easier just to use the free wordpress. You do a good job of describing things.

    1. Thank you :). WordPress free setup also provides very useful features for writers. If WordPress can be used for beyond writing, which is possible by extending features by plugin development. Who can’t write a plugin can also customize and extend functionality of a WordPress installed website by installing numerous plugins.

Leave a Reply

Back to Top
%d bloggers like this: