Lately, I’ve been super into improving my development workflow. I plan to cover a number of different topics related to my workflow as I implement new changes, and create new processes.
One thing that I’ve been wanting to tackle for quite a while is setting up a plugin boilerplate. There are some great boilerplates out there already, most notably the WordPress Plugin Boilerplate project, but I have my own preferences for how I like to structure the plugins I write. Since pretty much every plugin I write takes the same shape, I wanted to use this “template” to automate the creation of a new plugin.
Thanks to some inspiration and help from WPSwitzerland, I have finally created my own boilerplate WordPress plugin and BASH script to automate creating new plugins with just a simple command.
The Plugin Boilerplate
First up is the actual plugin boilerplate. This contains all the files that I start with for every plugin build. The way I like to structure my plugins is the following…
plugin-name
- plugin-name.php
- /assets
-- /css
---- /sass
---- /plugin-name.scss
---- /partials
-- /images
---- /raw
-- /js
---- /custom
---- /vendors
- /includes
- /languages
- /templates
This structure is pretty standard, and I enjoy the simplicity. Let me briefly explain the purpose of everything.
- The
plugin-name
is the directory name of the plugin. If my plugin will be called “My Sample Plugin,” I want the directory name to be “my-sample-plugin.” plugin-name.php
is the plugin’s bootstrap file, which contains the plugin’s required header information (e.g. plugin name, description, author, etc.), namespace, main plugin class, etc. This file also loads include files, defines some constants I commonly use, loads translation files, and a few other useful things.- The
assets
directory is where I keep the plugin’s assets. This directory is broken down intocss
,images
, andjs
directories. - The
assets/css
directory contains asass
andsass/partials
. Thesass/plugin-name.scss
will import the desired partials fromsass/partials
, and will be complied toassets/css/plugin-name.css
. I can add more.scss
files toassets/css/sass
, and they will each compile into their own.css
file inassets/css
. - The
assets/images/raw
directory contains uncompressed images. The images in this file will be compressed, and sent toassets/images
, which are the images I will include. - The
assets/js/custom
directory contains custom scripts for the plugin. These will all be concatenated, and the resulting output minified and sent toassets/js/custom.min.js
. - The
assets/js/vendors
directory contains third-party scripts, such as jQuery plugins. These will all be concatenated, and the resulting output minified and sent toassets/js/vendors.min.js
. This file will then be a dependency ofassets/js/custom.min.js
. - The
includes
directory is where I add PHP files for creating the functionality of the plugin. I like to keep plugins as modular as possible, so I separate out the concerns into their own class files, and include the files in the mainplugin-name.php
. If I am creating admin functionality, I’ll create aincludes/admin
directory to house the admin-specific functionality. - The
languages
directory will contain the.pot
file for creating plugin translations. This is mainly used in plugins I release to the community, as many users will need to translate the plugin into their own languages. - The
templates
directory is where I keep any markup. Similar to theincludes
directory, I will house admin-specific markup (e.g. settings pages) intemplates/admin
.
If you look through the boilerplate-plugin.php
file, and some of the other files, you’ll notice some variables that look like %PLUGIN_NAME%
. These “boilerplate variables” are replaced when I run the custom BASH script (keep reading).
In addition to the basics above, the boilerplate plugin contains a few essential, miscellaneous files:
gulpfile.js
– I use Gulp to run automated build tasks, such as CSS/Sass/JS concatenation and minifying, image compression, generating POT files, etc. This is where all that is configured. You can read about the specifics of my Gulp file here.README_BLANK.md
– This will serve as the readme file for the new plugin.gitattributes.txt
andgitignore.txt
– Notice these are not hidden (“dot”) files like you normally find. Instead, they’re visible text files. This is because the boilerplate itself has these hidden files. When the BASH script cleans up the cloned repo, all of the .git files are deleted, then these two files are moved to their respective dot files for use in the new plugin’s own repository.composer.json
andpackage.json
– These are the dependency config files.composer.json
for managing PHP dependencies, andpackage.json
for managing Node packages like Gulp.
Automating with the Command Line
Here’s where the real magic happens! The accompanying wp-plugin
BASH script is what automates the creation of a ready-to-go plugin from the boilerplate. It does this by running a few prompts to ask for some information about the plugin. Currently, the prompts include inputs for:
- Plugin key – Think of this as the directory name with hyphens (e.g. my-plugin); this is required
- Plugin name – Name of the plugin; used in the plugin header (defaults to title version of plugin key; “My Plugin”)
- Plugin description – Description of the plugin; used in the plugin header
- Plugin URI – URI of the plugin (e.g. sales page); used in the plugin header
- Plugin author – Name of the author (defaults to my name); used in the plugin header
- Author URI – URI of the author (defaults to my website); used in the plugin header
- Author email – Email of the author (defaults to my email); used in copyright and license text
- Git repo URI – Used in package.json
- Git origin URI – Used to add the remote via
git remote add origin ...
When I complete the prompts (I don’t enter input for most of them, as they’re set to my default information), the script clones the boilerplate’s git repo, and cleans it up by renaming some default files, and removing unnecessary files. It then runs a find-and-replace on the boilerplate variables. When the script is finished, I have a fresh plugin, customized just the way I like it, ready to build out for any purpose.
Feel free to fork my plugin and BASH script, and tailor them to your preferences. I’d love to know how you customize them, so please share in the comments!