Object?
What We're Going to Learn:
- Benefits of using OOP for WordPress plugins.
- How to setup a shortcode.
- How to setup a template tag.
- How to enable shortcode in WordPress widgets.
- Real-world example by using Dribbble's API.
Why Use OOP?
Before moving forward with this tutorial, you should have at least an elementary understanding of writing a WordPress plugin. Jonathan has written an amazing tutorial on "How to write a WordPress Plugin". Give it a read.
Creating WordPress plugins with object oriented code is quite efficient and tidy, when compared to using procedural code. It's easier to manage the code base, and expand it using inheritance techniques, which can be particularly helpful when writing a large plugin.
Dribbble
To write a WordPress plugin, we first need a sense of direction. We're going to write a plugin that will display the latest shots from Dribbble, using their REST API. We'll then add shortcode support for posts and widgets, and template tag for themes.
Step 1 - Setting up the Plugin Class
Object oriented code is based on classes and methods (functions). Let's create our core class, which will interact with WordPress' hooks and filters.
class WPDribbble { public function __construct() { } } $wpDribbble = new WPDribbble();
PHP classes have a constructor function,
__construct, which is executed as soon as a new instance of a class is instantiated. All WordPress hooks and filters will be registered under the constructor of our plugin class. Lets push ahead and register a shortcode for our plugin. The
add_shortcode() function/hook will go under the constructor function.
The new instance of a class/object is registered using the
new keyword. Refer to the last line in the code below.
class WPDribbble { public function __construct() { add_shortcode('Dribbble', array($this, 'shortcode')); } public function shortcode() { } } $wpDribbble = new WPDribbble();
- add_shortcode - The first parameter is the shortcode tag, and the second is the callback function.
Notice how we're using an
arrayin the callback function parameter? To register callback functions inside an object, we have to use an
array.
The first item of the array references the object, via
$this. The second item in the
array is the method name within the class. All hooks and filters have to be referenced like this when inside a class.
Still Confused?
# 1. Standard usage add_shortcode('shortcode_name', 'shortcode_func'); function shortcode_func() { // Contents of this function will execute when the blogger // uses the [shortcode_name] shortcode. } # 2. With PHP 5.3, we can pass an anonymous function. add_shortcode('shortcode_name', function() { // Contents of this function will execute when the blogger // uses the [shortcode_name] shortcode. }); #3. Within a class class WPDribbble { public function __construct() { add_shortcode('Dribbble', array($this, 'shortcode')); } public function shortcode() { // Contents of this function will execute when the blogger // uses the [shortcode_name] shortcode. } }
Step 2 - Dribbble API Class
Since we currently do not require any fancy API functions, we're going to create a rather simple API wrapper for Dribbble. There is already a library available for Dribbble, but, for the sake of this tutorial, we're going to write our own. It'll help you understand the concepts behind this tutorial.
We're going to write a DribbbleAPI
object, and register a
method called
getPlayerShots() to interact with Dribbble's API and return an
array of the latest shots.
Let's create a new file for this class, called
DribbbleAPI.php
class DribbbleAPI { // url to Dribbble api protected $apiUrl = ''; // Dribbble username or user id protected $user; }
Above, we're setting up two class variables.
- $apiUrl - The link to the Dribbble API, where the calls will be sent.
- $user - The username or user id of a Dribbble user. This value will be set from within the constructor (
__construct) method.
class DribbbleAPI { // url to Dribbble api protected $apiUrl = ''; // Dribbble username or user id protected $user; public function __construct($user) { $this->user = $user; } }
The constructor is passed a
$user variable, which is then passed on by the constructor to the class property, called
user.
We prefix the property, or variable name with
public to specify that the value of this property can be retrieved from outside of the
class. If we instead wish to limit access to the property to only this
class, and perhaps any
classes that inherit from it, we'd use the
protected prefix. This practice is referred to as encapsulation.
We have the base ready for our Dribbble API wrapper. Now, We're going to write a new
method, called
getPlayerShots(). The purpose of this
method will be to query the API and convert the result into an
array for usage within our plugin.
class DribbbleAPI { // url to Dribbble api protected $apiUrl = ''; // Dribbble username or user id protected $user; public function __construct($user) { $this->user = $user; } public function getPlayerShots($perPage = 15) { $user = $this->user; $json = wp_remote_get($this->apiUrl . 'players/' . $user . '/shots?per_page=' . $perPage); $array = json_decode($json['body']); $shots = $array->shots; return $shots; } }
Learn more about wp_remote_get.
The
getPlayerShots function retrives the user from the class variable. It uses WordPress'
wp_remote_get function to query the Dribbble API. The API then responds to our query with a JSON string, which is then parsed into an
array and sent back to the function using the
return keyword.
This is all that we require from the API at the moment - simply an
array of player shots. If we happen to require more functionality in the future, we can either add more
methods to the current
class, or create a new
class that extends this one. Again, this is referred to as inheritance.
Step 3 - Integrating the
DribbbleAPI Class
This is the fun part; the freshly baked
DribbbleAPI
class will come into use. We're going to loop through the shots retrived from the API, and generate an
html list of shots, which will be passed on to the shortcode and the template tag. During the loop, the full-sized Dribbble images will be cached and saved in the plugin folder, and the thumbnails will be generated using TimThumb.
To determine if the full images are already stored locally, the
plugin path is required. Also, to generate the thumbnails with
timthumb, the
plugin url is required. For this purpose, we'll create two class variables called
pluginPath and
pluginURL in our
WPDribbble class, and then set their values from within the constructor
method.
Setting PluginPath and PluginUrl
class WPDribbble { protected $pluginPath; protected $pluginUrl; public function __construct() { // Set Plugin Path $this->pluginPath = dirname(__FILE__); // Set Plugin URL $this->pluginUrl = WP_PLUGIN_URL . '/wp-Dribbble'; add_shortcode('Dribbble', array($this, 'shortcode')); }
getImages() Method
Create a new
method within the
WPDribbble
class, called getImages.
Inside a
class, you can use generic names for functions. They will not conflict with other plugins or WordPress' built-in functions, because they are under the
classnamespace.
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true) { }
- $user - Username or User ID of Dribbble.
$userwill be used when registering a new instance of the
DribbbleAPIclass.
- $images - Number of images to render.
$imageswill be used when querying the API through the
getPlayerShotsmethod.
- $width and $height - Timthumb will be used to generate thumbnails.
- $caption - Option to render title of an image.
Next, we're going to include the
DribbbleAPI class in the
getImages() function, and create a new instance of it to grab the images.
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true) { include 'DribbbleAPI.php'; $DribbbleAPI = new DribbbleAPI($user); $shots = $DribbbleAPI->getPlayerShots($images); if($shots) { } }
The
$shots variable in the code is populated with an
array of three recent Dribbbles from the
$user.
As mentioned previously, we're going to loop through the
$shots
array, and save the full size images locally for caching purposes. The cached images will be used with TimThumb to serve the thumbnails. For storing full-images and thumbnails generated by TimThumb, create two folders. We'll use
full-images/ for storing the full size images, and
cache/ for the thumbnails, since that is the default folder name for TimThumb.
The HTML for the list will be generated within the
$shots loop.
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true) { include 'DribbbleAPI.php'; $DribbbleAPI = new DribbbleAPI($user); $shots = $DribbbleAPI->getPlayerShots($images); if($shots) { $html[] = '<ul class="wp-Dribbble">'; foreach($shots as $shot) { $image = $shot->image_url; // url of the image $fileName = $shot->id . '.png'; // generating a filename image_id.png if (!file_exists($this->pluginPath . '/full-images/' . $fileName)) { // check if the full image exists $rawImage = wp_remote_get($image); // get the full image $newImagePath = $this->pluginPath . '/full-images/' . $fileName; $fp = fopen($newImagePath, 'x'); fwrite($fp, $rawImage['body']); // save the full image fclose($fp); } // generate thumbnail url $localImage = $this->pluginUrl . '/timthumb.php?src=' . strstr($this->pluginPath, 'wp-content') . '/full-images/' . $fileName . '&w=' . $width . '&h=' . $height . '&q=100'; if($caption) { // if caption is true $captionHTML = '<p class="wp-Dribbble-caption">' . $shot->title . '</p>'; } // combine shot url, title and thumbnail to add to the ul list $html[] = '<li class="wp-Dribbble-list"><a href="' . $shot->url . '" title="' . $shot->title . '"><img src="' . $localImage . '" alt="' . $shot->title . '" /></a>'.$captionHTML.'</li>'; } $html[] = '</ul>'; return implode("\n", $html); } }
Adding Classes
It's always a good idea to add classes to each element of your plugin. This provides the advanced users of your plugin with the freedom to customize it. Avoid using inline CSS for content that is generated through your plugin.
Step 4 - Setting up the Shortcode
Shortcodes, as the name suggests, allows users to easily add complex content into blog posts.
We already have the
add_shortcode hook ready in our plugin class constructor. Now, we're going to write the shortcode
method inside our
class, which will exract the shortcode attributes and return the Dribbble images by using the
getImages() method.
We'll be calling our shortcode
[Dribbble]. As mentioned previously, the name of the shortcode is determined by the first parameter in the
add_shortcode function. It will be used with the attributes required for the
getImages() method. For example:
[Dribbble user=haris images=5 width=100 height=100 caption=true].
public function shortcode($atts) { // extract the attributes into variables extract(shortcode_atts(array( 'images' => 3, 'width' => 50, 'height' => 50, 'caption' => true, ), $atts)); // pass the attributes to getImages function and render the images return $this->getImages($atts['user'], $images, $width, $height, $caption); }
Add Shortcode support for WordPress Widgets
By default, WordPress widgets don't support shortcodes, however, by using the
widget_text filter, we can force shortcode support in WordPress widgets.
We can add the filter in our
WPDribbble object constructor.
public function __construct() { // Set Plugin Path $this->pluginPath = dirname(__FILE__); // Set Plugin URL $this->pluginUrl = WP_PLUGIN_URL . '/wp-Dribbble'; add_shortcode('Dribbble', array($this, 'shortcode')); // Add shortcode support for widgets add_filter('widget_text', 'do_shortcode'); }
Step 5 Setting up the Template Tag
The template tag can be used directly in WordPress themes. The basic purpose of the template tag will be to create a new instance of our
WPDribbble class, and call the
getImages() method. The template tag will be a simple PHP function and it has to be registered outside the plugin
class. It needs to have a unique name; otherwise, it will conflict with functions / plugins with similiar name. Since our plugin is called
WP-Dribbble, we'll call the template tag,
wp_Dribbble().
function wp_Dribbble($user, $images = 3, $width = 50, $height = 50, $caption = true) { $wpDribbble = new WPDribbble; echo $wpDribbble->getImages($user, $images, $width, $height, $caption); }
Voila!
Congratulations! You have successfully written a WordPress plugin with OOP. If you have any questions, let me know, and I'll do my best to help you. .