In my last post, I shared my boilerplate plugin and shell script for automatically scaffolding new WordPress plugins. Among the components of my boilerplate plugin is a Gulp workflow for things like compiling Sass, concatenating and minifying Javascript, compressing images, etc. In this post, I’ll share all the details about what this file does, and how it benefits my plugin development workflow.
First, I can’t thank Ahmad Awais enough for his WPGulp project. My Gulp file is based heavily on WPGulp, but with some tweaks.
Project Variables
In my plugin boilerplate gupfile.js
file, the first 1/3 of the code is setting up project variables, and loading Node modules. These are grouped by function: styles, images, Javascript, and translation. They mainly include source paths (development files), and output paths (production files). Also included are paths to watch – Gulp will watch the Sass partials, and custom and vendor scripts, and will run the associated tasks when those files are changed.
Also in this section is the loading of Node modules, such as Gulp itself, and the Gulp plugins that do the heavy lifting. There’s also a constant for defining which browser versions to support in the Gulp Autoprefixing plugin for adding proper vendor prefixes.
Gulp Tasks
Each Gulp task handles its specific role, and output a push notification to let me know that it finished.
Styles Task
The styles
task compiles the project’s Sass into CSS, adds vendor prefixes, minifies the results, and sends it off to a .min.css
file in the assets/css
directory.
Note that each top-level file in the assets/css/sass
directory (.scss
files not in the partials
folder) will be compiled into its own, separate .css
file. For example, if I have assets/css/sass/main.scss
and assets/css/sass/other.scss
, then the styles
task will generate two CSS files: assets/css/main.css
and assets/css/other.css
. This is helpful for when I want to enqueue page-specific styles.
Images Task
The images
task is pretty simple: grabs each image in the assets/images/raw
directory, compresses them, and sends the compressed images to assets/images
, which is the source from which I pull the images in the plugin’s code.
Vendors JS Task
The vendorsJS
task concatenates (joins) all the Javascript files in assets/js/vendors
into one file, renames this file to vendors.min.js
, minifies the code, and sends the output to assets/js
. I keep the vendor scripts in a separate file from my custom scripts because the custom scripts will depend on the vendor scripts, so the vendor scripts will need to be loaded first.
Custom JS Task
This operates in the exact same way as the vendorsJS
task, except it concatenates the files from assets/js/custom
, and sends them to assets/js/custom.min.js
.
POT Task
The pot
task is what generates the .pot
file for the plugin. This file is important for internationalization of your plugins, because they’re used by translators to create translation files. It looks through all of the plugin’s PHP files, and generates a .pot
file based on your usage of WordPress i18n functions, such as __()
, _e()
, etc.
A convenient feature I added to the pot
task is the search-and-replace for the text domain placeholder. The best practice for creating translatable strings is to use a text domain that matches the name of the plugin directory. If my plugin’s directory name is my-plugin
, then the text domain should be my-plugin
. This means that the text domain is different for each plugin I develop. Unfortunately, I can’t use a constant for the text domain, because the pot
task won’t properly recognize the strings unless the second parameter of the WP i18n function is literally the text domain value. Meaning, this won’t work…
__( 'My translatable string', MY_PLUGIN_TEXT_DOMAIN );
Instead, the pot
task requires this…
__( 'My translatable string', 'my-plugin' );
Since some of the plugins I have can have lengthy text domains, I don’t want to type this out every time I add a translatable string, and locating-copying-pasting the text domain each time is not cool. To get around this, I’ve added a custom snippet to my code editor to output a placeholder text domain when I use the i18n functions.
__( 'My translatable string', 'tdomain' );
Now, when I run the pot
task, Gulp searches the PHP files for tdomain
, and replaces it with the value of text_domain
, a variable defined in the Gulp file. No longer do I have to repeatedly type out a plugin’s text domain, or screw around with copying and pasting it.
Default Task
Last is the default
task. This task is what runs when you run gulp
from within the project. It automatically runs the styles
, images
, customJS
, and vendorsJS
tasks. Then, it begins watching the Sass partials, and individual Javascript files, running the tasks associated with each when the files change.
This Gulp workflow works really well for me in my custom plugin development. I consider it a work-in-progress, and will be making adjustments in the future, but feel free to copy it and make it work for your needs. Again, huge thanks to Ahmad for all his hard work!