Practical WordPress Development

Announcing The WordPress Plugin Boilerplate 2.0

Back in December 2011, I released an initial version of the WordPress Plugin Boilerplate. The purpose of the boilerplate was to provide an easy way to build WordPress plugins.

Specifically, the project featured:

  • File organization
  • Documented code
  • Implementation of the Plugin API
  • Action and Filter Reference

After the feedback that I received upon thisl release, I officially published version 1.0 to GitHub on November 29, 2012. After over a year of various contributions from others and other improvements, I’m proud to release the second version of the WordPress Plugin Boilerplate.

WordPress Plugin Boilerplate

WordPress Plugin Boilerplate Homepage

In order to make the project a bit more accessible to those who are unfamiliar with GitHub, or who are simply looking for a way to download the project’s zip file, the boilerplate now features its own homepage as powered by GitHub Pages.

Of course, that doesn’t really speak much about the changes that are introduced in this version.

This version includes a number of new additions, features, and improvements many of which could not have been made possible without the contributions of others.

Latest Additions

Here’s what you can expect in the latest version of the boilerplate:

  • Disabling the admin menu by default
  • Initializing the attributes
  • Combining the admin_open and admin_close into a single admin view
  • Bringing some of the code up to the WordPress coding standards
  • Added access modifiers for functions
  • Implemented the singleton pattern
  • japh. Merged upstream changes, maintained separation of uninstall functionality
  • mikkelbreum. Restricted scripts and styles to load only on plugin settings page if it is enabled.
  • mikkelbreum. Added the option for a plugin settings page
  • mikkelbreum. Removed the need to customize the URL for wp_enqueue_style and wp_enqueue_scripts
  • mikkelbreum. Corrected action book for register_admin_styles
  • tbwiii. Listed jQuery as a dependency for both JavaScript sources
  • japh. Added an uninstall.php placeholder
  • leewillis77. Improved the way language files are loaded
  • wesbos. Updated the year to 2013


Because the project includes a README that provides detailed instructions on what to expect when using the boilerplate, the plugin actually lives inside of the download.

Once you’ve downloaded the project,

  1. Copy the plugin-boilerplate directory into your wp-content/plugins directory
  2. Navigate to the Plugins dashboard page
  3. Locate the menu item that reads TODO
  4. Click on Activate

Easy, right?

In Development

Of course, the project is always under development and is looking for contributions from others. If you happen to stumble across any bugs, issues, or feature requests, please don’t hesitate to open an issue or create a pull request.

Ultimately, I want this boilerplate to be written by WordPress developers for WordPress developers using the most common best practices and development strategies available.


  1. Paul

    Hi Tom,

    I had a question about the translation function: what’s the purpose of load_textdomain?

  2. Shaimoom Newaz

    You are a WordPress shaman. Thank you.

    • Tom McFarlin

      #LOL I wouldn’t go that far at all, but I appreciate the compliment.

  3. Steven Slack

    Tom, this is so exciting! I love your plugin boilerplate and have been using it on client projects. I love how it is now “more awesome”.

    • Tom McFarlin

      Awesome, Steven – thanks so much.

      There’s gonna be a lot more coming down the pipe in the coming weeks.

  4. Brunner Nathan

    Hey Tom,
    I hope that you will be successful with this second version of your plugin. I wanted to say that you did a great job with Boilerplate 1.0, it was very useful for creating plugins ;)
    I am looking forward the version 2.0.
    Best regards, Brunner Nathan

    • Tom McFarlin

      Thanks a lot, Brunner!

      I’ve got a number of issues open for the Boilerplate already, so I hope to have 2.1 released sooner rather than later, as well.

  5. Per Soderlind

    I really like what you’ve done here. I’m a strong believer of boilerplates for code consistency and the educational aspect for novice developers.

    Any chance for a plugin settings boilerplate based on the Settings API ? :)

    • Tom McFarlin

      The plugin Boilerplate does feature a basic example of how to include an options page; however, it doesn’t go into detail with the Settings API.

      Others have asked for this, but I’ve covered in in depth in a couple places (including some example projects) and have a video course on Tuts+ Premium coming out later this year:

      WordPress Settings Sandbox: A Working Example of the Settings API
      The Complete Guide To The WordPress Settings API

      Hope those help!

      • Sammy

        The tutorials are nice however; the same does not apply to a plugin options page. The steps in the tutorial render nothing when applied to a plugin admin page.

        • Tom McFarlin

          Then this is something that we’ll have to look into improving with future versions of the Boilerplate and its associated documentation :).

  6. Max Leitch

    Thanks for your continued work on this plugin boilerplate. One question…

    I noticed the use of the constructor to setup actions, filters, etc. However, some plugins using a similar instance method for instantiation contain an empty constructor, instead setting up actions, includes, etc through the $instance property (i.e. self::$instance->setup_actions();).

    I’m curious about the pros/cons of doing it your way as opposed to the alternative. Any benefits one way or the other?

    Thanks again!

    • Tom McFarlin

      Right now, the Boilerplate has a relatively simple constructor so it makes sense that we can do everything in a single constructor. If, however, there was to be an excessive amount of actions and filters, then I’d probably create private methods used to setup actions and to setup filters.

      To take it a step further, if one class is setting up a significant amount of each, that may be a code smell indicating that the plugin should be broken up into a set of classes each with their own purpose.

      I don’t know if this really provides you with pros and cons :), but hopefully it’s an explanation as why the Boilerplate is the way it is and how more complex code can be managed.

  7. Phil Derksen

    Tom, thanks a ton for kicking off this project! I plan on using it any new plugins (and rewrites of old ones).

    • Tom McFarlin

      Sure thing, Phil – glad you find it useful :). I actually have some older plugins I need to bring up to this standard as well…

  8. Mathew Porter

    Great post, greatly appreciated as ever Tom. Kudos.

  9. Evaldas Romaškis

    Great work Tom! I have this one question – why plugin activation/deactivation hooks are registered outside the constructor (as they were in v1.0) ?

    • Tom McFarlin

      This is a great question, Evaldas. I’m actually going to cover a detailed answer to this on Tuesday in a full on blog post (giving a link back to this question) so stay tuned and I’ll fill you in then :).

  10. Mark

    Hi Tom,

    Thank you. I just thought this resource and will have a look now. It sounds very exciting.

    I’ve seen some tutorials on nettuts. One of the other wordpress teachers recommends always using PHP’s new 5.3 closures where possible on the hooks. However, wouldn’t that eliminate the purposes of the hooks? I mean, to my understanding you cannot remove a function (via remove_action etc) if you have no handle to it.

    I thought it might be a performance bump but at the expense of accessibility to the code. I may be wrong. Please let me know your angle on this.

    • Tom McFarlin

      I don’t want to step on another author or developers toes, but my rule of thumb is this:

      WordPress says:

      To run WordPress your host just needs a couple of things:

      • PHP version 5.2.4 or greater
      • MySQL version 5.0 or greater

      So I don’t use any particular features that are not available in the base level of PHP.

      Since closures were introduced in 5.3, I don’t use them since there are a number of hosts and platforms that will be using 5.2.4.

      Once 5.3 is universal, then it’s something I’ll look at adopting :).

  11. Steve

    Great article Tom!

    Guess I’ve been doing it wrong. Still pretty new to this as I just taught myself PHP over the last year (after having done no programming at all since college in the lates 80s) to help code some custom plugins for my son’s school PTA web site.

    My plugins are getting HUGE and I’ve split them up into lots of files, each being their own class.

    What’s the proper way to handle really big plugins with lots of files/classes?

    Do I do one singleton class for the main plugin file that mostly sets things up, and then do regular classes, static classes, or singletons as needed for the other classes? For example, if I have one class that is all for handling plugin settings/options, could that also be singleton and called from the main plugin file as well as all the other classes? Not sure exactly how that works. Similarly I have a couple of “helper” classes: one for common input validation functions, and one for database functions. Should those be static or singleton? Other things like my Teachers class and Students class I think would need to remain regular classes since we may need more than one instance at a time.

    Still trying to wrap my head around all of this OOP stuff!

    • Tom McFarlin

      Don’t assume that you’re doing it wrong! There are other ways to do it, you know? Procedural programming, for example. I just tend to favor OOP, but that doesn’t mean I always use it :).

      What’s the proper way to handle really big plugins with lots of files/classes?

      This is where you get into the concepts of low coupling, high cohesion. It’s far too much to really explain in-depth in a comment, but I’ll try to summarize it:

      • Break the program apart into logical components whereas each class is its own component.
      • Each class should represent a single ‘thing’ or noun or a single entity of the program.
      • The functions that belong to each class should be relevant to only what that class is able to do.
      • Classes need to only be aware of other classes on which they depend. They don’t need to know about all of the classes in the program.

      Hopefully this gives a few guidelines to begin refactoring some of the code.

      Do I do one singleton class for the main plugin file that mostly sets things up, and then do regular classes, static classes, or singletons as needed for the other classes?

      This is a good rule of thumb, but I can’t say definitively yes or definitively no because there are always outliers, you know?

      Keep at it with this – sounds like you’re on the right track and you’re moving fast :).

      • Steve

        Thanks for the encouragement Tom!

        Yes, “doing it wrong” was maybe not so accurate. Everything I have programmed so far works, and over this last year of programming and learning as I go, my code has definitely gotten better (and I have to go back and refactor a lot of the older code to make it better).

        I did a little more digging after stumbling across your article last night, and it seems that the whole Singleton (or singleton) thing is very hotly debated. So, I guess there really is no “right” or “wrong” with regards to that… just depends on which side of those arguments you land on.

        I think my biggest thing to still figure out is how to divide up my classes even more to be more cohesive, and figure out how to do the coupling between classes so I’m not constantly having to create several “new” objects in each class to get what I need from the other classes.

        Right now, my classes are each pretty big, and are closer to being their own plugins rather than a tight and cohesive class. For example, my Students class does more than just create, edit, and delete students. It also handles the student directory, and admin plus parent related student functions, although I do have the database functions to create, edit, and delete objects split out to its own glass and made generic enough that they work for either the student objects or teacher objects.

        Thanks again for this great resource and all your educational work! I’ve got a lot to learn still, but am making good progress, and at least our new PTA site is up and running this year. So far, everything is working great!

  12. Andreas

    Hi guys,

    I´m currently struggeling with the question where (which file/folder) to put what part of my code like:
    – Register a custom post type/ taxonomy
    – Rendering metaboxes
    – Saving data entered at post edit screen
    – Adding contextual help
    Can you please give me some advice or even better provide some example plugins based on the boilerplate where I can learn from?

    Best regards, Andreas

    • Tom

      Hey Andrea — all of this will be better answered in the upcoming version of the Boilerplate, so sit tight while we work on getting that in place! :)

  13. Ramazan Recber

    I later learned that I did not know what to do plug-in settings give you many thanks for the information

    • Tom

      That’s awesome — glad to help :).

  14. Jerry Russell

    I downloaded the plugin and installed it as directed, but the plugin does not show in the list of plugins, so I can’t activate it. Any ideas?

    • Tom

      Hey Jerry,

      First, make sure that you’re up to date with the most recent version of the Boilerplate.

      Next, be sure to read the README file that ships with the plugin as it walks you through everything you need to know on how to set up the plugin!

Leave a Reply

© 2020 Tom McFarlin

Theme by Anders NorenUp ↑