
Understanding 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.
<?php /* Plugin Name: Example plugin Plugin URI: https://wp-learner.com/plugins/exmaple-plugin Description: This is a brief description of my plugin Version: 1.0 Author: Mahesh Bhat Author URI: https://wp-learner.com License: GPLv2 */ ?>
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:
<?php /* Copyright YEAR PLUGIN_AUTHOR_NAME (email : PLUGIN AUTHOR EMAIL) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 */ ?>
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
<?php register_activation_hook( __FILE__, 'myplugin_install' ); function myplugin_install() { //do something } ?>
One important check usually you do when activating your plugin is to check the version of the WordPress installation is compatible with the plugin.
register_activation_hook( __FILE__, 'myplugin_install' ); function myplugin_install() { global $wp_version; if ( version_compare( $wp_version, '4.1', '<' ) ) { wp_die( 'This plugin requires WordPress version 4.1 or higher.' ); } }
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
<?php register_deactivation_hook( __FILE__, 'myplugin_deactivate()' ); function myplugin_deactivate() { //do something } ?>
Remember that deactivation is not uninstalling, it is just to make that your plugin is no longer working in the WordPress.
Internationalization
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.
<?php $translated = __( 'Hello World!', 'mytextdomain' ); ?>
If your code echo the the translated string to your browser, you should use _e() function.
<?php _e( 'Hello World!', 'mytextdomain' ); ?>
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.
<?php $error_number = 6980; $error_field = "Email"; printf( __( 'Error Code %1$d: %2$s is a required field', 'mytextdomain' ), $error_number, $error_field ); ?>
Plurals need special consideration while translating strings. The _n() function uses the number parameter to determine whether singular or plural string should be returned.
<?php $count = 34; printf( _n( 'You have %d new message', 'You have %d new messages', $count, 'mytextdomain'), $count ); ?>
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.
<?php echo _x( 'Editor', 'user role', 'mytextdomain' ); echo _x( 'Editor', 'rich-text editor', 'mytextdomain' ); ?>
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.
<?php add_action( 'init', 'mytextdomain' ); function prowp_init() { load_plugin_textdomain( 'mytextdomain', false, plugin_basename( dirname( __FILE__ ) .'/localization' ) ); } ?>
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
<?php echo plugin_dir_path( __FILE__ ); ?>
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.
<?php echo '<img src="' .plugins_url( 'images/icon.png', __FILE__ ). '">'; ?>
This will return a full url to your plugins icon.png file
<img src="https://example.com/wp-content/plugins/halloween-plugin/images/icon.png">
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
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
<form method="post"> <?php wp_nonce_field( 'myplugin_settings_form_save', 'myplugin_nonce_field' ); ?> Enter your name: <input type="text" name="text" /><br /> <input type="submit" name="submit" value="Save Options" /> </form>
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.
<?php if(isset($_POST['submit'])) { //check nonce for security wp_verify_nonce("myplugin_settings_form_save",'myplugin_nonce_field'); //nonce passed, now you can do your further steps } ?>
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
<?php $link = "my-url.php?action=delete&ID=21"; ?> <a href="<?php echo wp_nonce_url($link,"myplugin_delete_action", "mypluin_nonce_url_check"); ?>">Delete</a>
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.
<?php if ( isset( $_GET['action'] ) ) { //check nonce for security wp_verify_nonce( 'myplugin_delete_action', 'myplugin_nonce_url_check' ); //do stuff } ?>
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
<?php add_filter($filter_action, $custom_filter_function, $priority, $accepted_args); ?>
- 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
<?php /* * Example to show filter hook in action */ add_filter('the_content','myplugin_content_filter'); function myplugin_content_filter($content){ $content = $content." Content added by myplugin"; return $content; } ?>
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
<?php add_action($action_hook_name, $custom_action_function, $priority, $accepted_args); ?>
- 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
<?php /* * Example to show action hook. Emails every time a new comment is posted */ add_action('comment_post','myplugin_email_new_comment'); function myplugin_email_new_comment(){ wp_mail('[email protected]','New blog comment','Someone has left a new blog comment'); } ?>
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
<?php update_option("myplugin_display_mode","bright"); ?>
Retrieving of an option is done by get_option() function.
<?php echo get_option('myplugin_display_mode'); ?>
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.
<?php $myplugin_options = array( 'myplugin_display_mode' => 'bright', 'myplugin_display_size' => 'large', 'myplugin_responsive' => FALSE, ); update_option('myplugin_settings', $myplugin_options); ?>
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
<?php add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position); ?>
- 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
<?php add_submenu_page($parent, $page_title, $menu_title, $capability, $menu_slug,$function); ?>
Following is an example of creating men with submenu
<?php /* * Example to create menu with submenu */ add_action('admin_menu', "myplugin_create_menu"); function myplugin_create_menu() { add_menu_page('Myplugin Menu', 'Myplugin', 'manage_options', 'myplugin_menu_main', 'myplugin_menu_main_page'); add_submenu_page("myplugin_menu_main", "Myplugin Sub Setings", "Sub Settings", "manage_options", "myplugin_menu_sub", "myplugin_menu_sub_page"); } ?>
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().
<?php /* * Example to add options submenu to settings menu */ add_action('admin_menu','myplugin_settings_submenu'); function myplugin_settings_submenu(){ add_options_page('My Plugin Settings', 'My Plugin Settins'."manage_options", "myplugin_settings","myplugin_settings_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.
<?php /* * Example to create options page */ add_action("admin_menu",'myplugin_create_menu'); function myplugin_create_menu(){ //* Create top level menu add_menu_page("Myplugin Menu Page",'Myplugin Options', "manage_options", 'myplugin_main_menu',"myplugin_main_menu_page"); //* Call register settings function add_action('admini_init','myplugin_register_settings'); } function myplugin_register_settings(){ register_setting("myplugin_settings_group","myplugin_options",'myplugin_sanitize_options'); } ?>
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
<?php /* * Exmaple code for options page */ function myplugin_main_menu_page(){ ?> <div class="form-wrap"> <h2> My Plugin Settings </h2> <form method="post" action="options.php"> <?php settings_fields("myplugin_settings_group"); ?> <?php $myplugin_options = get_option('myplugin_options'); ?> <input type="text" name="myplugin_options[option_name]" value ="<?php echo esc_attr($myplugin_options['options_name']); ?>" /> <br> <input type="text" name="myplugin_options[option_email" value="<?php echo esc_attr($myplugin_options['options_email']); ?>" /> <br> <input type="text" name='myplugin_otpions[option_url]' value="<?php echo esc_url($myplugin_options['options_url']);?>" /> <br> <input type="submit" value="Save options" /> </form> </div> <?php } ?>
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 .
<?php /* * Example to sanitize option data before saving to data. */ function myplugin_sanitize_data($input){ $input['options_name'] = sanitize_text_field($input['options_name']); $input['options_email'] = sanitize_email($input['options_email']); $input['options_url'] = sanitize_url($input['options_url']); return $input; } ?>
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
<?php /* * Example to add setting section to exisiting page */ add_action('admin_init','myplugin_settings_init'); function myplugin_settings_init(){ // create the new section in the exising seting->reading page add_settings_section('myplugin_settings_section','My plugin settings', 'myplugin_setting_section','reading'); //register the settings option add_settings_field('myplugin_settings_email', 'Enter the custom email address', 'myplugin_settings_email','reading','myplugin_settings_section'); //register the setting to store our values register_setting('reading', 'myplugin_setting_values', 'myplugin_sanitize_settings'); } ?>
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.
<?php /* * Example callback function for settings section */ function myplugin_settings_section(){ echo "<p> Configure My plugin </p>"; } /* * Example callback function to display settings field */ function myplugin_settings_email(){ $myplugin_settings = get_option('myplugin_settings_value'); //display the email address input box ?> <input type="email" name="myplugin_settings_value[email]" value ="<?php echo $myplugin_settings['email']; ?>" /> <?php } ?>
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.
<?php add_meta_box($id, $title, $callback, $page, $context, $priority, $callback_args); ?>
- 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
<?php /* * Example to create a custom meta box */ add_action('add_meta_box','myplugin_meta_box_init'); function myplugin_meta_box_init(){ add_meta_box('myplugin-meta','Myplugin Information','myplugin_meta_box','post','side'); } ?>
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
<?php /* * Example callback function to display meta box */ function myplugin_meta_box($post, $box){ //retrieve the custom meta box value $myplugin_value = get_post_meta($post->ID,'_myplugin_value',true); //create nonce for security wp_nonce_field('myplguin_meta_value'); //custom meta box form elemtents echo "<p> Enter Priority </p>"; ?> <input type="text" name="myplugin_value", value="<?php echo esc_attr($myplugin_value); ?> " /> <?php } ?>
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
<?php /* * Example callback function to save data in meta boxes */ add_action('save_post','myplugin_save_meta_box'); function myplugin_save_meta_box($post_id){ if(isset($_POST['myplugin_value'])){ //if auto saving skip saving our meta box if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; //check nonce for security wp_verify_nonce('myplugin_meta_value'); //update the meta values into the post update_post_meta($post_id,"myplugin_value",sanitize_text_field($_POST['myplugin_value'])); } }
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
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.
<?php /* * Example to show shortcodes */ add_shortcode('myname','myplugin_myname'); function myplugin_myname() { return "My name is Mahesh Bhat"; } ?>
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.
<?php /* * Example shortcode with attributes */ add_shortcode('myname', 'myplugin_myname_attr'); function myplugin_myname_attr($attr, $content=NULL){ extract(shortcode_atts(array('short'=>FALSE), $atts)); if($short==true){ return "My name is Mahesh"; }else{ return "My name is Mahesh Bhat"; } }
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.
<?php /* * Prototype to create a custom widget */ class My_Widget extends WP_Widget{ function My_Widget(){ //process the widget information } function form($instance) { //Widget form in admin dashboard } function update($new_instance, $old_instance){ //save widget options } function widget($args, $instance){ //display the widget } } ?>
The first step in creating a widget is to use the widgets_init hook to initialize your widget.
<?php /* * widgets_init hook to instantiate widgets */ add_action('widgets_init','myplugin_register_widgets'); function myplugin_register_widgets(){ register_widget('myplugin_widget'); } ?>
You can register multiple widgets . Each widget type has its own class extending WP_Widget.
class myplugin_widget extends WP_Widget {
The construction function is used to give information about our new widget
// Constructor for widget information function __construct(){ $widget_options = array( 'classname' => 'myplugin_widget_class', 'description' => 'Example widget that displays a users address', ); parent::__construct('myplugin_widget','Address Widget', $widget_options); }
Next is you need to create the function to build your widget settings form
function form($instance) { $defaults = array( 'name' => 'Mahesh Bhat', 'Address' => 'Karnataka, India' ); $instance = wp_parse_args((array)$instance, $defaults); $name = $instance['name']; $address = $instance['address']; ?> <p> <input type='text' name ="<?php echo $this->get_field_name('name'); ?>" value ="<?php echo esc_attr($name); ?> " /> </p> <p> <input type="text" name ="<?php echo $this->get_field_name('address'); ?>" value ="<?php echo esc_attr($address); ?> " /> </p> <?php }
Next you need to update your widget settings using update widget function.
function update($new_instance, $old_instance){ $instance = $old_instance; $instance['name'] = sanitize_text_field($new_instance['name']); $instance['address'] = sanitize_text_field($new_instance['address']); return $instance; }
Finally you need to display your widget
function widget($args, $instance){ extract($args); echo $before_widget; $name = (emppty($instance['name'])) ? ' ': $instance['name']; $address = (empty($instance['address'])) ? ' ':$instance['address']; echo "<p> Name : ". esc_attr($name). "</p>"; echo "<p> Address : ".esc_attr($addres)."</p>"; }
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.
<?php /* * Example code to create and display dashboard widget */ add_action('wp_dashboard_setup'. 'myplugin_add_dashboard_widget'); function myplugin_add_dashboard_widget(){ wp_add_dashboard_widget('myplugin_dashboard_widget', 'My Plugin Dashboard Widget', 'myplugin_dashboard_widget'); } // To display dashoboard widget function myplugin_dashboard_widget(){ echo "<p> This is my Dashboard Widget"; } ?>
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.
<?php /* * Example code to create custom table */ register_activation_hook(__FILE__,'myplugin_install'); function myplugin_install(){ global $wpdb; //define custom table name $table_name = $wpdb->prefix. "myplugin_data"; //build the query to create table $sql = "CREATE TABLE ".$table_name. "(" . "id mediumint(9) NOT NULL AUTO_INCREMENT," . "name tinytext NOT NULL," . "address text NOT NULL," . "phone tinytext NOT NULL," . "UNIQUE KEY id(id)" . ");"; //include upgrade.php before executing your query require_once(ABSPATH."wp-admin/includes/upgrade.php"); //execute the query to create our table. Checks if table exists before creating dbDelta($sql); //set the table structur version $myplugin_db_version = "1.0"; add_option('myplugin_db_version', $myplugin_db_version); } ?>
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.
<?php /* * Uninstall using uninstall.php */ // Ensure that uninstall.php called from WordPress if(!defined('ABSPATH') && !defined('WP_UNINSTALL_PLUGIN')) exit(); delete_option('myplugin_options'); // Delete any other options and custom tables , files, etc. ?>
The second method of uninstall is to execute Uninstall hook. After the hook has been called, your plugins will be deleted.
<?php /* * Example code for uninstall hook */ register_uninstall_hook(__FILE__, 'myplugin_uninstall_hook'); function myplugin_uninstall_hook(){ delete_option('myplugin_options'); //remove additional options and custom tables } ?>
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.
=== Plugin Name === Contributors: bhatmahesht, Donate link: http://example.com/donate Tags: admin, post, images, page, widget Requires at least: 3.8 Tested up to: 4.2 Stable tag: 1.1.0.0 License: GPLv2 Short description of the plugin with 150 chars max. No markup here.
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.
== Description == This is the long description. No limit, and you can use Markdown Additional plugin features * Feature 1 * Feature 2 * Feature 3 For support visit the [Support Forum](http://example.com/forum/ " Support Forum")
The description section feature detailed description it can have HTML markups and links.
== Installation == 1. Upload 'plugin-directory' to the '/wp-content/plugins/' directory 2. Activate the plugin through the 'Plugins' screen in WordPress 3. Place '<?php myplugin_custom_function(); ?>' in your theme templates
Installation section should have specific installation instructions also list the function name and shortcode that can be used with the plugin.
== Frequently Asked Questions == = A question that someone might have = An answer to that question. = Does this plugin work with WordPress Multisite? = Absolutely! This plugin has been tested and verified to work on the most current version of WordPress Multisite
FAQ section helps to answer commonly asked questions and can eliminate many support requests.
== Screenshots == 1. Screenshot of plugin settings page 2. Screenshot of plugin in action
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 == = 1.1 = * New feature details * Bug fix details = 1.0 = * First official release
ChangeLog section lists out what is being added or fixed for each plugin version.
== Upgrade Notice == = 1.1 = * Security bug fixed
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.