How to Bootstrap a WordPress Plugin

Bootstrapping WordPress Plugins

When WordPress fires up one of the steps along the way is looking for and loading plugins. This happens before the current theme is loaded and after most of the core and must-use plugins are loaded and setup. This process can be seen in wp-settings.php.

The gist is that the plugin file is simply loaded with an include. So the main plugin file itself should cause some side effects, but which ones?

I like to only do a few things in the main plugin file:

  1. Stop execution if WordPress isn’t loaded.
  2. Include an other required files that only contain symbol declarations. Just because we’re doing WordPress doesn’t mean we can’t follow PHP best practices.
  3. Add a single function into the plugins_loaded hook that fires after all plugins have been loaded.

So plugin file might look like this:

<?php
/**
 * Plugin Name: Example
 * Plugin URI: https://chrisguitarguy.com/category/wordpress
 * Description: Example Plugin
 */

// stop if WP isn't loaded
!defined('ABSPATH') && exit;

// include any other files or register autoloaders, etc.
require_once __DIR__.'/src/functions.php';

// hook the single function into `plugins_loaded`
add_action('plugins_loaded', 'chrisguitarguy_example_load');

The chrisguitarguy_example_load function is where any other hooks into WordPress will get added.

// in src/functions.php
function chrisguitarguy_example_load()
{
  add_action('init', 'chrisguitarguy_example_register_types');
  // other `add_action` or `add_filter` calls here
}

The advantage of this method is maximum flexibility for the end user and/or developer. Should they only want to use certain pieces of a plugin, they could hook into plugins_loaded themselves early and essentially deactivate the plugins default functionality and use it as they see fit.

// in another plugin

add_action('plugins_loaded', function () {
  remove_action('plugins_loaded', 'chrisguitarguy_example_load');
}, 1); // hook in early

It’s also, to me, quite a bit cleaner to trace execution through the plugin with this method. And also a bit more testable: tests may call the `chrisguitarguy_example_load` function and see if things got hooked in correctly.