WordPress Plugin Structure

The power of WordPress lies in its pluggable infrastructure.  Unlike other content management applications which require you to edit the core code of the system to make changes, WordPress supports plugins.  These smaller applications tie in to a rich API provided by WordPress that allows you to change just about everything about the application and customize it as needed.

The official plugin repository on WordPress.org is currently home to over 20,000 distinct plugins.  Each one adds some new functionality to WordPress, giving you the ability to tweak content, change colors, adjust layouts, or integrate with external systems.  This doesn’t even begin to cover the hundreds of premium plugins you can find online that provide even richer functionality.

Most WordPress developers will, at some point, be asked to create some kind of plugin for a client site. These client plugins can range from a shortcode manager to some kind of advertisement rotation engine to an API integration with a third-party customer management system. Instead of focusing on the what for your plugins, this tutorial will focus on the how. Namely, the three different ways you can structure a WordPress Plugin.

Functional

The quickest, easiest approach is to use standard functions to define your custom functionality. For simple plugins, this is actually the best and most straight-forward approach.

All of your plugin code will reside in a single file – [cci]my-plugin.php[/cci] – in the root of your [cci]/my-plugin[/cci] directory. Prefixing every function name with a unique string (i.e. [cci]myplugin_[/cci]) will prevent your code from colliding with any code shipped by another developer. It also makes it easy for other developers to remove and re-add action hooks and filters should they need to.

The following example code will add the number of draft posts to the Right Now box on the WordPress dashboard:

function myplugin_count_posts() {
$posts = wp_count_posts();

$num = number_format_i18n( $posts->draft );
$text = _n( 'Draft', 'Drafts', intval( $posts->draft ), 'myplugin_translate' );

if ( current_user_can( 'edit_posts' ) ) {
$num = "$num";
$text = "$text";
}

echo '

' . $num . '

';
echo '

' . $text . '

';
}
add_action( 'right_now_content_table_end', 'myplugin_count_posts' );

This hook can easily be removed, reordered, or otherwise manipulated by other developers if they know the hook name. Keep things consistent in your code, and things will work well for community involvement.

Unfortunately, if your plugin is much more complex, the functional approach can quickly become a nightmare. Figuring out which functions are defined where in a large, monolithic file can be challenging. Once you start breaking your one file into smaller pieces of distinct functionality, though, you face other organizational difficulties.

For more complex plugins, you should begin structuring things in a class format.

Static Class

Just like prefixing function names can prevent function collision, making your functions all static members of a class will, essentially, “namespace” your plugin’s functionality. After prefixing, this is the easiest way to organize your plugin in such a way that it plays well with other systems in the WordPress infrastructure.

The trick is that action hooks and filters are now added using an array notation rather than a straight string. For example, instead of [cci]add_action( ‘wp_head’, ‘myplugin_head’ )[/cci], you would call [cci]add_action( ‘wp_head’, array( ‘My_Plugin’, ‘head’ ) )[/cci]. Similar notation, but it’s important to include the class reference here, otherwise WordPress won’t know where your code is defined.

Breaking your function up into several files is best done when each file represents a distinct class. It’s easy to know which functionality is encapsulated within which class if you keep related functions together and are clear with your project names. It’s also relatively easy for other developers to manipulate your code later, so long as they also remember the static class notation you used with [cci]add_action()[/cci].

Here is our functional example from above, but rewritten as a call from a static class:

class My_Plugin {
static function count_posts() {
$posts = wp_count_posts();

$num = number_format_i18n( $posts->draft );
$text = _n( 'Draft', 'Drafts', intval( $posts->draft ), 'myplugin_translate' );

if (  current_user_can( 'edit_posts' ) ) {
  $num = "<a href='edit.php'>$num</a>";
  $text = "<a href='edit.php'>$text</a>";
}

echo '<tr><td class="first b b">' . $num . '</td>';
echo '<td class="t">' . $text . '</td></tr>';

}
}
add_action( 'right_now_content_table_end', array( 'My_Plugin', 'count_posts' ) );

Some tutorials recommend an instantiated class with some static elements for adding/removing action hooks and filters. Their code will work, but is a bit hacky. Particularly if you’re ever in a place where the class can be instantiated more than once. With that in mind, I would never recommend that approach – either keep everything static, or go with my favorite pattern below.

Singleton

A singleton is a class that can only be instantiated once. Every other reference to the instantiated object is a reference to the same object. This is a pattern that works beautifully for plugins because, honestly, you only ever need to instantiate the plugin once. It’s also the way I prefer to build plugins since it keeps things clean, avails private variables to the plugin, and is an easy pattern to follow.

Basically, a singleton is a class with a read-only static instance and a private constructor. When you attempt to get the class instance, it checks to see if the class has been instantiated – if not, it fires the constructor internally and stores the constructed object inside the static instance. Now, every request for the instance returns the same object. Here’s a very basic example of a singleton class.

class Singleton {
private static $instance = false;

public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}

private function __construct() { }
}

With a singleton class, you can have methods and members that are members of the class, can refer to each other, and can reference data (properties) which are private to the class itself. For example, if you build a singleton and populate it with certain properties that are meant to be read-only, you can store those values as private members of the class and expose public getter functions.

class My_Class {
private $hidden_var; // Invisible outside of the class
var $visible_var; // Visible outside the class

public function get_hidden() {
return $this->hidden_var;
}

public function __construct() {
$this->hidden_var = 4;
$this->visible_var = 6;
}
}

$instance = new My_Class;
echo $instance->visible_var; // Echos 6
echo $instance->hidden_var; // Fatal Error
echo $instance->get_hidden(); // Echos 4

$instance->visible_var = 2; // Works
$instance->hidden_var = 2; // Fatal Error

Removing action hooks and filters is straight forward because you always have access to the instance of the class that wired them up in the first place. This means it’s easy for developers down the road to manipulate your code.

Here’s the same plugin example from above, but rewritten as part of a singleton class:

class My_Plugin {
private static $instance = false;

public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}

private function __construct() {
add_action( 'right_now_content_table_end', array( $this, 'count_posts' ) );
}

public function count_posts() {
$posts = wp_count_posts();

$num = number_format_i18n( $posts->draft );
$text = _n( 'Draft', 'Drafts', intval( $posts->draft ), 'myplugin_translate' );

if (  current_user_can( 'edit_posts' ) ) {
  $num = "<a href='edit.php'>$num</a>";
  $text = "<a href='edit.php'>$text</a>";
}

echo '<tr><td class="first b b">' . $num . '</td>';
echo '<td class="t">' . $text . '</td></tr>';

}
}

$my_plugin = My_Plugin::get_instance();

Conclusion

Most developers are just beginning to embrace object-oriented design patterns with WordPress. Unfortunately, few of us have enough experience with OOP to discern good versus bad programming patterns. Many developers are using instantiated objects to encapsulate plugin functionality – and running the risk of multiple instances being created during a single request. Others are properly using static classes and objects, then running afoul of global variables when attempting to pass data from one static method to another.

The most efficient pattern for WordPress plugin development is, hands down, the singleton. It can only be instantiated once, and has the ability to store data internally for quick recall – meaning member functions can easily pass data back and forth without cluttering the global namespace.

Which patterns are you using for plugin development? What other alternatives have you found?