This post covers Version 1.0 of the plugin for WordPress 2.7 and below. For WordPress 2.8 and above, use version 2.0 of the Plugin. Learn more by reading this updated post. I will try to support this plugin better than I did with Version 1.0. Thanks!

It seems like only yesterday, I set out to build my first ever WordPress Plug-in. Bright eyed and bushy tailed, I poured over the WordPress Codex, putting together the pieces of the process until I finally got the big picture. The WordPress Codex is an amazing resource for anyone looking to get into WordPress development; I strongly recommend any new developer read through the “Writing a Plugin” section.

While learning, I had a difficult time finding a straightforward template I could use as a base for my plug-ins. I wanted something that was clean and well-organized but also provided examples of more complex behaviours, such as: Internationalization, Widgets and Front and Back-End Ajax. I wanted to ensure my plug-in functionality was encapsulated inside a class structure so my functions and variables wouldn’t conflict with the WordPress Core, or other plug-ins.

I’ve finally gotten around to writing this template plug-in, and I thought I would share it with the community to get your feedback and improvements, and hopefully save new developers some time. If you are interested in learning how to build a plug-in, and have a strong programming background, you can look through my sample code, read the comments and pretty much piece together how everything works. If you want a more thorough description of what is going on, read through this article.

You can download the plug-in from the WordPress Plugin directory.

Getting Familiar With the Brolly Template Plug-in

  1. Download the template plug-in.
  2. Place the files in the plug-ins directory of your development installation of WordPress.
  3. Come up with a unique name for your plug-in, such as MyPlugin. Check the WordPress Plug-in directory to ensure this name hasn’t been used.
  4. Rename the plug-in folder from B2Template to your plug-in name (i.e. MyPlugin). Do not use spaces or special characters.
  5. Rename the file B2Template.php to MyPlugin.php
  6. Rename the file B2Template.class.php to MyPlugin.class.php
  7. Rename the class inside MyPlugin.class.php from B2Template to MyPlugin
  8. Rename the constructor function inside MyPlugin.class.php from B2Template() to MyPlugin()
  9. Activate the plugin from the WordPress Plugin Administration Panel
  10. Add the Template widget to your sidebar from the WordPress Appearance Administration Panel
  11. View your site, and interact with the widget to observe it’s behaviour
  12. From the WordPress Administration page, click on Settings, and select MyPlugin.
  13. Interact with the plugin from this page, to view its behaviour.

How to Write a Plugin Using the Brolly Template Plug-in

Note: Substitute B2Template in the instructions below, to whatever you named your plugin (i.e. MyPlugin).

There are two main files in the Brolly WordPress Plug-in Template. The first, B2Template.php, is used to initialize the plugin and route various WordPress actions and filters to class methods in the second file, B2Template.class.php. Keeping all our plug-in functions inside a class gives us greater flexibility to reuse the code we write for the plugin. It also prevents naming conflicts from occuring when multiple plug-ins use the same function or variable names.

Actions

After following the instructions above, the only modifications you should need to do to the B2Template.php file is adding or removing actions and filters. WordPress uses actions to allow you to call plug-in functions after a specific event occurs. For example, you can register an action to call a plug-in function whenever a user deletes a post, publishes a page or whenever a comment is submitted. The WordPress codex website provides a complete list of available actions. The B2Template plugin includes the following actions by default:

  • init: Fires when the plugin loads
  • admin_menu: Fires when wordpress is building the Administration menus on the back-end
  • wp_print_scripts: Fires when WordPress is building the tag for front-end pages
  • wp_admin_print_scripts: Fires when WordPress is building the tag for back-end pages
  • widgets_init: Fires when WordPress is loading widgets

You can easily add another action and route it to a function in the B2Template.class.php file by adding the following line to the B2Template.php file:

add_action('', array($b2_plugin, ''));

Where you replace with the WordPress action you are adding, and with the function inside B2Template.class.php you want to be called.

Filters

Filters are similar to actions, except they let you modify data as it is being saved to the WordPress database, or modify it before it is displayed to the end user. The WordPress Codex provides a complete list of available filters. The B2Template provides the following filter by default:

  • the_content: Passes the page or post content into the specified function as a string. You can then append, prepend or replace sections of this string using php, and then return the modified string at the end of the function. This is what will be displayed to the end user.

To add another filter and route it to a function in the B2Template.class.php file, add the following line to the B2Template.php file:

add_filter('',array($b2_plugin, ''));

Where you replace with the WordPress filter you are adding, and with the function inside B2Template.class.php you want to be called. Here is an example of a filter function, that makes all post and page content uppercase.

function make_upper_case($content){
$filtered_content = strtoupper($content);
return $filtered_content;
}

Custom Actions

The Brolly WordPress plug-in template is setup to allow you to create custom actions very easily. To understand the purpose and usage of custom actions, consider the following example.

You want to build a plugin that adds a link to the end of every post, that lets users rate a post between 1 and 5.

To do this, you would first create a Filter (see above), that appends an HTML drop-down box and submit button to the end of each post. When the user clicks the submit button, you need your plug-in to save this data to your database table. To do this, you can have your submit button POST to http://?B2Template_action=SaveTableData . Open the file B2Template.class.php, and scroll to the function ActionInit. This action gets called on every page load, so here you can check for the variable B2Template_action, and then call a class function based on whatever action you want perform. Here is an example of how you would use this function to save the submitted rating.

function ActionInit()
<pre>{
<pre style="padding-left: 30px;">$action = $_REQUEST[$this-&gt;pf.'action'];
$this-&gt;SetLanguage();
switch ($action) {
case "SaveTableData":
$this-&gt;SaveTableData();
break;
}
}
function SaveTableData()
{
global $wpdb;
// Get POST data and perform SQL function to update database
}

Saving Data

If you only have a bit of data you need to collect from users, you can store this data in “Options”. WordPress documents this well in the Creating Options Pages of the WordPress Codex. There is an implementation of this in the GetConfigHTML function of B2Template.class.php.

If you are collecting more data, it may be handy to create a table for your plugin in the WordPress Database. This process is documented in the Creating Tables with Plugins article of the WordPress Codex. An implementation of this can be found in the Activate function of B2Template.class.php.

AJAX

Ajax isn’t too difficult to do within the WordPress framework. The B2Template provides examples of how to do AJAX calls from the front-end and back-end. The first step is to make sure the ‘SACK’ javascript library is included. We do this by placing the following line in our ActionWpPrintScripts and ActionWpAdminPrintScripts functions in B2Template.class.php:

wp_enqueue_script( array( 'sack' ));

Using WordPress’s wp_enqueue_script function allows you to load javascript libraries that come bundled with WordPress, such as Scriptaculous, jQuery and SACK. It also ensures that multiple plugins don’t include the same library multiple times, improving page load time. The ActionWpPrintScripts function wraps this call inside an IF statement so the library is only loaded when the Template Widget is being used. It’s a good idea to do this so you avoid loading unnecessary javascript on pages that don’t use it. Likewise, the ActionAdminWpPrintScripts calls the function, IsPluginConfigPage, which checks to see if the user is looking at the plug-ins configuration page.

Next you should include the javascript files that performs the Ajax calls.

ActionWpPrintScripts:

wp_enqueue_script($this-&gt;pf.'js', $this-&gt;dir .'/js/js.php?url='.urlencode(get_bloginfo('url')));

ActionWpAdminPrintScripts:

wp_enqueue_script($this-&gt;pf.'admin_js', $this-&gt;dir.'/js/admin_js.php?url='.urlencode(get_bloginfo('url')));

These files can be found in the js/ folder. The JS files are saved as PHP, so that we can pass the blog’s url into the js files as query string variables. The following code demonstrates how to formulate an AJAX request that retrieves a result from the plug-in:

function B2Template_sample_data_save( content )
{
	var mysack = new sack(
		   "<!--?php $_REQUEST[ 'url']; ?-->/wp-content/plugins/b2_template/b2_template.php" );
 
	  mysack.execute = 1;
	  mysack.method = 'POST';
	  mysack.setVar( "B2Template_action", "SaveTableData" );
	  mysack.setVar( "B2Template_sample_table_data", content );
	  mysack.encVar( "cookie", document.cookie, false );
	  mysack.onError = function() { alert('Error saving data.' )};
	  mysack.runAJAX();
 
	  return true;
 
}

In the first line, we specify the path to the plugin file. This is the file we are going to hit to return our result. The next line specifies that our Ajax call is going to return javascript that we want to be executed upon successful completion. The next line specifies that we are using the POST method. Next we set the variables we want to send to the server. Setting B2Template_action to SaveTableData means our Custom Action (see above) will handle the event. The next line states that we also want to POST the users COOKIE variables to the server as well (this isn’t totally necessary in this case). The next line specifies the javascript function that should run in case an error occurs. The final line executes the request.

NOTE: The class function you call using Ajax should echo out any javascript you want to run on the client side once the request is complete, and should then end with a call to  exit();.

For more information on Ajax in plugins view the article on Ajax in the WordPress Codex.

Widgets

Making widgets with plugins is very easy. The function ActionWidgetsInit gets called in B2Template.class.php when WordPress is registering sidebar widgets. Simply place the following line inside that function to register a widget:

register_sidebar_widget('Template Widget', array($this, 'TemplateWidget'));

This line creates a Widget called “Template Widget”, and instructs WordPress to call the function TemplateWidget, inside this Class when it needs to get the Widget Content.

 function TemplateWidget( $args ) {
		extract($args);
 
		echo $before_widget.$before_title.__("Template Widget", $this-&gt;name). $after_title;
		echo __("Here is a list of interesting words: ", $this-&gt;name);
		echo '
<div id="'.$this-&gt;pf.'widget">
				'.$this-&gt;GetWidgetData().'</div>
';
		echo '
<form>
					<label><strong>'.__("Add your own", $this-&gt;name).'</strong></label>
<input id="'.$this-&gt;pf.'sample_table_data" name="'.$this-&gt;pf.'sample_table_data" type="text" />
<input onclick="'.$this-&gt;pf.'sample_data_save( document.getElementById(''.$this-&gt;pf.'sample_table_data').value )" type="button" value="'.__(" />name).'"/&gt;
				</form>
 
';
		echo $after_widget;
	}

This function prints out the widget content. It receives the variable $args, which is an array containing the HTML code the user has specified they want to place before the Widget, before the Widget title, after the Widget title, and after the Widget. (This lets them wrap your widget inside a LI list item, or inside DIV tags, to make it jive with the theme they are using.)

Internationalization

I won’t go too deep into detail about internationalizing your plug-in. It is a great idea to design your plugin to support this, and it’s really no extra work if you take this approach from the beginning. Suffice it to say, that whenever you display language-specific text to a user or administrator, you should wrap it a simple function that attempts to find a translation for your text. Here is an example:

echo "This is a piece of text that can't be translated";

becomes

echo __("This is a piece of text that can be translated", $this-&gt;name);

In this example, we are simply echoing out a piece of text. The second parameter specifies the namespace of the translation which we’ve set to be the Class name of the function. We need namespaces for translations to ensure our translations don’t conflict with those made for other plugins or in the WordPress core.

In order for translations to work, we need to call the function SetLanguage as soon as the plugin begins formulating output. This function, shown below, simply loads the translation textdomain.

function SetLanguage() {
load_plugin_textdomain( $this-&gt;name, WP_PLUGIN_DIR.'/'.$this-&gt;name.'/lang', $this-&gt;name.'/lang' );
}

Your plug-in is now ready to be translated, however, there are a few more steps to do before someone can actually translate your plug-in. For more information visit WordPress’ documentation on Plugin Internationalization.

Conclusion

Those are the basics of the plug-in. If you have any questions, comments or other feedback feel free to comment. If you are interested in contributing to this plug-in please let us know and we can add you to the WordPress SVN repository.