Since the inception of WordPress plugins about 10 years ago not a lot has changed in the way we write them. There’s a main plugin file with a header followed by the Wild West basically. Apart from using hooks, there is no standardized way of making plugins.
This isn’t necessarily a problem. There are many simple plugins that don’t need a governing framework, and there are some people who can write perfectly coherent procedural code. That said, the quality of code in plugins is generally not the best, a framework or methodology would go a long way in raising it.
In this article, I’ll look at one possible solution – WordPress Plugin Boilerplate. It is meant to be a starting point for plugin development, an object oriented way of creating a standardized plugin. Since it is coded with OOP principles, it is mainly intended for intermediate coders, but you can easily use it even as a beginner if you know what goes where. By the end of this article, you should know what’s what and how you can get started with it – regardless of your coding experience.
General File Structure
The boilerplate is meant to be used as a Github repository, so the main directory contains files commonly found in Github repos. The README.md file is a general readme and shows up on your main repository page as the description. The CHANGELOG.md file is for recording changes between version and the .gitignore file is for setting files that git should ignore when working with files.
The main folder here plugin-name is where the plugin is stored. Its structure follows the WordPress repository, and you can “check in” this folder to the SVN plugin repo. By default, it contains the assets folder, which stores images and screenshots for your plugin, and the trunk folder, which contains the code for the plugin.[SHOW_ADS]
The trunk folder is what contains the plugin, you could paste this folder into a WordPress installation and activate your plugin. We’ll look at the contents of this folder in detail a bit later. Before we do that, let’s set up shop.
Setting It All Up
Having all these folders and SVN/Git awesomeness in one place is all well and good, but how can you actually use this? You can’t check the whole folder out straight into your plugins folder, it simply won’t work. Checking out only the trunk directory is a hassle, plus you won’t have access to files outside that directory.
Let me show you my favourite way of setting things up. I have a folder on my computer with the following structure:[SHOW_ADS]
- other wordpress files
The html folder is where WordPress is installed. The github folder contains all my WordPress plugins from Github. The wordpress folder contains the same plugins pulled via SVN from the WordPress repository.
Creating A Symlink
The first step I take is creating a vanilla version of WordPress Plugin Boilerplate on Github. I then check that out into my github folder. Next, I create a symlink between the trunk folder within to the wp-content/plugins directory of my WordPress install.
Symlinks is a reference to a file or a folder that resolves to its target as you would expect. The end result of this is that if you symlink a plugin from anywhere on your system to your WordPress directory, it will work just fine. This gives you the following benefits:
- You can store plugins elsewhere.
- You can symlink a folder from within a larger repository.
- You can symlink the same plugin into multiple installations.
Creating a symlink is easy from the terminal or the command prompt on Windows. I suggest opening one and navigating to the plugins directory of your WordPress installation. Then, type the following command:[SHOW_ADS]
# For OSX or Linux ln -s /absolute/path/to/github/My-Plugin-Name/my-plugin-name/trunk my-plugin-name # For Windows mklink /j C:\absolute\path\to\github\My-Plugin-Name my-plugin-name
This creates a link from the first path to the second. The first path is the absolute path to the trunk directory in your Github repository. The second is only the name of the folder you want to link it to when you are already in the plugins directory of your WordPress installation.
Once done, you should see your new plugin show up, just like in the image above. We’ll need to customize things, but we now have our plugin running from the Github repository, making development a lot easier.
There are a lot of folders and files within the trunk directory, let’s start renaming them! First of all, I recommend you name your repository using dashes and capital letters, something like this: My-Awesome-Plugin. The main folder within should be named ‘my-awesome-plugin’. I recommend using this convention throughout the plugin.
Renaming the files is easy in OSX. Open all the folders and select all the files that have the string plugin-name in them. Right click to rename all 14 files and batch rename the lot.[SHOW_ADS]
It will be a bit more difficult in Windows, take a look at this HowToGeek article for more info, or just go one by one.
Terms like “plugin-name” and other variations are spread all throughout the file contents as well. You can use Sublime, Atom.io or other capable text editors to mass-replace within multiple files. Here is a list of what you should replace (make sure to do case-sensitive search-replaces).
- plugin_name should become my_awesome_plugin
- Plugin_Name should become My_Awesome_Plugin
- plugin-name should become my-awesome-plugin
Once you’re done, make sure to fill out the main file’s header comment (my-awesome-plugin.php) to customize it to your needs.[SHOW_ADS]
Table Of Contents
There is a lot contained within WordPress Plugin Boilerplate. The idea is to set strict guidelines on where you can put things. There is one specific place to add your hooks for example, a standard place to add front-end functions and so on. Let’s take a look at the major parts of the framework.
Note that I will be referring to the files as they have been renamed, for example: includes/class-my-awesome-plugin.php. If you’ve renamed your plugin to something else you’ll need to remember that the my-awesome-plugin part of the file name will be different for you.
Activation, Deactivation And Uninstallation
Any code you want to run when the plugin is activated should go in includes/my-awesome-plugin-name-activator.php. In this file, there is a class named My_Awesome_Plugin_Activator inside which there is a activate() method you should use.
Don’t worry if you’re not up to speed on objects just yet, knowing where to put things will be enough to get started.[SHOW_ADS]
The code you need to run on deactivation should be placed in includes/my-awesome-plugin-name-deactivator.php. The activate() method within the My_Awesome_Plugin_Deactivator is what you’ll need to use.
Do you think this is a bit too complex? I don’t blame you! When you start using object oriented concepts you’ll see the benefit of this over procedural code. If nothing else, it provides a very obvious place to put your code which is in itself a huge help.
For uninstallation, the recommended method is to use uninstall.php which is what WordPress Plugin Boilerplate does. Your code should be placed at the very bottom of that file.
Hooks are handled by WordPress Plugin Boilerplate amazingly, but it may seem a bit unwieldy at first. All your hooks should be placed within includes/class-my-awesome-plugin.php. More specifically, inside the My_Awesome_Plugin class, within two methods:[SHOW_ADS]
- define_public_hooks() when adding a hook that is used on the front-end
- define_admin_hooks() when adding a hook that is used on the back-end
Instead of using add_action() or add_filter() as usual, you’ll need to do things slightly differently. Here is how you modify the post contents for example.
$this->loader->add_action( 'the_content', $plugin_public, 'modify_post_content' );
The first parameter is the name of the hook, the second is a reference to the public or admin object. For public hooks this should be $plugin_public, for admin hooks it should be $plugin_admin. The third parameter is the hooked function.
While it seems more convoluted it standardizes the addition of hooks completely, splitting them into two distinct groups in the process.
Public And Admin Content
WordPress Plugin Boilerplate splits hooks into admin/public groups but that’s not all. It splits all your code in the same way by asking you to write public-facing code in the public folder and admin-facing code in the admin folder.[SHOW_ADS]
Both folders contain css, js and partials folders. You should place used CSS/JS assets into these folders and write templates and other reusable bits of HTML into the partials folder. It’s okay to create new files in the partials folder, in fact, that’s what it’s there for!
You should write your hooked functions in these folders as well, within the class in the respective directories. When we hooked the modify_post_content function to the_content above, we told WordPress Plugin Boilerplate where to look for it as well. Since we added this to the public facing side, WordPress Plugin Boilerplate expects it to be defined within the My_Awesome_Plugin_Public class which is in the public folder. Simply create this function within the class and write everything else as usual.
Resources And Dependencies
If you want to use external resources, such as TGM plugin activation, you should add that to the includes folder. TGM is a single file named class-tgm-plugin-activation.php that should be included in the class-my-awesome-plugin.php file, within the load_dependencies() method:
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-tgm-plugin-activation.php';
Are you confused by all the file names and functions? Don’t worry, you’ll get the hang of it pretty quickly. In fact, you will usually be modifying only three files:[SHOW_ADS]
- includes/class-my-awesome-plugin.php is where you add all your hooks and dependencies.
- public/class-my-awesome-plugin-public.php is where you add all public facing functions.
- admin/class-my-awesome-plugin-admin.php is where all admin facing functions go.
At first, using WordPress Plugin Boilerplate may seem like a hassle, but it will pay off in the end. You will come back a year later and know where everything is, your plugin development will be standardized across products and other developers will be able to figure out what’s going on as well.
Finally, don’t forget that a plugin providing a simple widget may not need such a framework. While the use of WordPress Plugin Boilerplate won’t slow down your plugin it does clog up the view if all you need is a few simple lines of code!