A WordPress Plugin Bootstrap File

The longer I work with building custom solutions for others in the form of WordPress plugins, the more I am a fan of having a WordPress plugin bootstrap file.

Honestly, this isn’t anything new, but it’s something I like to discuss periodically because the methods in which we build plugins, the ways posts can become outdated, and the strategies that we employ as we get better at what we do for a living change over time.

At least I hope they do. If you’re doing the same thing now that you were three or four years ago, then you’re a stellar developer. Or you haven’t grown that much. :)

But that’s content for another post.

When it comes to the work I do for others, the work is primarily in the creating plugins (which I enjoy building). So it’s only natural that I’d have things to add continually to this topic, right?

WordPress Plugin Bootstrap File

I know that it’s a trendy thing right now to have boilerplate code for everything. And it’s also becoming fun to hate on this stuff.

That’s the nature of the Internet, I suppose.

But this isn’t about boilerplate code. Instead, this post is about a bootstrap file, and I want to make sure that’s clear before moving any further in the post. And for those who are curious, bootstrapping has been around for a long time in the world of computing.

The Purpose of the Bootstrap

With that said, here’s how I view the purpose of a WordPress plugin bootstrap file:

  1. Define any necessary DocBlocks,
  2. Set the plugin header,
  3. Make sure the plugin file can’t be accessed directly,
  4. Include any necessary dependencies (though this may be achieved differently based on the version of PHP you’re using),
  5. Start the plugin.

But walking through the steps only goes so far, so I’ll share an example of how I tend to structure my bootstrap files. And I’ll add some notes on how this may change depending on the work you’re doing.

A Template for a Bootstrap

Generally speaking, here’s how I structure my plugin bootstrap files:

This particular structure adheres to the WordPress Coding Standards and also uses a custom tag, namely @wordpress-plugin@wordpress-plugin to delineate between the documentation and the content that WordPress reads when displaying the plugin in the administration screen.

Secondly, I always name this file the same name as the plugin as per the file naming conventions for WordPress plugins. So within the plugin directory, this is what you’re likely to see:

The WordPress Plugin Bootstrap File

First, the file is accessed. Then, it follows all of the steps I’ve outlined and creates an instance of the plugin.

Why Instantiate the Plugin This Way?

Though WordPress affords us the ability to write out plugins in both procedural programming and object-oriented programming, I’m a fan of the latter. Thus, I define a function that instantiates the plugin and then the lifecycle calls the function at the end of the file.

This doesn’t interfere with the $GLOBALS collection, this doesn’t require we add the plugin to any particular hook, and it doesn’t require that the plugin is dependent on any other third-party aspect of PHP or WordPress.

To be clear, this doesn’t mean that it can’t be dependent upon it. In fact, I’ve found this approach to be one of the most flexible.

For example:

  • If I wanted to hook the instantiation of the plugin into a hook, then I could add the function definition to one of WordPress’ hooks.
  • Similarly, if I want to instantiate the plugin in another area of WordPress, I can do that by just removing the function. You would then need to add the plugin file in some other way, but it’s still possible.
  • Keeping code separate from dependencies makes it easier to unit test (though it’s easy enough to unit test WordPress plugins through the use of WP-CLI).

That said, there are still other ways in which you may go about bootstrapping your WordPress plugin, and I’m all for hearing what other options there are.

This particular strategy has worked well for me for the last few years and its one that I’ve iterated on, more of less, to make it as consistent as possible.

11 Replies to “A WordPress Plugin Bootstrap File”

  1. Hey Tom,

    That’s a very interesting topic, and one where I have not yet quite come up with a definitive approach for my own projects. Somehow, each project seems to end up with a different approach that I’m testing.

    Most of the time, my bootstrapping file is the “WordPress-specific” bootstrapping file, which makes sure that, when run through WordPress, the plugin knows where to fetch its configuration data. In the same way, I have different bootstrapping files for testing, for CLI usage, etc… (a bit like preparing the plugin to be used as different ports within a hexagonal architecture).

    I would like to know why you choose to add a function to your bootstrap file. In the article, you explain like this would be a consequence of going the OOP-route, which I don’t think makes sense.

    So, what would be the benefit of the function in lines 44-50, compared to just having a single line, like:

    new Demo_Plugin()->run();

    As I see it, the function has two disadvantages:

    Adds a function to the global namespace (you didn’t set a namespace within the bootstrap file), so potential for naming conflict.
    Adds function call overheard. I know that this overhead is insignificant, but what is the advantage that would justify it?

    Would love to hear more about the reasoning behind these decisions!

    Cheers,

    Alain

    1. Most of the time, my bootstrapping file is the “WordPress-specific” bootstrapping file, which makes sure that, when run through WordPress, the plugin knows where to fetch its configuration data.

      This sounds cool and I’m pretty sure I have an idea as to how it’s structured. Got a gist for it or anything? I’d like to see if for no other reason to improve my own :).

      I would like to know why you choose to add a function to your bootstrap file. In the article, you explain like this would be a consequence of going the OOP-route, which I don’t think makes sense.

      Sure! But to be clear, I don’t always add it to this file. Sometimes it’s added in the context of another file, another project, or when a third-party utility needs to invoke it.

      In terms of OOP, this function could be called and then return the reference to the plugin so it can be used elsewhere. The rest of the reasons are listed above.

      The reason I dislike the single line is mainly because there’s no way to maintain an existing reference to the instance of the plugin (if it’s needed) and I generally don’t like doing the new Object()->run(). I’d rather grab an instance and then determine what to do with it after that.

      Adds a function to the global namespace (you didn’t set a namespace within the bootstrap file), so potential for naming conflict.

      Yes but that’s also why I went with the procedural route of trying to include a prefix. If the version of PHP on the server supports namespaces, definitely use it.

      Adds function call overheard. I know that this overhead is insignificant, but what is the advantage that would justify it?

      It just sets the plugin in motion and allows it to be hooked, if needed. I don’t worry about performance for something like this (as you mentioned, too :).

      Eager to hear your thoughts, too!

      1. This sounds cool and I’m pretty sure I have an idea as to how it’s structured. Got a gist for it or anything?

        Here you go: https://gist.github.com/schlessera/5738bde230112bcddaea422ad1a29951

        In order to get a reference to an object after having it instantiated, it mostly depends on the scale of the project.

        For a small plugin, I use a static instance variable if necessary (not a true singleton, only a “singleton by convention”).

        For larger projects, where there’s lots of business logic involved, I use a combination of a service locator for large, cohesive modules, and an auto-wiring dependency injector at the individual object level. I use Pimple as an SL and Auryn as a DI.

        1. Here you go:

          This was awesome – really enjoyed reading through the code and going through some of the other things you linked (like the Config, etc.)

          Thanks for that. Filing this away for reference in the future :).

          For a small plugin, I use a static instance variable if necessary (not a true singleton, only a “singleton by convention”).

          Yep. Totally with you on this one.

          For larger projects, where there’s lots of business logic involved, I use a combination of a service locator for large, cohesive modules, and an auto-wiring dependency injector at the individual object level. I use Pimple as an SL and Auryn as a DI.

          I’ve typically used DI but I haven’t used any thing else like Pimple or Auryn as I’ve not yet worked on a plugin that was that large (or perhaps I have and just haven’t used those thools to help me out ;).

          Regardless, I’m definitely a fan of dependency injection no matter how it’s done.

  2. I’m doing something similar. The only thing I’m doing that you aren’t is delaying the call to “acme_demo_plugin();”. Instead of calling it right away, I hook it to the “plugins_loaded” hook so that it looks like “add_action(‘plugins_loaded’, ‘acme_demo_plugin’);”

    This lets you add hooks in your init process. Otherwise, other plugins need to hack around the plugin load order if they want to use a hood. :)

    1. Instead of calling it right away, I hook it to the “plugins_loaded” hook so that it looks like “add_action(‘plugins_loaded’, ‘acme_demo_plugin’);”

      I used to do this but then there were a few plugins I wrote that needed to be hooked earlier in the lifecycle or needed to have priority changed, so I just left it out for the purposes of this raw example.

      What you’ve provided is still spot on accurate, IMHO.

      This lets you add hooks in your init process. Otherwise, other plugins need to hack around the plugin load order if they want to use a hood. :)

      Yes! Based on Alain and your comments, I think I should’ve made that clearer in the post. At least we have comments to clarify this stuff :).

    1. I almost linked to this because I’m the original author of the Boilerplate. I gave it to Devin some time ago.

      But remember that the Boilerplate has a completely different purpose and rationale and it’s completely different than a bootstrap file :).

  3. I think we should have different types of bootstrap plugin file.

    In my library also have a starter WordPress plugin which included CMB2 framework as well. What about you? Which framework you should consider to include for rich-feature plugin?

    1. I think we should have different types of bootstrap plugin file.

      Definitely. I don’t think this is a one-size-fits-all solution, but it’s something with which to get started. Alain has another good option and there are others as well.

      In my library also have a starter WordPress plugin which included CMB2 framework as well. What about you? Which framework you should consider to include for rich-feature plugin?

      I don’t really use any frameworks right now. Most of the work that I do is custom so it’s based on the needs of the job.

  4. Hi Tom,

    my approach is similar, I use the main file for doing some compatibility check and then I load another file for bootstrapping the plugin classes with DI (DI is awesome :-)), in the main file I also have 2 hooks for allowing other plugins hook it and an array filtered for adding directly files to load with require.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.