Categories
Web WordPress WordPress Plugins

WORDPRESS PLUGIN BOILERPLATE

What is Plugin Boiler Plate?
A foundation for WordPress Plugin Development that aims to provide a clear and consistent guide for building your plugins.

Every time I start working on a new plugin I find myself renaming files names, searching and replacing plugin-namePlugin_Name , the packages, sub packages names, etc. All these tasks take me around 5-10 minutes every time, and I don’t like repeat unnecessary tasks.

So I found an easy way to generate WordPress plugin basic structure with in seconds. Of course it saved a lot of time.

Please visit  WordPress Plugin Boilerplate to generate plugins boiler plate. Obviously it won’t generate all of the files you require for your plugin. You can add more files once you have your basic structure.

WordPress Plugin Boilerplate Generator Configuration
WordPress Plugin Boilerplate Generator Configuration

There is no standard way to write a plugin. People follow different ways to write plugins. Some plugins require OOP to be followed and some don’t. But this is the best OOP structure that I had ever found and used in my Plugins development.

Please visit WordPress Plugin Boilerplate GitHub repository to get the essence of the final plugin structure.

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.
Lets dig deeper into it.

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 and details about the plugin. 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. It should have at least one fine your-plugin-slug.php with all the plugin details (Plugin Name, Version, Description, Author, Plugin Slug).

<?php

/**
 * The plugin bootstrap file
 *
 * This file is read by WordPress to generate the plugin information in the plugin
 * admin area. This file also includes all of the dependencies used by the plugin,
 * registers the activation and deactivation functions, and defines a function
 * that starts the plugin.
 *
 * @link              www.authoruri.com
 * @since             1.0.0
 * @package           Your_Plugin_Slug
 *
 * @wordpress-plugin
 * Plugin Name:       Your Plugin Name
 * Plugin URI:        www.yourpluginurl.com
 * Description:       This is a short description of what the plugin does. It's displayed in the WordPress admin area.
 * Version:           1.0.0
 * Author:            Author Name
 * Author URI:        www.authoruri.com
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain:       your-plugin-slug
 * Domain Path:       /languages
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Currently plugin version.
 * Start at version 1.0.0 and use SemVer - https://semver.org
 * Rename this for your plugin and update it as you release new versions.
 */
define( 'YOUR_PLUGIN_SLUG_VERSION', '1.0.0' );

/**
 * The code that runs during plugin activation.
 * This action is documented in includes/class-your-plugin-slug-activator.php
 */
function activate_your_plugin_slug() {
	require_once plugin_dir_path( __FILE__ ) . 'includes/class-your-plugin-slug-activator.php';
	Your_Plugin_Slug_Activator::activate();
}

/**
 * The code that runs during plugin deactivation.
 * This action is documented in includes/class-your-plugin-slug-deactivator.php
 */
function deactivate_your_plugin_slug() {
	require_once plugin_dir_path( __FILE__ ) . 'includes/class-your-plugin-slug-deactivator.php';
	Your_Plugin_Slug_Deactivator::deactivate();
}

register_activation_hook( __FILE__, 'activate_your_plugin_slug' );
register_deactivation_hook( __FILE__, 'deactivate_your_plugin_slug' );

/**
 * The core plugin class that is used to define internationalization,
 * admin-specific hooks, and public-facing site hooks.
 */
require plugin_dir_path( __FILE__ ) . 'includes/class-your-plugin-slug.php';

/**
 * Begins execution of the plugin.
 *
 * Since everything within the plugin is registered via hooks,
 * then kicking off the plugin from this point in the file does
 * not affect the page life cycle.
 *
 * @since    1.0.0
 */
function run_your_plugin_slug() {

	$plugin = new Your_Plugin_Slug();
	$plugin->run();

}
run_your_plugin_slug();

Activation, Deactivation & Uninstall:
This file ( your-plugin-slug.php ) also includes activation and deactivation hooks. These hooks are fired when plugin is activated and deactivated. This file is a gateway to the functionality of the whole plugin. You can add your whole code in this file but its not recommended you should follow MVC separate your models, views and your controllers. Any code you want to run when the plugin is activated should go in includes/your-plugin-slug-activator.php. In this file, there is a class named Your_Plugin_Slug_Activator inside which there is a activate() method you should use.

<?php

/**
 * Fired during plugin activation
 *
 * @link       www.authoruri.com
 * @since      1.0.0
 *
 * @package    Your_Plugin_Slug
 * @subpackage Your_Plugin_Slug/includes
 */

/**
 * Fired during plugin activation.
 *
 * This class defines all code necessary to run during the plugin's activation.
 *
 * @since      1.0.0
 * @package    Your_Plugin_Slug
 * @subpackage Your_Plugin_Slug/includes
 * @author     Author Name <author@gmail.com>
 */
class Your_Plugin_Slug_Activator {

	/**
	 * Short Description. (use period)
	 *
	 * Long Description.
	 *
	 * @since    1.0.0
	 */
	public static function activate() {
		//activation code here
	}

}

The code you need to run on deactivation should be placed in includes/your-plugin-slug-deactivator.php. The deactivate() method within the Your_Plugin_Slug_Deactivator is what you’ll need to use.

<?php

/**
 * Fired during plugin deactivation
 *
 * @link       www.authoruri.com
 * @since      1.0.0
 *
 * @package    Your_Plugin_Slug
 * @subpackage Your_Plugin_Slug/includes
 */

/**
 * Fired during plugin deactivation.
 *
 * This class defines all code necessary to run during the plugin's deactivation.
 *
 * @since      1.0.0
 * @package    Your_Plugin_Slug
 * @subpackage Your_Plugin_Slug/includes
 * @author     Author Name <author@gmail.com>
 */
class Your_Plugin_Slug_Deactivator {

	/**
	 * Short Description. (use period)
	 *
	 * Long Description.
	 *
	 * @since    1.0.0
	 */
	public static function deactivate() {
		//deactivation code here
	}

}


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. You should dump everything that your plugin has created it is a sign of good plugin development to clean what is of no use. WordPress will automatically call uninstall.php if found in the plugins main folder. You can also use uninstallation hook.

<?php

/**
 * Fired when the plugin is uninstalled.
 *
 * When populating this file, consider the following flow
 * of control:
 *
 * - This method should be static
 * - Check if the $_REQUEST content actually is the plugin name
 * - Run an admin referrer check to make sure it goes through authentication
 * - Verify the output of $_GET makes sense
 * - Repeat with other user roles. Best directly by using the links/query string parameters.
 * - Repeat things for multisite. Once for a single site in the network, once sitewide.
 *
 * This file may be updated more in future version of the Boilerplate; however, this is the
 * general skeleton and outline for how the file should work.
 *
 * For more information, see the following discussion:
 * https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate/pull/123#issuecomment-28541913
 *
 * @link       www.authoruri.com
 * @since      1.0.0
 *
 * @package    Your_Plugin_Slug
 */

// If uninstall not called from WordPress, then exit.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
	exit;
}

//write uninstallation code here.

Adding Hooks

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-your-plugin-slug.php. More specifically, inside the Your_Plugin_Slug class, within two methods:

  • define_public_hooks() when adding a hook that is used on the front-end for public.
  • define_admin_hooks() when adding a hook that is used on the back-end for admins.

Instead of using add_action() or add_filter() as usual, you’ll need to do things slightly differently. Here is how you add an action.

$this->loader->add_action( 'init', $plugin_public, 'display_message' );

Here we have a loader class Class Your_Plugin_Slug_Loader that automatically adds actions and filters for us.
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 callback 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.

Both folders contain cssjs 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 display_message function to inti hook 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 Your_Plugin_Slug_Public class which is in the public folder. Simply create this function within the class and write everything else as required.

Resources And Dependencies:
You can add other resources and dependencies in includes folder, admin or public folder depending on the use of that resource.

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!

Cheers!

  • plugin-boiler-plate-overview
  • plugin-boiler-plate-admin-overview
  • plugin-boiler-plate-includes-overview
  • plugin-boiler-plate-public-overview

And if you have enjoyed this post, feel free to share it or subscribe to my newsletter below.

By Muhammad Faizan Haidar

A self motivated WordPress developer. I have years of experience in WordPress plugins development.

Leave a Reply

Your email address will not be published. Required fields are marked *