WordPress Plugin Boilerplate

A few months ago, I released my WordPress Widget Boilerplate. Since then, it’s received several contributions from the community that’s made it a solid resource off of which to begin building WordPress Widgets.

In that same post, I mentioned that I was working on a boilerplate for plugins but had yet to finish it; however, today – with a little help of a few contributors that have already been watching the repository – I’m releasing the WordPress Plugin Boilerplate.

WordPress Plugin Boilerplate

Similar to the Widget Boilerplate, the WordPress Plugin Boilerplate includes the following features:

  • File Organization. The Boilerplate ships with both JavaScript sources and stylesheets for both the administrator and the client-side views. It provides a basic localization file to make it easy to localize the plugin. It also includes a stubbed out README that follows WordPress conventions.
  • Documented Code. Each file of the plugin and each method of the core code is clearly documented for its purpose in the overall plugin. Additionally, the core code includes various TODO’s to make it easy for your IDE to locate everything you need to populate when working on your plugin.
  • API Implementation. The Boilerplate is based on the WordPress API in order to enforce best practices when building on top of the WordPress platform. This makes it easy to develop conventional, familiar code and makes it easy to compare your work with the recommendations of the Codex.
  • Action and Filter References. One of the challenges of working with plugins is managing actions and filters. The Boilerplate includes references to all WordPress documentation of both and already includes two templates for both actions and filters.
You can check out the project on GitHub. Feel free to watch, fork, and/or contribute – I’d love for this to become a solid boilerplate for plugin development.

30 Comments

Thx for that boilerplate.

I just red a post about plugin development. They suggest to use a uninstall.php file to clear up after unstalling. (http://wp.tutsplus.com/tutorials/7-simple-rules-wordpress-plugin-development-best-practices/)

That file don’t fit for every plugins but it could be good for some.

This looks entirely awesome! Massive thanks for such a useful resource.

    Thanks so much for the comment. As far as what’ll go into the boilerplate, here’s what will, what won’t, and why:

    1. Most likely not. This isn’t something that includes work with the Settings API which is something that developers may often have to strip out in order to get a plugin going. I have an example for the Settings API already, but my goal for the boilerplate is to make a foundation off of which to build. The less to take away, the better.
    2. Yes. At the very least, the next version will include adding constants for versioning to make caching busting of JavaScript and stylesheets much easier.
    3. Not sure yet. There’s been some talk about it and I think there’s benefit, but it really depends on the functionality of the files being loaded. We’re already doing that some in the Widget Boilerplate for the views.

    Hopefully this answers your questions and gives a reasoning for my stance on certain things. I take all of the suggestions seriously so always appreciate the feedback.

      Thank you very much for you reply.

      1. Could you tell me how I should load the files to get this to work?
      https://github.com/tommcfarlin/WordPress-Settings-Sandbox
      2. Great
      3. There would not need to be alot of functionality if any just so that I can see how it should be loaded properly.

        1. You can just download the zip file and then install the theme in WordPress. That should do it (assuming that’s what you’re asking :)).
        2. :)
        3. Generally speaking, it’d just be a call to an include_once call, but the next version should take care of this as it’s going to demonstrate how to pull in an uninstall.php file.

          1. I have messed around with the settings in theme but was looking to integrate them in a plugin.
          3. Look forward to it.

          I working on a plugin and want to work along the best practices.

            The Settings API isn’t really any different than what occurs in a theme.

            You’d just need to adapt the various books for the menus, options, sections, settings, and fields that you see in the theme sandbox into a plugin.

            If you’re building your plugin with OOP practices, then the hooks will be registered in the constructor and the functions implemented as public functions in the class.

            Hope this helps!

I’ve been playing with custom themes for a few months now, and this is my first attempt at a plugin. Thanks for the boilerplate as a great starting point.

However, I’m stuck trying to add a shortcode to the plugin. I’ve been following another tutorial, plus reading a plugin dev book, but my code isn’t working correctly.

Do you have an example of how to add a simple shortcode to a plugin?

What I’ve done so far is:
1) add_action in the __construct() to call my register_shortcode().
2) public function register_shortcode() {
add_shortcode( ‘fun_staff_bio’, ‘rfsb_fun_staff_bio’ );
}
3) public function rfsb_fun_staff_bio() {
return ‘This is my SHORTCODE’;
}

When I add the shortcode to a page, WordPress simply writes the actual shortcode text: [fun_staff_bio]

I thought it could have been a name conflict since my plugin is the same name as the shortcode, but changing the name of the shortcode didn’t help

Thanks for either an example or some pointers to my problem.

    Heya David,

    Based on what you’ve supplied above, the code in your constructor should be as follows:

    add_shortcode( 'fun_staff_bio', array( $this, 'rfsb_fun_staff_bio' ) );

    And then that should call your function:

    function rfsb_fun_staff_bio() { }

    Try that – it should work if all else is done correctly.

Combining your short course on Tuts+ with your boilerplate, I have learned how to create some pretty awesome plugins and I have committed myself to learning it “your way” because I find your preferences as good as any and better than most. So before I ask my question, I wanted to thank you for what you have added to the community so far and I look forward to the more that is coming.

Now, my question –

Niether in the course nor in the boilerplate do you use AJAX in the admin. I have a need to do so and as a foundation I created the functionality in a procedural plugin which works fine like this:

(1) I created the function in plugin.php as such:

function ppmhnh_add_location(){
global $wpdb;
$values = array();
parse_str($_POST['form'], $values);
$wpdb->insert(
‘ppm_hoopsandhits_locations’,
array(
‘locale’ => $values['locale'],
‘locale_city’ => $values['locale_city'],
‘locale_state’ => $values['locale_state']
),
array( ‘%s’, ‘%s’, ‘%s’ )
);
echo “Added successfully!”;
die();
}
add_action(‘wp_ajax_ppmhnh_new_location’,’ppmhnh_add_location’);

(2) The jquery code looks like this:

$(‘#newLocation’).submit(function(e){
$(‘#wait-gif’).show();
$(‘#btnAddLocation’).attr(‘disabled’, true);
data = {
action: ‘ppmhnh_new_location’,
form: $(this).serialize()
};

$.post( ajaxurl, data, function(response){
//alert(response);
$(‘#wait-gif’).hide();
$(‘#btnAddLocation’).attr(‘disabled’, false);
location.reload();
});
return false;
});

The procedural way above works but it is not the clean approach I learned from you so I tried to move it into my OOP version.

(1) To the HoopsAndHits class, I placed an add_action(‘admin_ajax_new_location’,’ajax_add_location’);

(2) I added this public function:

public function ajax_add_location(){
global $wpdb;
$values = array();
parse_str($_POST['form'], $values);
$wpdb->insert(
‘ppm_hoopsandhits_locations’,
array(
‘locale’ => $values['locale'],
‘locale_city’ => $values['locale_city'],
‘locale_state’ => $values['locale_state']
),
array( ‘%s’, ‘%s’, ‘%s’ )
);
echo “Added successfully!”;
die();
}

(3) I modified the jquery to this:

$(‘#newLocation’).submit(function(e){
$(‘#wait-gif’).show();
$(‘#btnAddLocation’).attr(‘disabled’, true);
data = {
action: ‘admin_ajax_new_location’,
form: $(this).serialize()
};

$.post( ajaxurl, data, function(response){
//alert(response);
$(‘#wait-gif’).hide();
$(‘#btnAddLocation’).attr(‘disabled’, false);
location.reload();
});
return false;
});

I thought that would work, but it doesn’t. The “Wait” spinner just spins and spins and nothing else happens. I don’t get any errors and I have tried to debug without success.

Would you set me straight???

Jon

    Unfortunately, questions like this normally require a bit more debugging and discussion via email rather than a blog comment.

    If the plugin works exactly as you expect given the procedural approach, but it’s failing on the object-oriented approach, then I’d say you may need to work to implement a bit of a hybrid as I’m not exactly sure that using the pure OOP approach works. For more information, see this page.

    Here’s what I’d do:

    Implement the singleton pattern on the plugin
    Have the Ajax callback get an instance of the plugin, then call the method that you want to trigger via Ajax
    Have the function then return the response to the caller

    For a super contrived example:

    function foo_example_function() {
    $plugin = Foo_Plugin::get_instance();
    $response = $plugin->perform_ajax_request();
    echo $response;
    }

    Hope this helps!

Hi!

I’m having a problem with activate and deactivate methods not being called.
I want to create a table in the database on activation but it doesn’t happen.
I tried adding error_log messages and even die() in the single_activate() method, but none of them seem to happen.

I’m running WordPress 3.7.1
Anyone else having this issue?

Hi Tom, I released a WordPress plugin in the WP repo, built on your helpful boilerplate.
I have some suggestions for the next boilerplate versions:

1. Added a function in the public class which checks the requirements on activation, i.d. checking the required WP version. Added a constant REQUIRED_WP_VERSION, too.
Under some circumstances because of this function the variable $plugin-slug had to be set as a constant in this class.

2. Deleted screen_icon() which is deprecated since WP 3.8.

3. Changed the call of the language file completely.
Instead of loading textdomain from the WP lang dir it loads plugin_textdomain from the plugin’s lang dir. I could not figure out why the first mentioned way was used.

The most sophisticated query to get the current locale / domain I found is the function wpcf7_load_textdomain() of the plugin “Contact Form 7″. Maybe you would found it useful to implement.

You can take a look into the plugin built on your boilerplate: http://wordpress.org/plugins/quick-featured-images/

    Martin – love this feedback. Thanks for providing all of this – I take it all seriously and will see what we can do about making the Boilerplate a bit easier to use in the next version :).

Great plugin, saves a lot of time! One question:
Would you say that saving plugin options within `admin > views > admin.php` is the way to go, or is there a better, more oop way to do it?

Great plugin, but Just one question.
I want to add a multilevel menu to the admin menu, and in add_plugin_admin_menu I see only one menu, with the $this->plugin_screen_hook_suffix = …
But how do I add more than one menu without damaging the $this->plugin_screen_hook_suffix ?

    You can opt to use a different string that the prefix if you’d like. Remember the Boilerplate is just a starting point – it’s absolutely capable of being flexible to suit your needs for doing what you need it do it :).

Hi Tom,

Great tool. Thanks for putting in the time.

I’m curious how I should configure the boilerplate to allow theme functions? E.g. I want to be able to call functions from, say, the public class in functions.php or theme files.

Thanks in advance

Chris

    There are a couple of ways to do this (more, really, but off the top of my head):

    1. You can implement hooks via do_action
    2. You can create some type of container object or reference object that implements the singleton pattern and maintains a reference to the plugin classes. Then you can grab an instance of the object from that container.

    Other suggestions you may come across include declaring something as global, but I highly recommend against doing that. It’s messier and is kind of a cheaper way of doing better architecture.

Hi Tom,
thank you for this wonderful project. It helped me a lot to move from procedural plugin development to oop. Right now I have an issue where I get stuck.
In my plugins I usually just register scripts at wp_enqueue_scripts and enqueue them later due to localization/parameter definition or simply because I load my scripts only if they are really needed (e.g. with a shortcode). This works perfect in a procedural approach. However I cant get it running with oop.

This works:

class my_class extends your_class {
	
	public function __construct() {
		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'), 99);
		add_shortcode('my_shortcode', array($this, 'my_shortcode' ));
	}
	
	public function enqueue_scripts(){
		wp_register_script( 'my_js', plugins_url( '/js/my.js', __FILE__ ), array( 'jquery' ), '20140821', true );
		wp_localize_script( 'my_js', 'myajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'ajaxnid' => wp_create_nonce('my_ajax_nonce') ) ); 
		wp_enqueue_script( 'my_js' );
	}

	public function my_shortcode( $args=array() ) {
		// doing all the stuff  
	}

}
$my_class = new my_class();

Trying to enqueue the script later however fails and my.js does not get even loaded:

class my_class extends your_class {
	
	public function __construct() {
		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'), 99);
		add_shortcode('my_shortcode', array($this, 'my_shortcode' ));
	}
	
	public function enqueue_scripts(){
		wp_register_script( 'my_js', plugins_url( '/js/my.js', __FILE__ ), array( 'jquery' ), '20140821', true );
	}

	public function my_shortcode( $args=array() ) {
		wp_localize_script( 'my_js', 'myajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'ajaxnid' => wp_create_nonce('my_ajax_nonce') ) ); 
		wp_enqueue_script( 'my_js' );

		// doing all the stuff  
	}

}
$my_class = new my_class();

What am I missing? I guess I have to deal somehow with $this-> as I do to call procedures or constants within the class. But how would I?

Any help is highly appreciated.

Michael

    Never mind. If I would have done it as described above it would have worked. In my real code I simply called wp_enqueue_script to late because I called it in a function that retrieves the return value of my shortcode. So actually I answered my own question while providing the example.

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>