Classy Plugins

I was asked a few weeks ago why I structured my WordPress plugins the way I do.

Anyone who has spent any time looking at my code knows that I like to keep my main functions in a class and wire up action hooks and filters in the root of the plugin.  But few people have asked me why I set things up this way.

My explanation is in two parts:

  1. Writing clean code
  2. Writing easy-to-maintain code

Though it should be noted now that, while this particular development style makes heavy use of classes within PHP, this is not object-oriented programming.

Let me say again – this is not object-oriented programming.  I use classes often to define custom objects, but in this situation I use them merely as convenient wrappers for code.

Writing Clean Code

Ideally, code should be self-documenting.

Function names should be concise yet descriptive.  Variable names should reflect what’s contained within them.  I should be able to tell from glancing at your code what it does without looking to external documentation.

Where code isn’t enough to explain what’s happening, a quick in-line comment usually is.

To stick to this idea, I like to name my plugin functions after the WordPress hooks they tie to.  If I want to hook onto the [cci]init[/cci] hook, I’d like to do so with a function named [cci]init()[/cci].

And that’s a problem because that function name is already used.

To keep things clean, I make all of my plugin functions public, static members of a class.  Then, I can specify the class name when hooking in to WordPress and can keep things clean:


class My_Plugin {
public static function init() {
add_image_size( 'mp-image', 120, 140, true );
}

public static function query_vars( $public_vars ) {
$public_vars[] = 'mp-paged';
return $public_vars;
}

public static function the_content( $content ) {
global $post;
if( 'mp_post_type' != $post->post_type )
return $content;

$mp_post = new MP_Post( $post );
return $mp_post->summary;

}
}

A lot of other developers prefix their function names.  I have no problem with this as an alternative practice.  I just have my own preferences for code organization.

Easy-to-maintain Code

I keep all of my hooks in one place so I don’t need to hunt for them later.

My first experience with an “advanced theme framework” was what should have been a 2-hour design project.  Instead I spent 2 weeks hunting through the code and referencing online documentation to find out which hooks were defined in which files so I could override them.

It was painful.

As much as I like the elegance of seeing a [cci]fire_main_engines()[/cci] or similar method in a plugin root (leaving that function to call others that wire up the hooks), that kind of model is difficult to maintain.  If all of the hooks are instead defined in one spot, it’s easy to add new ones, remove deprecated ones, or just see at a glance every part of the plugin that interacts with WordPress.


require_once( 'lib/class.my-plugin.php' );

add_action( 'init', array( 'My_Plugin', 'init' ) );

add_filter( 'query_vars', array( 'My_Plugin', 'query_vars' ) );
add_filter( 'the_content', array( 'My_Plugin', 'the_content' ) );

What We Gain

The folder structures of my plugins are very uniform and easy to follow. The root directory contains a single PHP file with plugin information, licensing, and all of the hooks used by the system. There’s also a readme file containing a changelog, FAQs, and other useful information. If the plugin adds presentation elements, there are a few screenshots.

The [cci]/lib[/cci] folder contains PHP files with static classes that wrap the functionality of the plugin. They are either [cci]require()[/cci]ed or [cci]include()[/cci]ed by the root PHP file.

You can browse the base file in the root directory to see where my plugin ties in to WordPress. Based on the function and class name in the hook, you know exactly which file to look at for the actual functionality.

Is this the best way to do things? I don’t know for sure. All I do know is that it’s clean and efficient.