Two Ways to Develop WordPress Plugins: Object-Oriented Progamming

This entry is part 1 of 1 in the series Two Ways to Develop WordPress Plugins

When it comes to writing WordPress plugins, there are generally two ways to go about doing so: Object-Oriented Programming and Functional Programming (with Widgets being the exception – we’ll cover that later in the article).

Though you generally have people vouching for one style of programming over the other, each presents its own set of advantages and disadvantages.

In this two-part series, Stephen Harris and I are going to break down the two ways that you can go about writing WordPress plugins. Specifically, I’m going to talk about object-oriented programming, and he’ll be covering functional programming.

Because the experience level of readers varies, we’re going to be talking about programming at a high-level, so if you’re a beginner, then you should have no problem following along. If, however, you’re a more experienced developer, then you may find more useful information later in the article.

With that said, let’s begin looking at an object-oriented approach to developing WordPress plugins.


Developing WordPress Widgets

As mentioned in the introduction, plugins can be developed for WordPress in two ways:

  1. Object-Oriented Programming
  2. Functional Programming

The second article in the series will be covering Functional Programming, but let’s provide a working definition of object-oriented programming so that we’re all on the same level throughout this article.

Wikipedia states:

Object-oriented programming (OOP) is a programming paradigm using “objects” – usually instances of a class – consisting of data fields and methods together with their interactions – to design applications and computer programs.

Those that are more experienced with computer programming, especially those who use object-oriented programming techniques, will likely like that definition.

But let’s simpify it for purposes of this article:

Object-oriented programming is a programming technique that uses a collection of related methods to define a computer program or part of a computer program.

Simple enough, right? In our case, our plugins are definitely part of a computer program since they are hooking into WordPress.

Though we’ll be looking at code throughout the rest of this article, note that object-oriented programs are identified by the grouping of their related methods and that is done within the context of what’s called a class – which we’ll be covering momentarily.

A Word About Widgets

Although it’s true that WordPress plugins can be developed using OOP or functional programming, there is an exception when it comes to developing Widgets.

According to the Codex article on developing widgets, the following structure is to be used for writing a widget:

class My_Widget extends WP_Widget {
	public function __construct() {
		// widget actual processes
	}
	public function form( $instance ) {
		// outputs the options form on admin
	}
	public function update( $new_instance, $old_instance ) {
		// processes widget options to be saved
	}
	public function widget( $args, $instance ) {
		// outputs the content of the widget
	}
}

This means that all Widgets should be written using OOP. If you’ve not seen code like the above, we’ll be covering that in the next section and it should provide everything you need to know to understand what’s going on.


A Concise Introduction to OOP

Before we get started looking at building OOP-based plugins for WordPress, let’s take a closer look at the basics of OOP to make sure that we’re clear on terminology, and how the paradigm works.

Classes

Like we defined earlier, OOP uses “a collection of related methods.” But we can’t stop there. After all, functional programming does the same thing.

In OOP, these “related methods” are all related in the context of what’s called a class. In the example Widget above, you’ll see the class keyword as the very first word in the code.

It begins on a line that ends with an opening bracket (much like functions), and then it encapsulates – or wraps – all of its related functions before terminating with the closing bracket (for now, ignore the extends keyword in the Widget’s example – we’ll touch on that in a moment).

A Logical Grouping of Functions

If you’re just getting started with writing classes and you’re wondering if a function belongs in a given class, ask yourself if the function sounds like something that particular class would do.

For example, in the Widget example above, the update method is obviously something that a widget would do. But let’s say you’re writing a class that’s going to to be responsible for reading a blog post to the WordPress database. It would make sense for that particular class to have a function called read or read_by_id, but should it have a function called write? What about delete?

Depending on how you’ve designed your class, possibly. But if the sole purpose of the class is to read data, then probably not.

And that’s OOP: it’s logically grouping your functions together in a class, but said logical grouping depends on the responsibility that you’re giving your class.

Advanced Topics in OOP

OOP is a powerful paradigm that’s employed throughout the WordPress application. OOP allows for advanced operations such as inheritance (which is represented by the extends keyword in the Widget class), design patterns which are essentially existing solutions to common problems.

This article doesn’t attempt to be a deep dive into object-oriented programming. It’s simply trying to provide a foundation off of which we can explore the two ways of writing WordPress plugins, but I mention them here should you be interested in diving further into object-oriented programming.


Developing Class-Based Plugins

Now that we’ve defined object-oriented programming and explored just enough to lay a foundation, it’s time to actually begin talking about the components of OOP-based development in the context of WordPress plugins.

Throughout the rest of this article, we’re going to cover the basics of what’s required for writing OOP-based plugins, and the advantages that it brings.

Defining the Class

Before you do anything in object-oriented development, you have to define your class. Assuming that you already have an idea as to what your class is going to do, this generally a matter of coming up with what you want to name your class.

For the most part, I think that viewing example code is always advantageous when actually teaching code, so we’ll be taking a look at the WordPress Plugin Boilerplate.

Note that the Plugin Boilerplate is a project that I originally created to help jumpstart OOP-based plugins. It’s since been contributed to by a number of different people. I’m using it in this article because it demonstrates the topic at hand.

That said, notice the class definition for the Plugin Boilerplate looks like this:

class PluginName {
	// More to come…
}

Because the Plugin Boilerplate is a starting place for development, we’d obviously rename the class. For this article, let’s call it DemoPlugin.

class DemoPlugin {
	// More to come…
}

At this point, we’re ready to begin defining functions that live within the class.

The Constructor

In OOP, the first function that you’re likely to see in a class is a function called “the constructor” and PHP is no different.

A simple, working definition of the constructor is this:

The constructor is where you initialize data that is going to be used throughout the class.

How this works varies from project to project, but there are two primary things that we can do within the context of a WordPress plugin:

  1. Setup the textdomain for localization purposes
  2. Define our actions and filters (specifically, our actions and our filters).

In our DemoPlugin, we’re going to do just that. We’ll set a textdomain of demo-plugin and we’ll register actions for registering and enqueueing an example stylesheet and an example JavaScript file.

To be complete in our example, we’ll also register a hook for appending some text to the end of content displayed in a post.

First, let’s define the constructor:

class DemoPlugin {
	public function __construct() {
	}
}

Note that in PHP, a constructor is defined by a public function named construct that is preceeded by two underscores.

Next, let’s define our textdomain:

class DemoPlugin {
	public function __construct() {
		load_plugin_textdomain( 'demo-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
	}
}

In the above line of code, note that we’ve defined the key for our textdomain to be demo-plugin and the line expects to find the localization files in a subdirectory called lang in the plugin’s directory.

Because localization is out of scope for this article, I won’t be diving any futher, but you can review the source code for the Plugin Boilerplate to see how this is setup.

Next, let’s define the actions for registering our stylesheets and JavaScript as well as the filter that will append some text to the end of our content:

class DemoPlugin {
	public function __construct() {
		load_plugin_textdomain( 'demo-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
		add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_styles' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_scripts' ) );
		add_filter( 'the_content', array( $this, 'append_post_notification' ) );
	}
}

If you’re not familiar with actions and filters, be sure to read one of my recent articles here on Wptuts+ as it explains the difference.

Now, if you’re familiar with WordPress theme development or functional programming, then you’re likely used to seeing something like the following:

add_action( 'wp_enqueue_scripts', 'register_plugin_styles' );

Rather than:

add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_styles' ) );

Notice that the difference in the two calls above is in the second parameter. Specifically, in our plugin we’re passing an array whereas the first line of code is simply passing a string.

Because we’re developing this plugin using OOP, WordPress has to know where to call the register_plugin_styles method. Since it lives within our class, we have to tell WordPress to call the method on an instance of our class.

Make sense?

Essentially, we’re telling WordPress: I’ve got this method called register_plugin_styles, but you need to call it on an instance of this class (hence the this keyword).

If you’re new to WordPress, but are coming from a programming background, then you could imagine that you’re telling WordPress to do this:

$demo = new DemoPlugin();
$demo->register_plugin_styles();

Anyway, the bottom line is that if you’re developing your plugins using OOP, then you must register your hooks using an array with two indexes: the first being $this and the second being the name of the function.

A Note About Pass-by-Reference and Pass-by-Value

Advanced developers will be familiar with PHP’s ability to pass-by-referene and pass-by-value. In WordPress Development, it’s not that uncommon to see the following:

add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_styles' ) );

Where this is passed by reference; however, as of PHP 5.4, the ability to pass variables by reference at call time has been removed. That’s why this tutorial is opting to pass by value.

Functions

In programming, functions are the units of code that are essentially responsible for “doing something.” In object-oriented programming, it’s helpful to think of them slightly differently.

In OOP, classes are usually represented by nouns. In our case, we have a DemoPlugin. Similarly, functions are often verbs. That is, they are actions that our noun can take. At this point, we’ve already opted to define the following functions:

  • register_plugin_styles
  • register_plugin_scripts
  • append_post_notification

Notice how each function name represents an action that can be taken. This is a good rule of thumb to employ when writing functions.

In functional programming, there’s really only just the idea of functions; however, in OOP, there are several different types of functions, two of which are “public” functions and “private” functions.

Public Functions

Public Functions are functions that are accessible outside of the class. This means that you’re able to call these methods once you’ve instantiated the class.

This is exactly what we did earlier in the following code:

$demo = new DemoPlugin();
$demo->register_plugin_styles();

Basically, these functions are accessible by the public (where the public may be a programmer or another object).

The functions that we’re writing for registering our stylesheets, our JavaScript, and that we’re writing to append text to a post have to be marked as public because there will be a third-party calling on them – WordPress.

Let’s define the two functions for the wp_enqueue_scripts action:

public function register_plugin_styles() {
	wp_register_style( 'demo-plugin', plugins_url( 'demo-plugin/css/plugin' ) );
	wp_enqueue_style( 'demo-plugin' );
}
public function register_plugin_scripts() {
	wp_register_script( 'demo-plugin', plugins_url( 'demo-plugin/js/display.js' ) );
	wp_enqueue_script( 'demo-plugin' );
}

Again, note that these two functions expect that the stylesheets and JavaScript reside in css and js subdirectories, respectively. To see this in action, remember to check out the Plugin Boilerplate.

Finally, let’s define the function for the_content filter:

public function append_post_notification( $content ) {
	$notification = __( 'This message was appended with a Demo Plugin.', 'demo-plugin-locale' );
	return $content . $notification;
}

Note that we’re using the __ function to make sure our script is localized with the textdomain that we defined in the constructor.

Private Functions

If public methods are accessible by anyone, then it would imply that private functions are accessible by no one, right? For the most part, that’s correct: The only person – or thing - that can call private methods are the class in which they’re defined.

That means that WordPress, third-party objects, nor programmers can programmatically call private functions. Private functions can only be called from within the class they are used.

Generally speaking, private functions are very useful when writing helper methods – that is, they are useful for manipulating data internally to help another function carry out its job.

To give a working example, let’s define a private function that will return a localized string that our append_post_notification function can use:

private function get_localized_notification() {
	return __( 'This message was appended with a Demo Plugin.', 'demo-plugin-locale' );
}

Next, let’s refactor the append_post_notification function to call this new helper:

public function append_post_notification( $content ) {
	return $content . $this->get_localized_notification();
}

Notice that we’ve simplified the first function by adding a second function. You could also argue that we’ve increased the readability of the initial function by adding a call to a function with a name that helps clarify what’s happening.

Perhaps the most important thing to note is that in order to call private functions, you must prefix the function call with the $this keyword and the ->. This is telling PHP: “Call the get_localized_notification function that lives in this class.”

At any rate, we’ve given each method a single responsibility – another good practice in object-oriented programming – and we’ve demonstrated the use of both public and private functions.

Other Function Types

In object-oriented programming, there are also other types of functions that are beyond the scope of this article.

To be complete, I wanted to summarize them here:

  • Static Functions are functions that do not require an instance of a class to be called. Instead, you can simply call them directly on the name of the class. For example: DemoPlugin::use_this_static_method().
  • Protected Functions are like private functions except for subclasses. That is, the only objects that can access protected functions are subclasses of the given class. This particular type of function plays into the concept of inheritance which was mentioned earlier in the article.

Advantages in WordPress

At this point, we’ve hit all the high notes for object-oriented WordPress development. To summarize the advantages:

1. All Functions Are in Context

When using object-oriented programming, you don’t have to prefix a function with the name of the theme or the name of the plugin that you’re working on, nor do you have to worry about naming a function something that may interfere with a WordPress function, another theme’s function, or another plugin’s function.

Instead, all functions live within the context of another class. The only thing to make sure of is that your class isn’t named something that interfers with another existing class.

2. Calling Them Outside of the API

By using object-oriented programming, you can programmatically call on your plugin from outside of the standard WordPress API.

Let’s say that you’re developing a theme and you want something to render on the sidebar that your plugin provides. In the sidebar template, you can actually instantiate your plugin and then call methods on it to have it write information out into the sidebar.

This is particularly useful whenever you’re working on a template and want to provide some default data if the user doesn’t manually enter something.


Conclusion

Like we said at the beginning of the article: this is but one way in which you can develop your WordPress plugins. Stephen’s article will cover how to do it using functional programming.

After reading this article, you should have a better understanding of object-oriented programming, its advantages, and you should be able to follow along with code documented in the Widget API, in my related Widget Boilerplate, and even throughout places in the WordPress codebase.


Resources

from Wptuts+ http://wp.tutsplus.com/tutorials/plugins/two-ways-to-develop-wordpress-plugins-object-oriented-progamming/

About these ads

Kommentar verfassen

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ photo

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s