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-nameis 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.phpis 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
assetsdirectory is where I keep the plugin’s assets. This directory is broken down intocss,images, andjsdirectories. - The
assets/cssdirectory contains asassandsass/partials. Thesass/plugin-name.scsswill import the desired partials fromsass/partials, and will be complied toassets/css/plugin-name.css. I can add more.scssfiles toassets/css/sass, and they will each compile into their own.cssfile inassets/css. - The
assets/images/rawdirectory 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/customdirectory 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/vendorsdirectory 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
includesdirectory 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/admindirectory to house the admin-specific functionality. - The
languagesdirectory will contain the.potfile 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
templatesdirectory is where I keep any markup. Similar to theincludesdirectory, 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.txtandgitignore.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.jsonandpackage.json– These are the dependency config files.composer.jsonfor managing PHP dependencies, andpackage.jsonfor 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!