A few years ago, I started the WordPress Plugin Boilerplate project as nothing more than a GitHub repository used to store code that I found myself frequently using in both personal and client projects.

As I became more involved with WordPress, as I began to build more plugins for fun and profit, and as I began updating the repository, it grew into something a little more than I had expected.

Over time, people began to open issues, offer pull requests, perform code reviews, and create their own forks of the project. I learned a lot over the next few years, and I honestly couldn’t be more excited to see such a little project become, you know, such a slightly less little project.

Months ago, I mentioned that work on the next iteration of the WordPress Plugin Boilerplate was started and I’m excited to announce that, as of today, the WordPress Plugin Boilerplate 3.0.0 is officially ready for use.

And it comes with a lot of new and neat things to boot.

An All New WordPress Plugin Boilerplate

As of this version, there are a number of new things and major changes all of which I’m excited to share (though I know we’ve all got limited time to so I’m going to keep this as brief as possible).

The Homepage

The WordPress Plugin Boilerplate Homepage

The WordPress Plugin Boilerplate Homepage

First, the project now has an official homepage. This is the first step to making the project more accessible to those who are just jumping into the foray of writing WordPress plugins.

There are more plans for the site: I’d love to create an area for documentation, frequently asked questions, perhaps a community forum, and more. I certainly don’t plan on leaving it as a single page for long – but this is the first step.

A Total Rewrite

As mentioned throughout several previous blog posts, the Boilerplate underwent a complete rewrite. This means the project started at ground zero and was built upwards from there.

So what does this look like?

The WordPress Plugin Boilerplate Directory Structure

The WordPress Plugin Boilerplate Directory Structure

As you can see, the project itself includes its own README and ChangeLog and then the rest of the project is broken down into two directories:

  1. assets
  2. trunk

For anyone who as submitted a plugin to the WordPress plugin repository, then you’re familiar with the standard Subversion directory structure. The Boilerplate now mimics that.

The assets directory contains placeholders for plugin headers, plugin icons (which are a new addition coming in WordPress 4.0), and a screenshot that corresponds to the contents of the plugin’s readme.txt.

The trunk contains the actual Boilerplate source code. This is a functioning plugin that can be installed and run within WordPress all of which I talk more about momentarily.

The directory structure of trunk has changed a bit since this previous version of the Boilerplate. Ultimately, the goal was to create better file organization, a better class architecture, and generally a more organized approach to working with plugins.

  • admin is used for all dashboard-specific functionality
  • includes is used for all shared functionality either as part of the core of the plugin or for a third-party library
  • languages are where the i18n files are kept
  • public is where all public-facing functionality is kept

Naturally, there are subdirectories to each of these directories, as well; however, rather than spend time going through each and every file, you can read the comments contained in each one to get an idea as to how they all work together.

This means that the Boilerplate no longer uses the TODO placeholders. Instead, the comment blocks explain exactly what’s going on and are left for you to change the content during implementation of your work.

The Loader

There are a number of classes that are located in the includes directory such as the activator, deactivator, and more. But the newest addition to the project is The Loader (in context of the Boilerplate, this class is called Plugin_Name_Loader.)

The goal of this file is to encapsulate the registration of hooks and then execute both actions and filters at the appropriate time when the plugin is loaded.

Based on the feedback I’ve gotten, this particular class is the one thing that’s resulted in people asking the most questions, sharing that they aren’t sure how they feel about, sharing that they dislike it, and sharing that they love it.

Such is the nature of programming.

Regardless, this helps to easily manage hooks throughout the plugin as you’re working on your code, and you can trust that everything will be registered with WordPress just as you would expect.

Up To Standards

One of the things that I think we should all be doing is adhering to the WordPress Coding Standards and the Inline Documentation Standards. To that end, the Boilerplate has come done the best possible job at attempting to adhere to both of those.

If you find something that needs changing or think something needs to be removed, issue a pull requests, I’ll review, and I’ll be happy to merge.

Ultimately, the point is to get more people using the standards as defined in the Codex to write more WordPress-specific and maintainable code.

Credits

Projects like this are rarely done alone and this is no exception.

The latest version of the Boilerplate would not have been possible were it not for Josh Eaton, Ulrich Pogson, and Brad Vincent.

WordPress Boilerplate Plugin Slack

Their opinions, contributions, and overall backing in this project helped drive it to the point that it is today.

Notice also that the project has its own branding including colors and a logo. I have Rob McCaskill of BungaWeb to thank for lending his talents on creating the Boilerplate. I basically said that I was interested in something that was steampunk, vintage Americana, and a bit more modern and he delivered.

Mickey Kay is also responsible for creating a small set of icons one of which is used as the plugin’s favicon.

WordPress Plugin Boilerplate Merges

WordPress Plugin Boilerplate Merges

And, naturally, I thank everyone who has opened issues, contributed pull requests, and helped out in whatever capacity.

Yes, there’s still a lot that I want to do around this project, but I’m really excited to start fresh, to see where this goes, and to continue building out the Boilerplate in order to make it the best place to start building plugins for those who are just getting into object-oriented WordPress plugin development.

Category:
Projects
Tags:

Join the conversation! 77 Comments

  1. Hey Tom, nice to read that!

    Are you planning some sort of builder or code generator?

    Thanks again!

  2. “First, the project now has an official homepage. This is the first step to making the project more accessible to those who are just jumping into the foray of writing WordPress plugins.”

    I guess I missed it, but it would be even more accessible with a download link…

    :o)

    • Tony – :facepalm: – you’re right. My bad :).

      I did the usual and just made the assumption people would just from the page to repository. I’ll have that download link hooked up soon!

  3. Congrats, man. #EPIC as usual. :)

  4. Tom, great job! Really looking forward to seeing this project grow even further than it already has. For those that have questions regarding the structure of the plugin and especially the loader, I suggest reading Tom’s articles on Tutsplus on Object Oriented Programming in WordPress. There is a plugin example which has the loader explained in detail: http://code.tutsplus.com/tutorials/object-oriented-programming-in-wordpress-an-introduction–cms-19916

  5. Excellent work again Tom! Thanks for leading the charge with this and your timing could not be better for me :)

    Jeremiah

  6. Just in time… we are developing our first “theme” functionality plugin and have added to our programmer’s todolist to incorporate this structure and best practices… thanks!

    Patrick
    @churchbuzz

  7. Nice work Tom, truly Awesome man!
    I look forward to having a dig!
    Benbodhi

  8. thanks for leading this project and seeing it through to its current state Tom.

  9. Hey Tom,
    Nice effort. The logo illustration is cool.

  10. Great work, thanks! Are there any reason why my contribution to uninstall.php didnt make it into v3.0 (https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate/pull/172)
    best,
    Robert

  11. Tom it was great working with you on this project, best of luck in the next phase of Boilerplate. We are here at #bungaweb to help.

  12. Great work this. Going to take it for a spin this week sometime!

  13. Tom, this is great. I’m an experienced LAMP developer who is new to WP and building my first plugin. I have held off a bit, waiting for your v3.0 template. There’s a bit of a problem, though: Your template seems to have no definition for the class Plugin_Name_Admin, such as in

    $plugin_admin = new Plugin_Name_Admin( $this->get_plugin_name(), $this->get_version() );

    I could define it myself, but it would surely be less than you intended. Am I missing something?

  14. I created a little generator for your fantastic boilerplate. It copies the master.zip from github to your own server, extracts it, replaces all instances of Plugin_Name with a proper plugin name. Finally it cleans up the comment blocks, renames all files, creates a zip file and provides a download link.

    Maybe this could be something for the new wpbp.io. Interested?

    Greetings from germany

  15. Simple question, but since there isn’t any documentation yet I figured I’d better ask =P. If I’m registering a custom post type, would that be registered as an admin action? Or a public action? Thanks!

    • If you’re registering a custom post type, then the registration of the post type would go in the includes directory. Any specific functionality related to say, meta boxes, would be in admin and then any public facing functionality, styles, scripts, and so on would reside in public :).

  16. Thank you for the plugin Boilerplate and the dedication. Will be using it in my project.

  17. Hi! Not here, not anywhere else did I find instructions on what and how to replace so that the plugin is correctly named. Could you kindly explain?

    • This is coming as soon as possible in the form of documentation on the WordPress Plugin Boilerplate site. Right now, we’re slated to start working on the docs by January.

    • It is as Tom mentioned earlier. You will have to just do a search and replace for “Plugin_name” in each file and replace that with your plugin name. Just ensure that (let’s use your first name as an example):
      1) When replacing “Plugin_name” it should say “Anton”.
      2) When replacing “plugin_name” it should say “anton”.

      Cheers!

    • Thanks for the quick replies. However, I’m not sure about the following:

      What about the files? Should I replace “plugin-name” in some file names too? Obviously, the main file needs to be renamed, but there are many others. And if I do rename them, do I need to also replace this text in some of the files? I suspect failing to do that would likely break the plugin.
      If I just blindly replace all occurrences of “plugin_name” with “anton”, then that would also effect property and variable names, like, for example, private $plugin_name in Plugin_Name_Public.

      • Anton,
        You are welcome! In regards to your question, you are correct. For instance, if you go to the file called “class-plugin-name-public.php” you would need to first change the file name to “class-anton-public.php” then in the file, you will see a code for a class in which it says “class Plugin_Name_Public” and it would need to be changed to “class Anton_Public”. For the most part, all instances of “Plugin_name” or “plugin_name” will need to be changed, but there is ONE place you do not. If you go to “class-plugin-name.php” in the folder called “includes”, there is one function on line 202 that says “public function get_plugin_name() {” this is one place you do NOT replace “plugin_name” to “anton”.

        I hope this helps. :)

  18. Aaron,
    Thank you for your advice. However, are you saying that properties and variables also need to be replaced?

    • No, don’t change the properties. For example, in “class-plugin-name.php” you will see on line 71 that says “$this->plugin_name = ‘plugin-name’;” you do not change the property, but only the value so it wold say “$this->plugin_name = ‘anton’;”

  19. Thank you and forgive me if I’m being anal. I’m just trying to understand whether it is safe to run a search-and-replace on the repo to get everything in order. Apparently, it’s not.

    Tom, maybe you would consider renaming “plugin_name” to, for example, “pluginname”, so that we just do the following global replacement?

    'Plugin_Name' -> 'My_Plugin'
    'plugin-name' -> 'my-plugin'
    'pluginnane'-> 'my_plugin'

    I’m just trying to find out if there’s a way to take a couple of steps and be sure that everything is in order. Thank you all for your help. =)

    • All you have to do really is change the file names and the file names in the code as well as the classes and functions, but not the variables themselves. Do you want me to give you a zipped file with the plugin renamed to whatever you want it so you can better understand where all the instances of (P/p)lugin_name should be replaced?

    • Thank you and forgive me if I’m being anal. I’m just trying to understand whether it is safe to run a search-and-replace on the repo to get everything in order. Apparently, it’s not.

      You’re not being anal, you’re being thorough :).

      Anyway, I can’t recommend running a search and replace because there are a few tokens where, say, Plugin_Name is appending or prepended to other variables, class names, and so on. If you end up doing that, then you may lose out on understanding how things fit together — at least at first.

      Hopefully, documentation will help mitigate this.

      • Tom, thank you for your help and for your effort. However, I think this situation can be easily fixed by replacing Plugin_Name with, for example, My_Pugin in the cases where future replacement would need to be done in order to get started with the boilerplate. Then, no need for a custom generator, the logic of which will also have to change every time you use Plugin_Name again.

  20. So I was looking around and I saw a comment that says the following:

    An instance of this class should be passed to the run() function defined in Plugin_Name_Public_Loader as all of the hooks are defined in that particular class.

    However, I failed to find class Plugin_Name_Public_Loader anywhere. Am I missing something?

    • The keyword here is ‘should’ as this is just telling you if you create an instance of the class with a name of Plugin_Name_Public_Loader that it must be passed to the run() function.

    • Aaron,

      I’m quite confused now. As I understand this comment, which appears in class Plugin_Name_Public, I must pass the instance of Plugin_Name_Public (“this class”) to the run() method that belongs to (is “defined in”) some Plugin_Name_Public_Loader class. If, on the other hand, what you are saying is true, then I am not sure why I would create a class called Anton_Public_Loader, since, as I understood, the loading functionality is part of the boilerplate, and my classes should be called something like Anton_Gym_Listing_Post or Anton_PayPal_Api.

      Regarding your offer to send an archive, there’s no need. I will probably find exactly what I need and need not rename. My only issue is that I was hoping it could be done by performing a few steps that can be simply automated. Consider the Advanced Custom Field Template class; it’s documentation leaves me confident that just by performing 2 steps, most of which can be achieved by simple find-and-replace, my custom field plugin will be made into what I expect, without having to manually go through each file and fixing things, or worrying that I may have replaced something wrong.

      Please don’t take this the wrong way. I am not saying that my expectations are right, or that the boilerplate should be as I think it should be. Just trying to point out that what the developer must go through in order to start using it is very inconvenient and does not leave one confident of the results.

      Thanks again for your help.

      • Anton,
        I understand how you feel, but keep in mind this project is fairly new to the public and Tom as well as other contributors are working on creating a documentation. Tom is also going to include the fantastic generator Andre made to help plugin developers replace all instances of “P/plugin-name” with just one click.

        • Thanks for mentioning. Seems that the generator could indeed be pretty usefull for some people. But to be honest, I wrote it just because of my own lazyness ;-) And I of course stumbled over the problem with simply replacing all instances of P/plugin_name, too. I overcome it by first replace all and change the appropriate lines back after that.

          Greetings from Germany. Would be proud to be a part of this.

      • Consider the Advanced Custom Field Template class; it’s documentation leaves me confident that just by performing 2 steps, most of which can be achieved by simple find-and-replace, my custom field plugin will be made into what I expect, without having to manually go through each file and fixing things, or worrying that I may have replaced something wrong.

        This is the mark of good documentation for existing software.

        Remember though, the Boilerplate itself isn’t itself a plugin or a piece of software that’s meant to be simply customized. Instead, it’s a foundation off of which plugins should be based.

        The purpose isn’t to provide a set of classes that you can perform a few find/replaces on and then have a working plugin. It’s meant to be a set of files that need to have things customized for your plugin, and then have other features added (such as custom post types, taxonomies, scripts, styles, etc.), and others stripped away (like the example files).

        Just trying to point out that what the developer must go through in order to start using it is very inconvenient and does not leave one confident of the results.

        I’m not taking anything as offensive or wrong, though I appreciate the sentiment. I’m also just trying to clarify what the Boilerplate should be: A foundation for writing WordPress plugins using both WordPress and object-oriented best practices.

        Sure, there needs to be additional documentation added to go along with this and example code can go a long way — I want to be able to provide that. But, unlike other premium plugins such as ACF, the Boilerplate is a project that’s freely available so I have to work on it when I have the time :).

        I appreciate all the feedback and want to continue making it as strong as possible, but it’s going to take some time for all of that information to accumulate.

  21. Thanks Tom, great resource, just started to get hands on with the development of a plugin, a god send that I found your boilerplate to save me time and get my head around things.

  22. Tom, thanks for your great effort! I would use this as my new WordPress plugin foundation and see what i can do with this, cheers.

  23. Has anyone got a plugin developed on the WordPress Plugin Boilerplate 3? An example plugin would be awesome for newbies to learn off of. :)

  24. Gah I posted this at wptavern just now – wrong browser tab! Apologies for repeated posting for any who subscribe to both!

    I wanted to say thanks to Tom for the leg up! We are trying to improve the way we implement plugins and this is a great learning resource.

    One question – what is the most appropriate way to implement template tags (methods called in the theme)?

    Currently we have a template-tags.php which we include in the load_dependencies method in the main plugin file. We were unsure whether the intent of Boilerplate was to have all these methods in the plugin_public.php. I note that Custom Field Suite uses a public method to return a singleton instance to the controller so you can call CFS()->method_name()

    What’s considered best practice here?

    • One question – what is the most appropriate way to implement template tags (methods called in the theme)?

      The short answer is that these would need to be public methods that are exposed in a class in the public directory such that the template would be able to:

      1. Grab the current instance of the plugin (which can be achieved in a number of ways)
      2. Make a call to said instance functions

      We were unsure whether the intent of Boilerplate was to have all these methods in the plugin_public.php

      Maybe. If it makes the class too large, I’d say you need separate classes each with their own set of responsibilities and then have a way to access them.

      I note that Custom Field Suite uses a public method to return a singleton instance to the controller so you can call CFS()->method_name()

      This is one strategy, it’s common, it’s worked well, and I’ve used it before. Another would be to place the class in some type of container or collection from which you could retrieve it at run time.

      Each has its own advantages and disadvantages, so I don’t have a recommendation as to what is the best practice. Someone else may have a good opinion; however, I always try to lean in the direction of whatever makes the code the most readable and the most maintainable.

      • Another would be to place the class in some type of container or collection from which you could retrieve it at run time.

        Thanks for the suggestions. Do you perchance have a quick example of how that might look?

        • Unfortunately, off the top of my head, I do not.

          At a high-level, this could be a class that implements the singleton pattern, has a hash table, an array, or a generic collection of objects that are keyed by their name. It could then have a get method that would accept a key a return to you the instance it has stored.

          Hope this helps!

  25. It would be great to have cookbook style tutorials for Post Type, Shortcodes, Quicktags, oEmbed, Admin Bar.

  26. I would like to ask a question about a post original posted by Andre, from Germany. He posted:

    “I created a little generator for your fantastic boilerplate. It copies the master.zip from github to your own server, extracts it, replaces all instances of Plugin_Name with a proper plugin name. Finally it cleans up the comment blocks, renames all files, creates a zip file and provides a download link.

    Maybe this could be something for the new wpbp.io. Interested?

    Greetings from germany”

    I would like to ask if this has been sorted out yet, or could I have access to his generator because I am having some issues with the comments at the top of my files. For some reason there are 2 separate header comments at the top of most files, apart from the main plugin.php file.

    Or are there supposed to be 2 different comment blocks at the top of each file? This is the first time I have attempted to write a plugin and I figured the new boilerplate would be a great place to start, but I have spent hours searching the internet for the proper coding standards or header comments standards and I am becoming more confused.

    A little guidance would be greatly appreciated, or if someone could tell me where I can access the generator developed by Andre from Germany.

    Thanks Guys :-)

    • Hey Jack,

      Great question! Though I don’t maintain the Boilerplate anymore (as it’s been handed over to Devin Vinson), I can tell you that the comments at the top of the file are for the WordPress Coding Standards.

      You can read more about them in the link above or you can check out another generator here. It’s not written by Andre, but it works pretty well with the Boilerplate as it stands today.

  27. Love the plugin Tom, great work :) Really helps get a new plugin off to the right start! Much appreciated, go to boilerplate of choice for new plugins :)

Leave a Reply

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