Feature
Post

Category
Code

Constructing a WordPress Plugin User’s Panel

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

There will be situations where you will have a main administrative panel, but would like individual users to set their own preferences. In the case of the Devlounge Plugin Series, we added an option for text to be added in at the end of each post. However, what if a logged-in user doesn’t want to see this text? Why not give them the option without affecting all of the other users?

This post will go over the steps to add in your own User’s Administration Panel.

Devlounge Plugin Series User’s Panel

Name Your User Options

class DevloungePluginSeries {
		var $adminOptionsName = "DevloungePluginSeriesAdminOptions";
		var $adminUsersName = "DevloungePluginSeriesAdminUsersOptions";

Line 3 shows where I added in the member variable called adminUsersName . I gave this variable the long and unique name of DevloungePluginSeriesAdminUsersOptions.

Set Your the Default User Options

You’re going to need a place to initialize your user options, especially when a user first activates your plugin. However, these options should also work outside of the admin panel where users may or may not be logged in.

Here’s the function I inserted in the DevloungePluginSeries class:

//Returns an array of user options
		function getUserOptions() {
			global $user_email;
			if (empty($user_email)) {
				get_currentuserinfo();
			}
			if (empty($user_email)) { return ''; }
			$devOptions = get_option($this->adminUsersName);
			if (!isset($devOptions)) {
				$devOptions = array();
			}
			if (empty($devOptions[$user_email])) {
				$devOptions[$user_email] = 'true,true';
				update_option($this->adminUsersName, $devOptions);
			}
			return $devOptions;
		}

What this function does is:

  • Checks to see if a user is logged in (lines 3 – 7). This is easily determined by checking to see if the user_email variable is set.
  • Attempts to find previous options that may have been stored in the database (line 8).
  • If options aren’t found, defaults are assigned (lines 9-15)
  • The options are returned for your use (line 16).

Initialize the Admin User Options

The getUserOptions can be called at anytime to retrieve the admin user options. However, what about when the plugin is first installed (er, activated)? There should be some kind of function that is called that also retrieves the user options. I added the following function into the init function:

function init() {
			$this->getAdminOptions();
			$this->getUserOptions();
		}

Line 3 calls the new function getUserOptions. Since there is already an action added that calls the init function, no extra steps are necessary.

How the Admin Panel and User Panel Will Work Together

You will recall from the last post about setting up an admin panel that the WordPress admin could set the content at the end of the post, whether code was shown in the header, and whether an author’s name was uppercase in the comments. The user’s panel allows users who aren’t admin to be able to specify whether they want these options or not.

We’re going to allow the user to decide if they:

  • Want content at the end of the post to show (only if the admin has this enabled already).
  • Wants the comment authors to be uppercase (only if the admin has this enabled already).

Set up the User’s Panel Function

The first thing we want to do is set up a function that will actually print out the user’s panel. The function’s name will be printAdminUsersPage. This next bit of code will read in the options we specified earlier and check to see if any post options have been submitted. All the code in this section is assumed to be within the printAdminUsersPage function.

//Prints out the admin page
				function printAdminUsersPage() {
					global $user_email;
					if (empty($user_email)) {
						get_currentuserinfo();
					}
					$devOptions = $this->getUserOptions();

					//Save the updated options to the database
					if (isset($_POST['update_devloungePluginSeriesSettings']) && isset($_POST['devloungeAddContent']) && isset($_POST['devloungeAuthor'])) {
						if (isset($user_email)) {
							$devOptions[$user_email] = $_POST['devloungeAddContent'] . "," . $_POST['devloungeAuthor'];
							?>
								<div class="updated"><p><strong>Settings successfully updated.</strong></p></div>
							<?php
							update_option($this->adminUsersName, $devOptions);
						}
					}
					//Get the author options
					$devOptions = $devOptions[$user_email];
					$devOptions = explode(",", $devOptions);
					if (sizeof($devOptions) >= 2) {
						$content = $devOptions[0];
						$author = $devOptions[1];
					}
					?>

The above code:

  • Retrieves the user options (line 7)
  • Saved post data (if available) to the database (lines 9 – 18)
  • Reads in comma-separated variables for the user.(lines 19-25)

The next bit of code will display the HTML form that is necessary for the user’s panel. All the code is doing is displaying the form elements and reading in options that were already retrieved.

<div class=wrap>
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
<h2>Devlounge Plugin Series User Options</h2>
<h3>Allow Content Added to the End of a Post?</h3>
<p>Selecting "No" will disable the content from being added into the end of a post.</p>
<p><label for="devloungeAddContent_yes"><input type="radio" id="devloungeAddContent_yes" name="devloungeAddContent" value="true" <?php if ($content == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?> /> Yes</label>&nbsp;&nbsp;&nbsp;&nbsp;<label for="devloungeAddContent_no"><input type="radio" id="devloungeAddContent_no" name="devloungeAddContent" value="false" <?php if ($content == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?>/> No</label></p>
<h3>Allow Comment Authors to be Uppercase?</h3>
<p>Selecting "No" will leave the comment authors alone.</p>
<p><label for="devloungeAuthor_yes"><input type="radio" id="devloungeAuthor_yes" name="devloungeAuthor" value="true" <?php if ($author == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?> /> Yes</label>&nbsp;&nbsp;&nbsp;&nbsp;<label for="devloungeAuthor_no"><input type="radio" id="devloungeAuthor_no" name="devloungeAuthor" value="false" <?php if ($author == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?>/> No</label></p>
<div class="submit">
<input type="submit" name="update_devloungePluginSeriesSettings" value="<?php _e('Update Settings', 'DevloungePluginSeries') ?>" /></div>
</form>
 </div>
					<?php
				}//End function printAdminUsersPage()

Set up the User’s Panel Action

While setting up the administrative panel, we specified a function called DevloungePluginSeries_ap that helped initialize the admin panel. We’re going to piggy back on this function in order to add in our user’s panel.

//Initialize the admin and users panel
if (!function_exists("DevloungePluginSeries_ap")) {
	function DevloungePluginSeries_ap() {
		global $dl_pluginSeries;
		if (!isset($dl_pluginSeries)) {
			return;
		}
		if (function_exists('add_options_page')) {
	add_options_page('Devlounge Plugin Series', 'Devlounge Plugin Series', 9, basename(__FILE__), array(&$dl_pluginSeries, 'printAdminPage'));
		}
		if (function_exists('add_submenu_page')) {
			add_submenu_page('profile.php', "Devlounge Plugin Series User Options","Devlounge Plugin Series User Options", 0, basename(__FILE__), array(&$dl_pluginSeries, 'printAdminUsersPage'));
		}
	}
}

On line 12, you can see a line of code that:

  • Adds a sub-menu to the profile.php page.
  • Let users with a user’s level greater than or equal to zero access to the user’s panel.
  • Calls our printAdminUsersPage function.

The access level (in this case a 0) is described in more detail at the Users Levels page in the WordPress codex.

Conclusion

We now have an user’s panel that allows users their own control whether certain content is shown or actions performed. The code to influence the behavior of the plugin was added to the downloadable example, but was not described here. You can download the current version of the Devlounge Plugin Series plugin regarding a user’s panel.

If you were to test out the plugin code above, the admin could specify the overall behavior, but a user could override that behavior depending on the settings specified.

Download the Code Used In This Post

For further reading, please check out these links:

Feature
Post

Category
Code

Constructing a WordPress Plugin Admin Panel

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

Any plugin that needs user input, such as changing a variable, should have some kind of administration panel. Building a administration panel isn’t all that difficult, so it annoys me when plugin authors decide not to build one and want plugin users to modify PHP code. Asking users — whose experience with PHP might be nil — to modify code is generally not a good idea. This post will go into what it takes to successfully create an admin panel for your plugin.

Devlounge Plugin Series Admin Panel

A Place to Store the Variables

One of the first problems you will likely encounter when constructing your own admin panel is where exactly to store the variables. Luckily WordPress makes it quite easy with options. I will explain options and database storage in a later post in this series. For now, all you have to do is nod your head and follow the steps to store your own admin variables in the WordPress database.

The first thing I usually do with regards to options is to assign a “unique” name for my admin options. I store this in the form of a member variable inside my class. In the case of the Devlounge Plugin Series plugin, I added this variable declaration to the DevloungePluginSeries class:

Name Your Admin Options

class DevloungePluginSeries {
		var $adminOptionsName = "DevloungePluginSeriesAdminOptions";
		function DevloungePluginSeries() { //constructor

		}

Line 2 shows where I added in my member variable. I named my variable adminOptionsName and gave it the long and unique value of DevloungePluginSeriesAdminOptions.

Set Your Admin Default Options

You’re going to need a place to initialize your admin options, especially when a user first activates your plugin. However, you also need to make these options upgrade-proof just in case you decide to add more options in the future. My technique is to provide a dedicated function to call your admin options. Your plugin needs may be different, but most admin panels aren’t incredibly complicated so one function for your admin options should be sufficient.

Here’s the function I inserted in the DevloungePluginSeries class:

//Returns an array of admin options
		function getAdminOptions() {
			$devloungeAdminOptions = array('show_header' => 'true',
				'add_content' => 'true',
				'comment_author' => 'true',
				'content' => '');
			$devOptions = get_option($this->adminOptionsName);
			if (!empty($devOptions)) {
				foreach ($devOptions as $key => $option)
					$devloungeAdminOptions[$key] = $option;
			}
			update_option($this->adminOptionsName, $devloungeAdminOptions);
			return $devloungeAdminOptions;
		}

What this function does is:

  • Assigns defaults for your admin options (lines 3 – 6).
  • Attempts to find previous options that may have been stored in the database (line 7).
  • If options have been previously stored, it overwrites the default values (lines 8 – 11).
  • The options are stored in the WordPress database (line 12).
  • The options are returned for your use (line 13).

Initialize the Admin Options

The getAdminOptions can be called at anytime to retrieve the admin options. However, what about when the plugin is first installed (er, activated)? There should be some kind of function that is called that also retrieves the admin options. I added the following function into the DevloungePluginSeries class:

function init() {
			$this->getAdminOptions();
		}

Short, sweet, and simple. An action, however, is required to call this init function.

add_action('activate_devlounge-plugin-series/devlounge-plugin-series.php',  array(&$dl_pluginSeries, 'init'));

This action is a little complicated, but easy to figure out. Here’s what the action does:

  • You tell it to run when a plugin has been activated.
  • You give it the path to the main plugin PHP file, which is devlounge-plugin-series/devlounge-plugin-series.php. This of course is assuming that your plugin is properly placed in the wp-content/plugins/ directory.
  • You pass a reference to the instance variable dl_pluginSeries and call the init function.

So anytime the plugin is activated, the init function is called for the Devlounge Plugin Series plugin.

How the Admin Panel Works

Before I delve into the code of constructing the actual admin panel, it will be beneficial to describe the behavior of the admin panel. Here are the steps you’ll want to take for setting up your admin panel:

  • Check to see if any form data has been submitted.
  • Output notifications if form data is present.
  • Display the admin panel options.

One thing that may confuse you greatly in the admin panel is the use of the _e WordPress function. The _e function allows WordPress to search for a localized version of your text. This will help WordPress potentially translate your plugin in the future. The function works like a normal echo, but instead you pass it your text and an identifier variable (typically your plugin name). An example would be:

_e('Update Settings', 'DevloungePluginSeries')

This code would work the same way as: echo "Update Settings".

Set up the Admin Panel Function

The first thing we want to do is set up a function that will actually print out the admin panel. The function’s name will be printAdminPage. This next bit of code will read in the options we specified earlier and check to see if any post options have been submitted. All the code in this section is assumed to be within the printAdminPage function.

//Prints out the admin page
		function printAdminPage() {
					$devOptions = $this->getAdminOptions();

					if (isset($_POST['update_devloungePluginSeriesSettings'])) {
						if (isset($_POST['devloungeHeader'])) {
							$devOptions['show_header'] = $_POST['devloungeHeader'];
						}
						if (isset($_POST['devloungeAddContent'])) {
							$devOptions['add_content'] = $_POST['devloungeAddContent'];
						}
						if (isset($_POST['devloungeAuthor'])) {
							$devOptions['comment_author'] = $_POST['devloungeAuthor'];
						}
						if (isset($_POST['devloungeContent'])) {
							$devOptions['content'] = apply_filters('content_save_pre', $_POST['devloungeContent']);
						}
						update_option($this->adminOptionsName, $devOptions);

						?>
<div class="updated"><p><strong><?php _e("Settings Updated.", "DevloungePluginSeries");?></strong></p></div>
					<?php
					} ?>

All the above code does is load in the options and test to make sure each portion of the form is submitted. The if-statement overkill isn’t necessary, but sometimes it is useful for debugging. The first form variable that is tested as being set is update_devloungePluginSeriesSettings. This variable is assigned to our “Submit” button. If that isn’t set, it’s assumed that a form hasn’t been submitted.

As promised, in line 16, I use the apply_filters function to format the content for saving in the database.

The next bit of code will display the HTML form that is necessary for the admin panel. It’s a little involved, so I’ll summarize it here. All the code is doing is displaying the form elements and reading in options.

<div class=wrap>
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
<h2>Devlounge Plugin Series</h2>
<h3>Content to Add to the End of a Post</h3>
<textarea name="devloungeContent" style="width: 80%; height: 100px;"><?php _e(apply_filters('format_to_edit',$devOptions['content']), 'DevloungePluginSeries') ?></textarea>
<h3>Allow Comment Code in the Header?</h3>
<p>Selecting "No" will disable the comment code inserted in the header.</p>
<p><label for="devloungeHeader_yes"><input type="radio" id="devloungeHeader_yes" name="devloungeHeader" value="true" <?php if ($devOptions['show_header'] == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?> /> Yes</label>&nbsp;&nbsp;&nbsp;&nbsp;<label for="devloungeHeader_no"><input type="radio" id="devloungeHeader_no" name="devloungeHeader" value="false" <?php if ($devOptions['show_header'] == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?>/> No</label></p>

<h3>Allow Content Added to the End of a Post?</h3>
<p>Selecting "No" will disable the content from being added into the end of a post.</p>
<p><label for="devloungeAddContent_yes"><input type="radio" id="devloungeAddContent_yes" name="devloungeAddContent" value="true" <?php if ($devOptions['add_content'] == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?> /> Yes</label>&nbsp;&nbsp;&nbsp;&nbsp;<label for="devloungeAddContent_no"><input type="radio" id="devloungeAddContent_no" name="devloungeAddContent" value="false" <?php if ($devOptions['add_content'] == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?>/> No</label></p>

<h3>Allow Comment Authors to be Uppercase?</h3>
<p>Selecting "No" will leave the comment authors alone.</p>
<p><label for="devloungeAuthor_yes"><input type="radio" id="devloungeAuthor_yes" name="devloungeAuthor" value="true" <?php if ($devOptions['comment_author'] == "true") { _e('checked="checked"', "DevloungePluginSeries"); }?> /> Yes</label>&nbsp;&nbsp;&nbsp;&nbsp;<label for="devloungeAuthor_no"><input type="radio" id="devloungeAuthor_no" name="devloungeAuthor" value="false" <?php if ($devOptions['comment_author'] == "false") { _e('checked="checked"', "DevloungePluginSeries"); }?>/> No</label></p>

<div class="submit">
<input type="submit" name="update_devloungePluginSeriesSettings" value="<?php _e('Update Settings', 'DevloungePluginSeries') ?>" /></div>
</form>
 </div>
					<?php
				}//End function printAdminPage()

One observation to make in the above code is the reference to the options and how the HTML and PHP is integrated.

Set up the Admin Panel Action

Now the the printAdminPage function is added, we need to call it through an action. First a function must be set up right above the actions that it outside the scope of the class.

//Initialize the admin panel
if (!function_exists("DevloungePluginSeries_ap")) {
	function DevloungePluginSeries_ap() {
		global $dl_pluginSeries;
		if (!isset($dl_pluginSeries)) {
			return;
		}
		if (function_exists('add_options_page')) {
	add_options_page('Devlounge Plugin Series', 'Devlounge Plugin Series', 9, basename(__FILE__), array(&$dl_pluginSeries, 'printAdminPage'));
		}
	}
}

The above code does this:

  • A function named DevloungePluginSeries_ap is created.
  • Variable dl_pluginSeries is tested for existence (lines 4 – 7). This variable references our class.
  • An admin page named “Devlounge Plugin Series” is initialized and our printAdminPage function is referenced (lines 8-10).

The add_options_page function format is described by WordPress as: add_options_page(page_title, menu_title, access_level/capability, file, [function]);

The access level (in this case a 9) is described in more detail at the Users Levels page in the WordPress codex.

An action must now be set up to call the DevloungePluginSeries_ap function:

add_action('admin_menu', 'DevloungePluginSeries_ap');

Conclusion

We now have an admin menu that we can use to set our plugin’s behavior. The code to influence the behavior of the plugin was added, but was not described here. You can download the current version of the Devlounge Plugin Series plugin regarding administrative panels.

If you were to test out the plugin code above, you would see an admin panel for the plugin and be able to manipulate its output.

Download the Code Used In This Post

For further reading, please check out these links:

Feature
Post

Category
Code

WordPress Plugin Filters

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

WordPress filters are the functions that your plugin can hook into with regards to modifying text. This modified text is usually formatted for either inserting into a database or displaying the output to the end user.

WordPress filters allow to you modify virtually any kind of text displayed and are extremely powerful. WordPress filters allow you to modify posts, feeds, how authors are displayed in comments, and much, much more.

To demonstrate the usefulness of WordPress filters, we will continue working with the existing code in the Devlounge Plugin Series code from the WordPress Plugin Actions post.

Adding A Content Filter

One of the cool filters you can hook into is one called ‘the_content‘. This particular filter is run for post content being displayed to the browser. We’re going to just add a line of text that will be displayed at the end of the content.

The format for adding a filter from the WordPress Plugin API is: add_filter('hook_name', 'your_filter', [priority], [accepted_args]);

We just need to add in a function to the DevloungePluginSeries class. Let’s call it addContent.

function addContent($content = '') {
			$content .= "<p>Devlounge Was Here</p>";
			return $content;
		}

In the above code, the following things are happening.

  • The above function will accept one variable named content.
  • If no variable is passed, a default value is set.
  • The content variable has our line of text added to it.
  • The text is then returned.

After the function is added to the class, the next step is to hook into the ‘the_content‘ filter and call the function.

//Actions and Filters
if (isset($dl_pluginSeries)) {
	//Actions
	add_action('wp_head', array(&$dl_pluginSeries, 'addHeaderCode'), 1);
	//Filters
	add_filter('the_content', array(&$dl_pluginSeries, 'addContent'));
}

As you can see on line 6, a filter with the name ‘the_content‘ is added and our function ‘addContent‘ is called.

If the plugin were activated and a post was viewed, the text “Devlounge Was Here” would show up towards the end of the post content.

Adding An Author Filter

Another example of a filter I will show is manipulating the display of comment authors. I’m simply going to make all authors uppercase.

We just need to add in a function to the DevloungePluginSeries class. Let’s call it authorUpperCase.

function authorUpperCase($author = '') {
			return strtoupper($author);
		}

In the above code, the following things are happening.

  • The above function will accept one variable named author.
  • If no variable is passed, a default value is set.
  • The author string is returned as uppercase.

After the function is added to the class, the next step is to hook into the ‘get_comment_author‘ filter and call the function.

//Actions and Filters
if (isset($dl_pluginSeries)) {
	//Actions
	add_action('wp_head', array(&$dl_pluginSeries, 'addHeaderCode'), 1);
	//Filters
	add_filter('the_content', array(&$dl_pluginSeries, 'addContent'));
	add_filter('get_comment_author', array(&$dl_pluginSeries, 'authorUpperCase'));
}

As you can see on line 7, a filter with the name ‘get_comment_author‘ is added and our function ‘authorUpperCase‘ is called.

If the plugin were activated and a post with comments was viewed, the comment authors would all be upper case.

Applying Filters

One of the more powerful things you can do with filters is to call then dynamically. There’s no need to add a filter to be run every time. You can run a filter whenever you choose from within your code.

The format for the apply_filters function is: apply_filter('filter name', 'your text');

You will see an example of apply_filters in use later in this series.

Conclusion

Hopefully you have a good understanding of the capability of WordPress Plugin Filters. You can download the code for the Devlounge Plugin Series filter portion.

Download the Code Used In This Post

For some further reading, please check out these links:

Feature
Post

Category
Code

WordPress Plugin Actions

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

WordPress actions allow you as a plugin author to be able to hook into the WordPress application and execute a piece of code. An example of an action would be that you want a execute some code after a user has published a post or left a comment.

Some of the actions that I use heavily are:

  • admin_menu: Allows you to set up an admin panel for your plugin.
  • wp_head: Allows you to insert code into the <head> tag of a blog

Actions in Action

While defining the structure of a WordPress plugin, I left a place holder for some actions. In this example, we are going to set up a piece of code that will run inside the <head> tag of a WordPress blog.

First we need to add a function into our DevloungePluginSeries class.

function addHeaderCode() {
			?>
<!-- Devlounge Was Here -->
			<?php

		}

All the above function does is output an HTML comment. Rather simple, but you could output just about anything. To call this function, we add an action.

//Actions and Filters
if (isset($dl_pluginSeries)) {
	//Actions
	add_action('wp_head', array(&$dl_pluginSeries, 'addHeaderCode'), 1);
	//Filters
}

From the WordPress Plugin API page, the add_action structure is as follows:
add_action ( 'hook_name', 'your_function_name', [priority], [accepted_args] );

Since we are calling a function inside of a class, we pass the action an array with a reference to our class variable (dl_pluginSeries) and the function name we wish to call (addHeaderCode). We have given our plugin a priority level of 1, with lower numbers executed first.

Running the Code

If the Devlounge Plugin Series plugin is activated, the comment of “Devlounge was here” should show up when you go to View->Source in your web browser when looking at your main blog site.

Removing Actions

If your plugin dynamically adds actions, you can dynamically remove actions as well with the remove_actions function. The structure is as follows:
remove_action('action_hook','action_function').

Conclusion

Hopefully this post gave you some insight into what you could do when hooking into WordPress actions. Once again, you can download the code for the sample Devlounge Plugin Series for actions.

Download the Code Used In This Post

For further reading, please check out these links:

Feature
Post

Category
Code

Structure of a WordPress Plugin

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

One of the more important aspects of developing a WordPress plugin is how you structure it. This post will go over some tips on how to structure your plugin to organize your plugin resources and avoid naming collisions. Each plugin author is different in the way they structure a plugin, so these tips are merely my own personal preference. I’ll first briefly describe how a WordPress plugin works and then go into a plugin’s structure.

How a WordPress Plugin Works

After placing a WordPress plugin into the “wp-content/plugins/” folder, the plugin should automatically be available to install.

When a plugin is “Activated”, this tells WordPress to load your bit of code on “each” page (including admin pages). This is why if you have many plugins activated, your WordPress installation may be very slow due to the amount of code being included.

Since WordPress loads your code automatically when the plugin is activated, you can take advantage of this by tapping into the WordPress Plugin Application Program Interface (API). You can also access the WordPress template tags or create your own.

I suggest reading into the WordPress loop if you plan on making changes to the post content or comments. The WordPress loop is the loop that displays your posts. Some template tags will not work outside of this loop, so it is imperative that you know exactly where your code is executing. You can control this by taking advantage of actions and filters, which will be explained in later posts.

Folder Structure

All WordPress plugins will be installed in the wp-content/plugins directory. Some plugin authors simply include a PHP file for their plugin, but I recommend always creating a folder to store your plugin.

I typically structure my plugin in this folder structure:

  • Plugin Folder Name (The name of your plugin with no spaces or special characters)
    • Main plugin php file
    • js folder (for JavaScript files)
    • css folder (for StyleSheet files)
    • php folder (for other PHP includes)

For example purposes, here is a sample structure I have created:

  • devlounge-plugin-series
    • devlounge-plugin-series.php
    • js
    • css
    • php

Within the devlounge-plugin-series folder, I would include just the main PHP file and put all other files in their respective folders. This structure will assist other plugin authors who look at your code to be able to tell what the main plugin file is and where all the supporting files are located.

WordPress also recommends placing images in their own directory and including a read me file for your plugin.

Main Plugin File

When you start a new plugin file, the first seven lines are the lines that describe your plugin.

<?php
/*
Plugin Name: Your Plugin Name Here
Plugin URI: Your Plugin URI
Version: Current Plugin Version
Author: Who Are You?
Description: What does your plugin do?

Line 3 allows you to name your plugin. Line 4 allows you to point a user to the web location of your plugin. Line 5 allows you to specify the current version. Line 6 allows you to specify the author of the plugin. Line 7 allows you to describe your plugin.

Shown below is an example of the code filled out:

<?php
/*
Plugin Name: Devlounge Plugin Series
Plugin URI: http://www.devlounge.net/
Version: v1.00
Author: <a href="http://www.ronalfy.com/">Ronald Huereca</a>
Description: A sample plugin for a <a href="http://www.devlounge.net">Devlounge</a> series.

Shown below is a screenshot of what the plugin would look like in the WordPress Plugins panel.

Devlounge Plugin Screenshot

Set Up a Class Structure

You don’t have to be incredibly familiar with PHP Classes to develop a WordPress plugin, but it sure helps. A class structure is necessary in order to avoid naming collisions with other WordPress plugins. If someone out there sets up the same function name as yours in a plugin, an error will result and WordPress will be rendered inoperable until that plugin is removed.

To avoid naming collisions, it is imperative that all plugins incorporate a PHP class structure. Here is some bare-bones code that will allow you to set up a class structure.

if (!class_exists("DevloungePluginSeries")) {
	class DevloungePluginSeries {
		function DevloungePluginSeries() { //constructor

		}

	}

} //End Class DevloungePluginSeries

What the above code does is checks for the existence of a class named DevloungePluginSeries. If the class doesn’t exist, the class is created.

Initialize Your Class

The next bit of code will initialize (instantiate) your class.

if (class_exists("DevloungePluginSeries")) {
	$dl_pluginSeries = new DevloungePluginSeries();
}

All the above code checks for is if the class DevloungePluginSeries has been created. If it has, a variable called $dl_pluginSeries is created with an instance of the DevloungePluginSeries class.

Set Up Actions and Filters

The next bit of code sets up a place holder for WordPress actions and filters (which I will go over in a later post).

//Actions and Filters
if (isset($dl_pluginSeries)) {
	//Actions

	//Filters
}

?>

The above code checks to make sure the $dl_pluginSeries variable is set. If it is (and that’s only if the class exists), then the appropriate actions and filters are set up.

Conclusion

The post served as a very basic foundational structure for starting a WordPress plugin. If you want to download the sample code, please feel free. The code will be available after almost every post in this series for you to dig through.

Download the Code Used In This Post

Digging through plugin code is a great way to learn the in’s and out’s of plugin design. I still do it, and I learn something new almost every time. Thank you Lewis for the tip suggestion.

For further reading, please check out these links:

Feature
Post

Category
General

How to Get Ideas for WordPress Plugins

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

If you are convinced that you would like to investigate the possibility of creating your own WordPress plugin, it may be hard to think of that idea that will allow you to take the plunge. Fortunately, there are many places to find inspiration regarding developing your own WordPress plugin. Within this post, I will list several ways to get ideas for your very own WordPress plugin.

Listen to your Readers

Your readers are a valuable asset when it comes to getting ideas for plugins. For example, a reader might request an easy way to reply to or edit comments. Since blog readers are the ones who use your blog the most, they have a unique insight in what they want out of your blog. Just the other day, one of my readers asked me to have a way to preview a comment before posting. Luckily there is already a few plugins out there for that, but sometimes your readers will suggest something that has yet to be implemented as a plugin.

Listen to Yourself

“If only WordPress could do…”

If you find that WordPress lacks a feature that you truly want, why not program it yourself in the form of a plugin? Chances are that if you desire the feature added, others will too.

Check out Blogging Resources

Sites such as The Blog Herald and Weblog Tools Collection are great resources for plugin ideas. On Wednesday, The Blog Herald has a column called WordPress Wednesday. Within this column are plugin requests and a “wishlist” for WordPress. Weblog Tools Collection typically has a plugin announcement almost every day, and from there you can get an idea of what kind of plugins people are churning out.

Check out the WordPress Support Forums

The WordPress Support Forums are full of people looking for help on extending their WordPress blog. A particularly useful forum for plugin ideas is the Requests and Feedback forum. Another area is the WordPress ideas page.

Investigate APIs

Online services such as Flickr, FeedBurner, Google Maps, and others have APIs (Application Program Interfaces) that allow third-party applications the ability to interface with their services. Through these APIs, you start programming your own WordPress solution.

If there is a service that you really like, but you would like to see it included in WordPress, investigate the service’s API and see if it would make a good plugin.

Third Party Applications

There are many third-party applications that people may have installed along with a WordPress blog. Examples of such programs are Mint, Vanilla, and many others. Why not develop a WordPress plugin that integrates these third-party applications into a WordPress blog?

Existing WordPress Plugins

If you find a WordPress plugin you really like and would like to branch out with your own idea, feel free to do so. If you don’t like the implementation of a particular plugin, build your own implementation. There are many plugins out there that essentially do the same thing, but are all slightly different.

Conclusion

Hopefully you now have several resources for you to go out and find ideas for that next WordPress plugin. If you have any further suggestions regarding getting ideas, please share them in the comments.

Feature
Post

Category
General

Seven Reasons to Write a WordPress Plugin

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

While writing the “How to Write a Plugin” series, I thought it would be beneficial to list some reasons why WordPress users would want to write a WordPress plugin in the first place.

Listed below are seven reasons why a WordPress user should consider writing a WordPress plugin.

You like a plugin’s idea, but don’t like the plugin’s implementation

Whether discovering WordPress plugins on Weblog Tools Collection, the official WordPress plugins directory, or the WordPress Plugin Database, you will inevitably find a plugin that meets your needs — sort of.

You like the idea of the plugin, but not really the approach the plugin author took with it. Why not run with the original idea and create your own separate version?

You want to modify existing plugin code

Sometimes the plugin’s output needs to be tweaked a little bit or some functionality you would like is missing. You can try convincing the plugin author to add your feature, but plugin authors are usually quite busy or they may not like your suggestion. It takes a lot of effort by a plugin author to provide support and field feature and bug requests for a plugin that is free. Sometimes the plugin is no longer supported by anyone.

In the event the plugin author is unable to your needs, it will be up to you to take the initiative and modify the existing plugin code. If you do a good enough job and make enough changes, you can re-release the plugin as long as the original plugin was released under a GPL compatible license.

Usually one of the first things I do when I install or test a new plugin is to look at the code and see what I can modify, what I can’t modify, and what I can possibly add or take away.

You want to extend a plugin

Sometimes a plugin is good as it is, but you would like to build upon it and release your own version. For example, you may think a plugin would work better using AJAX, or would like to add more hooks so that it is compatible with other plugins. You may want to add an admin panel so you don’t have to dig through the code to change the output.

As stated earlier, if a plugin is released as GPL compatible, you are free to release your own version.

You want portable theme code

For those of us who opted to build a custom theme from scratch rather than download one, you may find yourself re-using code snippets all over the place. Wouldn’t it be better just to write your own plugin that combined all the little code snippets so that you could use them as template tags?

The beauty of template tags is that you can re-use them over and over for your theme and any future ones you build. And you only have one place to change the code rather than several.

You are a theme designer

I would argue that if you are a template designer for WordPress, the next logical step is to be a plugin author. Writing plugins gives you a more intimate knowledge of how WordPress behaves and allows you to extend the functionality of your released themes.

You want to make money

A good plugin author can usually get paid on the side for custom work. Some plugin authors take donations as well or charge extra for providing support or for consulting.

If you are a custom theme designer, you can package your custom plugins in with the theme for an extra charge.

You want incoming links

When launching the Reader Appreciation Project, one of the goals I had was to rapidly build incoming links. The best way I knew how was to write some WordPress plugins and promote them. One of my plugins (WP Ajax Edit Comments) turned out to be very popular and has currently generated more than 100 incoming links.

Conclusion

As you can see from the reasons listed above, there are many reasons to write a WordPress plugin. My next post in the series will go over how to get plugin ideas.

If you have any more reasons that I did not mention, feel free to add them in the comments.

Feature
Post

Category
General

How to Write a WordPress Plugin – Introduction

How To Write a WordPress Plugin Series

This post was written as part of the How to Write a WordPress Plugin series.

For any WordPress user, plugins are essential. WordPress Plugins allow those with little to no programming skills to extend the functionality of their blog. Plugins come in all shapes and sizes, and there is a plugin that does just about anything for WordPress.

As good as WordPress is as a standalone application, there are still things that WordPress lacks. Users are requesting more and more features for WordPress that would be very feasible to write as a plugin. There are many untapped ideas out there, and new ones created every day.

Having released three plugins already (not counting the custom ones I wrote), I am aware of some of the limitations of WordPress and wish to share some of the lessons I have learned (and am still learning) about creating WordPress plugins. As a result, I will be starting series that will discuss various topics regarding writing your own WordPress plugin. The series will start off very introductory and will assume your plugin knowledge is zilch.

Who is this Series For?

This series is for any WordPress user who is curious about or wants to learn how to write their own WordPress plugin. Readers of this series will have an intermediate knowledge of PHP, know a little JavaScript, and be decent at Cascading Style Sheets.

This plugin series will benefit theme designers, those that like to tinker with plugin code, and those that are interested in writing their own plugin from scratch.

Tools to Get the Job Done

To write plugins, any text editor will do. Here are the tools I personally use to create plugins.

This series assumes you have WordPress 2.1.x or greater installed.

Code Samples

All code I use will be available for download after each post in the Conclusion section. I will be building the code as I go along, so each download will be different. I will be creating a plugin that doesn’t really do anything other than to show you the basics of how a plugin works.

Since each post in this series builds on top of each other, it is recommended to read this series in the order it is presented.

I highly recommend not using the test plugin on a production WordPress installation. Instead, use a local WordPress installation.

Topics

I plan to start off really basic and move quickly into the more hard-core WordPress plugin functions. This series will not be a comprehensive micro-detail of plugin development, but will hopefully give you a nice foundation to start your own plugin development. If you have any questions or suggestions, please leave a comment or e-mail me using the Devlounge contact form (Ronald). I do ask that you not rely on Devlounge for support and instead use the WordPress Support forums.

Techniques

Some of the techniques I use in my code samples may not be the best way to present code and you may be cringing because I don’t have a lot of shortcuts. I apologize in advance. Everybody has a different coding style.

As far as plugin techniques, structure, behavior, and other nuisances, if there is a better and easier way that I overlooked, I am all ears (er, eyes).

Series Publication Schedule

A post from this series is planned to be published every two days. To stay up to speed on the series, I suggest you subscribe to the Devlounge feed.

Conclusion

Thank you for reading the series introduction. My hope is that this series will prove beneficial to the readers. Any feedback is welcome. Thank you.

Feature
Post

Category
General

Google Personalized Homepage Now Has Themes

The Google Personalized Homepage is a great tool for adding feeds and also showing the latest posts from Google Reader and Google Mail.

I noticed today that you can now select certain themes for your Personalized Homepage. Most of the themes I tried actually update themselves to local weather conditions. I hope Google allows users to submit their own themes soon.

Google Themes

Feature
Post

Category
Strategy

Ten Tips for Coordinating Clients in a Corporate Environment

Whether you’ve been put in charge of your corporate website, or you’re a freelancer who’s been hired on, designing a website for a corporation is never routine. There are turf wars, inner-departmental battles, upper management issues, and precedent that you must deal with.

Typically with freelancer jobs, there is only one client. However, in a corporation, there are many clients that you will have to deal with. These clients could be head of certain departments, divisions, or offices.

Listed below are ten short tips for coordinating clients in a corporate environment. These tips are listed in no particular order.

Establish Authority

Sometimes you will have to remind the clients that there is a reason that you are the web developer and they are not. There are times you will have to deal with a client that might actually know something about web development and questions you on a particular design decision. During these intense moments, it is crucial to listen and state your logical reasoning behind making a design decision.

The problem with dealing with multiple clients is that each one has a different idea of how a website should behave. You need to be empowered to make the final decision, however. Design by committee is never a good thing. Establish your authority to make the design decisions and make sure the upper management will back you when your client screams that web sites should never scroll.

Get Upper Management Cover

When you inevitably step on someone’s toes, it is important that the upper management has your back if a client strongly disagrees. One of your first jobs is to assure the upper management that you are the expert in web development. If a client then starts a fire, the upper management will be able to quickly put it out.

Get to Know Your Clients

In any working environment, it’s extremely helpful and beneficial to get to know people outside of work. Go out to lunch with your clients. Get to know them. If you start to get to know them on a personal level, the clients will be more willing to help you do your job.

Establish a Style Guide

Establishing a style guide is crucial. Style guides not only define the look and feel of the site, but also the behavior. A style guide will also force you as a designer to think through your decisions from beginning to end. The corporation may already have some kind of style guide. If that is the case, use that guide as a foundation for yours. The web style guide should be different, but do not venture too far away from the corporate style guide if there is one.

An example of a good style guide is A List Apart’s style guide.

How you do your style guide is up to you. If the style guide has upper management approval, you’ll have a standard to fall back on when someone disagrees with a certain part of the design.

Establish Single Points of Contact

When dealing with departments or divisions, it is absolutely critical that there is a single point of contact for each one. If you don’t have a single point of contact, then there will be nothing to stop dozens of different people from contacting you and flooding you with content changes, design “suggestions”, and the like.

Get the Clients Involved

Allow the clients to see your progress. It’s one thing to constantly ask the client for information and the client has no idea why he/she is doing the extra work. It’s another to show the client the work you are doing so that the client knows what the end result will be. It’s an extra way to show that the client’s feedback and contributions matter.

Get the Right Tools

Make sure you communicate to your upper management the tools you need. If the corporation does their own hosting, make sure you have the privileges to build the website. If the corporation needs to make a hardware/software purchase, make it very clear that without these tools, you will not be able to do your job. The point here is to get what you need up front.

Know the Key Players

Get to know the names and locations of all of the key players in the corporation. These key players will be upper management, the database administrators, the IT people, and the department heads. These key players can either make your job easier, or make it a living hell. Make sure each of these key players knows why you are there and what job you are trying to accomplish.

Educate Your Clients/Upper Management

While it is important to not overwhelm your clients with techno-speak, it is also important to educate them as to the benefit of the latest design techniques such as web standards. Since most of the clients won’t know the difference between MS Outlook and Web 2.0, educating your clients is more of a “show and tell” type thing. Show your clients why you are doing things rather than telling them about it.

Educate Yourself

The last tip doesn’t necessarily have to deal with coordinating clients, but it is important to stay on top of your industry. If you are a freelancer, make sure you take the time to learn new skills. If you are a corporate employee doing webmaster duties, try to convince the upper management of the importance of giving you time to learn new skills (such as training and seminars).

Conclusion

I hope you found these tips helpful. If you have your own tips for working within corporate environments, please share them in the comments.

Thank you for reading.

Feature
Post

Category
Publishing

WebEdit Professional

Every designer/developer at one point needs to think of a system to manage their content. Content management systems (CMS) have literally changed the way designers design. With most content management system requiring themes, designers have to design immense flexibility into a layout.

What makes content management systems so powerful is their extendability. Platforms that can be used as a CMS (such as WordPress and Drupal) have a strong community following and have made almost anything possible with the platforms as far as managing content goes.

One of the benefits of good content management system is the ability for non-techies to update websites. In an ideal corporate environment, every department would be in charge of updating their web content. Unfortunately, this is not always the case and the work usually gets piled onto a webmaster figure. WebEdit Professional tries to make it easier for website collaboration on a large scale. The rest of this article is dedicated to a review of WebEdit Professional and explains the strengths and weaknesses of the application. One thing to note is that for this review, I only had access to their online demo, which means I wasn’t able to try out their install or theme creation process.

What is WebEdit Professional?

WebEdit Professional is geared towards designers/developers who want to allow the clients to update a website themselves. WebEdit allows clients to edit specific sections of a site with a very robost WYSIWYG editor (clients can also edit the raw HTML if desired). Clients are able to create and modify new files and upload images and other objects without the need for an FTP client.

The File Manager

WebEdit Professional File Manager

After logging in to the CMS, you are taken to a file manager. The file manager is nothing special, but it does the job. I’m personally not fond of the approach of the file manager because it requires the end user to have a vague familiarity with a file system and the site’s structure. If you’ve ever been in a corporate environment, there are still some people that raise an eyebrow when you tell them to save an item to the desktop.

Adding a File

Upload or Add Pages

The CMS allows you to upload a file or start a new page. However, my attempt to upload a file resulted in an error, “A File Name MUST contain a valid extension.” This begs the question of, “What is a valid extension for a file?” For those wondering, I attempted to upload a CSS file.

Defeated in my effort to upload a stylesheet, I decided to create a new page.

WebEdit - Creating a New Page

When creating a new page, you are taken to a new screen that allows you to select a theme and specify the file’s name.

One thing to remember here is that this CMS is supposed to be geared towards the non-tech savvy people. Is having to select a page theme and typing out a full file name intuitive for a non-techie? I leave that answer open for debate.

Upon creating my new file, I was taken back to the file manager. I would have liked to have been taken straight to the editor rather than having to search for my newly created file.

The WYSIWYG Editor

Central to any CMS is the WYSIWYG editor. In my opinion, this is the make-or-break for any CMS. I have to admit that I was fairly impressed with the CMS until I noticed a few things that I simply could not overlook.

WebEdit - Firefox Restrictions

The first odd thing I noticed was this little message at the bottom of the WYSIWYG that said, “FireFox Restrictions.” The popup window that came up after I clicked on the message explained to me about typing in about:config and finding some value and changing it so that the WYSIWYG would work fully. This restriction only affects the Copy, Cut, and Paste portions of the WYSIWYG and does not disable the standard Windows keyboard shortcuts.

WebEdit - Text Overlap

The WYSIWYG is very well done, but there are some issues. After adding in a “text box” and typing some text, some weird overlap occurred. I went to view the source code and was stung by the bitter aroma of tag soup.

WebEdit - Source Code

After seeing this mess, I tried adding in my own doctype and formatting the HTML so the code would actually validate. The CMS actually reversed all of the changes I made that were not inside the BODY tag. The WebEdit Pro website says that the CMS is XHTML compatible. I would love to see a working example.

One other thing that threw me for a loop was the ability to add form elements in a page. I’m really scratching my head on this one and perhaps I’m missing something, but if someone includes a form on a page, someone else is going to have to write the back-end to handle that form (and then there’s form validation). Below is a screenshot of the full WYSIWYG with one form element on the page. For more screenshots of the WYSIWYG, WebEdit has several screenshots available.

WebEdit - WYSIWYG Editor

Targeted Editing – Restricted Templates

One last feature of the CMS I will mention is the ability to select which portions of a theme are editable by the end user.

WebEdit - Restricted Templates

The areas in blue are the only areas allowed to be edited by the end user. As cool as this feature is, there is one serious flaw in the technique. The same problem that popped up with the WYSIWYG and the “FireFox Restrictions” is a little more prevalent. Until the end user performs all the steps to resolve this restriction, the restricted template is truly restricted. I suppose the end user better use Internet Explorer.

Conclusion

WebEdit Professional is a decent CMS. However, I am reluctant to recommend it because I don’t think its easy to use and the browser limitations are just silly.

I can definitely see why some designers would want something like this so that they can rebrand the CMS and sell it (with a nice profit) to their clients. However, I’m not entirely sure the price tag ($179) is worth the price of this CMS when there are several open source alternatives (including Drupal) that seem to have similar (if not better) functionally and ease-of-use. Drupal, for example, is extendable via plugins while WebEdit is not.

WebEdit has a very well done WYSIWYG, but the non-standard code, browser limitations, and usability issues drag it down. WebEdit is a good CMS for those that need a CMS not requiring a database, but for the price and the features, I would recommend seeking an alternative.

The review you just read was a paid review for WebEdit Professional. This is my first paid review I have attempted and am open to any feedback (positive or negative). Thank you. – Ronald

Feature
Post

Category
Webapps

Gravatar Beta Review

Bes Zain — a former Gravatar moderator — helped contribute to this article.

As reported earlier, the Gravatar Public Beta is live. Within this review, you’ll find screenshots and my opinions of Gravatar’s new features. Please note that Gravatar is a paid service ($10) if you want more than two gravatars and/or more than one e-mail address.

Registration

Since I was already registered for Gravatar, I didn’t need to re-register which was nice. And my old Gravatar was there as well. The main screen — dubbed My Gravatars — shows which gravatars you have and allows you to add additional gravatars and/or e-mail addresses.

Gravatar Public Beta - Logged In Screen

Adding a Gravatar – Image Uploading

Since I didn’t particularly like my old gravatar, I decided to add in another one. Gravatar allows you to upload a picture from your computer (the file I used was 1.55 MB) and crop it from there.

One thing I’d like to see here is a status indicator for the image upload and also a limit on the file size uploaded.

Gravatar Public Beta - Image Upload Screen

Cropping the Gravatar

Now that I had my spiffy picture uploaded, I wanted to crop it. Gravatar conveniently has a cropping tool that allows you to easily do this. One thing I did notice is that the cropping tool gives you much more control when the picture is at a higher resolution.

Gravatar Public Beta - Cropping Tool

Rating the Gravatar

Once my gravatar was all cropped and ready, I got to rate it. As tempted as I was to rate my gravatar “X”, I decided to give my gravatar the Disney friendly “G” rating.

Gravatar Public Beta - Rating Mechanism

There is a potential for abuse here, but I’m glad Gravatar decided to allow users to rate their own gravatars. However, I foresee a problem with the reporting mechanism for abuse. What if it takes too long for an offending gravatar to be taken down? What if the admin is on vacation or something?

When reporting an “under-rated” gravatar, all you can enter in is the offending URL and an explanation. What I think should happen here is that the user can enter in the gravatar’s URL and give the gravatar a suggested rating. If enough users change the rating (say from G to X), then the offending gravatar is automatically changed to a neutral image until the owner of the gravatar changes it and/or the rating.

The owner of the offending gravatar would get a message telling him/her that the gravatar has been labeled as offensive. The owner can then appeal the offensive rating or change the gravatar and/or rating, which will then go into an admin queue. This takes the admin mostly out of the loop and makes the users the moderators.

Select Which Gravatar to Use

After uploading, cropping, and rating my gravatar, I had way too many choices to chose from. However, if I want to add one more gravatar, I would have to pay $10 a year. Rather than do that, I selected the gravatar I just uploaded.

Gravatar Public Beta - Selecting a Gravatar

Removing a Gravatar

Removing a gravatar is simple as well. Just hover over the gravatar you wish to delete and click the bright and shiny red “X”.

Gravatar Public Beta - Removing a Gravatar

The Future of Gravatar?

It sounds like from this WordPress Podcast that Tom Werner is planning on turning Gravatar into a pseudo-MyBlogLog.

I’m not incredibly convinced Gravatar will be able to pull it off, especially since Gravatar has had such a shaky start. MyBlogLog can almost be a full competitor since it offers a full profile, community, and avatars for comments as well. Gravatar will be playing catch-up for a while if anything.

However, MyBlogLog is bloated and Gravatar (right now) is extremely easy to use, especially for those who don’t own blogs. If Gravatar starts turning into MyBlogLog and still has the admin/server difficulties, there will be nothing to stop people from flocking to MyBlogLog for good, especially since MyBlogLog offers a great amount of services for free.

I also don’t personally see Gravatar surviving very long unless the service secures some serious funding, and right now ten dollars is a little much to pay for more e-mail addresses and gravatars.

Conclusion

I suggest giving Gravatar a second chance and checking out the beta. The service is much improved over what it was before and very easy to use. I foresee a significant problem with Gravatar as far as abuse goes, however.

My skepticism is high as far as the survivability of what I think is a valuable (but not ten dollars worth) service. MyBlogLog is a viable competitor, but it carries a lot of baggage that Gravatar doesn’t have at the moment.

Right now the service is still in beta and is having its ups and downs. If Gravatar cannot reliably stay online and functioning past the beta, I predict that the Gravatar launch will not be a success, especially since the service has already left a bad taste in a lot of people’s mouths.