WordPress is becoming popular by the minute, not just as a blogging platform but also as a full blown CMS (Content Management System).
We have seen and developed some really large applications recently using WordPress and so it is becoming imperative to follow the best practices for development as it is with any other framework.
Fortunately, the WordPress developers have foreseen these needs and added the possibility of customizing the basic functionality by adding plugins. Basically, a WordPress plugin is a (more or less) stand-alone piece of code that can be executed in different sections and stages within a page or site. The great thing about plugins is that they allow you to add features to your site and remain intact, even if you switch themes or upgrade your WordPress install.
The team at Wooninjas has developed, modified and contributed to several WordPress plugins, we try our best to follow all the best practices and so we decided to share them with others too.
1. Have a Strategy
How you strategize your development process is extremely important. And how you organize your code largely depends on the complexity of your plugin.
If your plugin has very little interaction with WordPress Core files, there is less work needed unless you foresee it expanding significantly later on. On the other hand, large plugins with a lot of groupable code benefit greatly from the use of classes, separate style sheets and script files in keeping the code organized and will definitely make the long term maintenance of the plugin easier.
Spend a significant amount of time on this stage, it’s as Abraham Lincoln said,
“Give me six hours to chop down a tree and I will spend the first four sharpening the axe.”
2. Namespace Your Plugin
You should always namespace (prefix) all your files, functions, classes and variables with your plugin name. Otherwise, it will cause conflicts with other plugins or even themes. I’m not talking about PHP namespaces feature (you can still use that too, but it’s not so common), but here we mean prefixing all your functions and variables like my_plugin_some_function()
or $my_plugin_my_variable
. If you have longer plugin name you should use its shorter version, for example, “the_plugin
would become tp".
3. White Screen of Death, Must!
You must always render WSoD when any public user directly access your .php
files through URL. Why? Because if your file contains some I/O operations it will eventually be triggered and can cause unexpected behavior.
By using the following snippet you can prevent them accessing your files (directly) and ensures that your plugin files will be executed within the WordPress environment only.
if(!defined('ABSPATH')) { exit; }
4. User Roles/Capabilities
WordPress provides us various roles by which we could get a strong hold on our data. Each role is distinguished from another with a set of skills known as ‘Capabilities’. Roles defines the user’s responsibilities and capabilities.Whenever updating/deleting data, check for the current user’s capability as this can provide an additional security layer to your plugin, verifying that the user can execute a specific task.
current_user_can() is a very handy function in this regard. It lets you restrict the access to your code for users lacking the required capabilities.
Consider an example where you need to show the link created by your plugin to only the site administrator and no one else. You can easily ensure that no one other than administrators is able to view your custom link by using the following snippet,
<?php if( current_user_can( ‘manage_links’ ) ) : ?> <a href=’#’>My custom plugin link in WP admin</a> <?php endif ?>
By default, the capability ‘manage_links’ is only provided to a site administrators, hence this piece of code will effectively hide this link from all backend users with non-admin access.
5. Extensible Plugin Development Approach
Have you ever come across a plugin you wanted to customize but can find no other way to do so except hacking the code? You find you are not able to see any action/filter hooks provided by the plugin developer in order to extend the capabilities of the plugin?
To make sure your plugin is up to the standard you should always provide action/filter hooks to allow other people to extend it’s capabilities according to their needs. There is lots of documentation on this but a good starter is this article.
6. Input Sanitization in WordPress
Sanitizing data is essential if you are dealing with user input else you expose your site to XSS (Cross Site Scripting), amongst other harmful affects. WordPress takes care of these things by providing an apprentice function, the sanitize *() class of helper functions. These are super kind to us, and ensure that user input is properly sanitized before passing it on to the database (a commonly used function provided by this class is sanitize_text_field).
In some instances using WP_KSES and its related functions might be a good idea as you can easily clean HTML while keeping anything relevant to your needs present.
7. Using The wpdb Class
The wpdb class is dedicated to providing functions to interact with a database. It is a recommended practice to use this class and not write raw queries. The class handles the user input in a secure manner and prevents any sort of risks associated with writing plain SQL queries. Also, you should consider the functions provided by this class so that your code does not make the site prone to SQL injection.
8. Using WordPress Nonces
A WordPress Nonce is a one-time token which guards your URLs and forms against misuse or any unwanted activity. It’s like a confirmation from a user that “I” want to perform this “action”. Specifically, it is a string created by WordPress which acts as a unique identifier for a person performing an operation such as deletion of a post, post preview etc. Use the wp_create_nonce() function to create the nonce.
The nonce is appended to the URLs and added as a hidden field in forms through wp_nonce_field() and are used to protect against CSRF attacks. They validate that the request to a specific URL was generated from the same site and not from any other site. More on CSRF attack can be read here.
In WordPress, nonces are generated as a hash which includes the user’s ID (which is unique). Each nonce is distinct for every user and they identify that the user has requested to perform a specific option and that he/she is not tricked to click on a link which would create unexpected behavior.
The nonce can be explicitly understood by an example. Let’s consider you are an administrator of a WordPress blog and you want to delete a specific post.
When you click on the “delete” link, WordPress will generate a nonce (token) and it will add it to the URL as follows:
“http://yoursite.com/wp-admin/post.php?post=123&action=trash&_wpnonce=b192fc4204”
Now consider for example that someone tricks you to click on the following link which could delete the post with ID 124. Which you would never want to trash yourself.
“http://yoursite.com/wp-admin/post.php?post=124&action=trash”
In the absence of a nonce, you would actually delete the post with ID 124 without your consent but thanks to WordPress, this is not possible as the nonce check will not allow you to delete this post in the absence of a nonce parameter.
9. Ajax Implementation in WordPress
AJAX is a very powerful and flexible tool that allows developers to create more streamlined applications. AJAX can be used for various purposes such as loading content or verifying login credentials. It is not one technology but a mixture of various programming languages which you probably know. There is, however, built-in support in WordPress for an AJAX workflow.
It is highly recommended that, in order to achieve full flexibility, you should use the core WordPress AJAX implementation while creating a plugin and do not implement your own custom ajax implemetation for WordPress. Using the standard implementation will allow you to utilize all the APIs provided by WordPress and the action/filter hooks within your ajax functions.
10. Errors Reporting
Make sure your plugin doesn’t generate any type of errors as this could potentially reveal information like system directory paths and code logic. Always test your plugin with WP_DEBUG
turned on true
. On a production site you should have a good system for catching errors and logging them to a file (a handy plugin to manage this for you is WP Debug Logger ).
WordPress is popular because of its large and mostly free community support. Without all of us, who are thinking about the possibilities to make this platform easier and robust, it wouldn’t nearly be as popular as it is today. So don’t hesitate to share with us if you have some other tips to make the WordPress plugin development process easier and successful.
1 thought on “WordPress Plugin Development – Best Practices”
Input sanitization practice is must for WordPress plugin development. Input sanitization describes cleansing and scrubbing user input to prevent it from jumping the fence and exploiting security holes.