How to Start Your Next Modern WordPress Plugin

In this issue, I’m going to walk through how to structure the main plugin file for a modern WordPress plugin.

When I say modern, I mean a plugin that utilizes Composer for autoloading files and Object Oriented PHP.

The primary function of the main plugin file is to initialize and load the rest of the plugin.

Unfortunately, there is no standard structure for the main plugin file

Without an efficient structure for the primary file in a WordPress plugin:

  • Included files can be loaded at the wrong time
  • Unnecessary code runs during every user request
  • Conflicts with other plugins occur more frequently

I’ve been creating several plugins lately and I’ve settled on a common structure that solves each of those issues.

I shared my method on X recently and lots of others had similar thoughts.

Here’s how it works, in three parts:

Initialize & Include Composer’s Autoloader

I’ve written about composer before, so if you need to catch up you can review that in ​one of my previous issues​.

Once you have composer configured and you’ve initialized your namespace and autoloader, you can include it directly in your plugin file.

When WordPress loads your plugin file, it’ll include the autoloader.

As long as you’re file is not referencing anything in the global scope, the autoloader won’t do anything except require what it needs.

However, when you do use it, it’s ​incredibly powerful and speeds up your development immensely​.

Note: Some of you will suggest adding the autoloader within the function where the class is called. I’ll admit, there is some unnecessary processing here, however, it’s not enough to worry about.

Boot Your Plugin At The Right Time

Each time WordPress handles a request, you want your plugin to hook in at exactly the right time.

If you hook in too early, WordPress will not have loaded everything your plugin needs.

If you boot your plugin too late, you’ll try to register other hooks and they won’t be called as they may have already been fired.

The hook that you should use is the plugins_loaded action which is fired off after WordPress is fully loaded.

All the active plugins are also loaded so you can be sure that your dependencies are available.

You can see in this diagram (edited to highlight significance) from ​Rarst​ that the plugins_loaded action is fired just a few steps before init.

This makes it a great place to load your plugin.

The init action is where you will probably hook to initialize additional features depending on what your plugin does.

Using the init hook, you can register everything necessary for your plugin, like instantiating your Core class and setting up additional hooks as you need to.

Hand Off Everything to A Core Class

With Object Oriented Programming, there’s a rule called the ​Single Responsibility Principle​ which states:

“every class, module, or function in a program should have one responsibility/purpose in a program.”

When your plugin is loaded by WordPress, it’s always good to have a Core class that is responsible for booting up other necessary objects.

You can ultimately name this class whatever you’d like to, but you’ll still need some class that owns the responsibility of booting and registering things.

It’s sole purpose is to load in dependencies when they are required and register hooks that are attached to unique class methods.

With a Core class, you guarantee that your code is only loaded during specific hooks in WordPress and can maintain an Object Oriented approach.

You maintain control of when and how code is executed within your plugin.

In Summary

When creating a plugin, it’s important that you load your plugin through the main plugin file in a responsible way.

You should load it when all necessary resources have been initialized, but before important hooks, like init, are fired.

When you have an autoloader and instantiate a core class within a hooked function:

  • you keep your plugin file small
  • you reduce unnecessary processing
  • prevent conflicts with other plugins.

It’s really the best way that I’ve found to begin any new modern WordPress plugin that I’m working on.