Feature
Post

Category
Homepage News

New Homepage Tomorrow

Not that homepage. With the main focus for the next few weeks going to be on completing and coding the next Devlounge design, as well as testing out new parts and features (along with juggling finals), the content department around here will essentially turn off, with the exception of new Friday Focuses. To prevent the homepage from becoming too stagnant, I will be introducing a lightweight temporary homepage tomorrow or Friday at the latest that will spotlight some of our favorite posts, interviews, and article series. The rest of the site will remain fully functional, without any visual changes. I’d say I’m about 3-4 weeks out of launching the next version. Comments have been mixed, but don’t just go with what that Flickr teaser may have shown you, because the final design will have plenty of nice touches no one has yet to see. If you haven’t done so already, please subscribe to our rss feed to stay on top of updates. We thank you for your patience and understanding during this transition and slow time for us.

Feature
Post

Category
Code

Releasing and Promoting Your WordPress Plugin

How To Write a WordPress Plugin Series

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

After you have finished writing your awesome WordPress plugin, there are a few things to consider before releasing and promoting your WordPress plugin.

Prior to Release

Try to Follow the Standards

While it isn’t required to follow the WordPress coding standards, there are some things in there that will make your life easier. One of the more valuable tips in there is to never use shorthand PHP. The reason? Not everybody has shorthand PHP enabled.

So instead of:

<? /*your php code*/ ?>

You would have:

<?php /*your php code*/ ?>

Make Sure You Have Tested Your Plugin Thoroughly

Find some guinea pigs (er, testers) who would be willing to test your plugin. Technically competent testers are good, but you also want some testers who will represent the average user who knows nothing about programming languages.

It’ll be impossible to find every bug, but at least make an effort to put out a stable release.

Make Sure You Have a Readme File

Before you release a plugin into the wild, make sure you at the very least have a Readme file. This file should contain at the very minimum installation instructions for your plugin. For a stricter version of a readme file, check out the WordPress recommendations regarding a Readme file. There’s even a groovy Readme file validator.

Set Up a Dedicated WordPress Plugin Page

Ajay D’Souza wrote some recommendations regarding releasing WordPress themes. The advice he gives can also be applied to plugins to an extent.

Make sure you set up a dedicated WordPress Plugin page for your plugin. This page will be the URL that people will go to to find out everything about your plugin. This plugin page should contain the following at a minimum:

  • A brief description of your plugin.
  • The download location.
  • A list of features.
  • Install instructions.
  • Version history (Changelog).
  • Known bugs and/or conflicts.
  • Screenshots or a demo (or both).
  • Contact or support information (or comments enabled).

The above information will assist you in promoting your plugin, especially the description and feature portion.

Have a Good Folder Structure

I would argue to always include your plugin in a folder. Any files other than the main plugin file should be included in sub-directories. Make sure you zip, gzip, or rar your plugin folder that way it is as easy as possible for people to install your plugin.

Does Your Plugin Require Theme or File Manipulation?

If your plugin requires users to tweak theme settings and/or files, prepare for the onslaught of bug reports and users wanting assistance. I would argue that a good plugin requires absolutely no theme manipulation or file manipulation. An exception to this would be the plugins that add template tags to the WordPress core.

If your plugin does require theme or file manipulation, include detailed examples on your download page and possibly include some examples in your release.

Promoting Your Plugin

After you have your dedicated download page, it is time to start making plugin announcements so people will download your work. The time you spent on your description and features is crucial since you’ll be using these for your plugin promotion. Others who link to your plugin will be doing the same.

Promote at Weblog Tools Collection

A very good resource for promoting your plugin is the Weblog Tools Collection news section. Under their Plugin Releases section, you can give details regarding your new plugin.

Promote at the WordPress Plugin Database

The WordPress Plugin Database is another good resource for adding in your plugin. The process for adding your plugin isn’t the most straightforward, but there are detailed instructions.

Promote at the Official WordPress Plugin Repository

WordPress itself has offered to host your plugin. You have to meet several requirements before you will be allowed to add your plugin, however. Remember that any publicity is good publicity.

Promote Using Social Networking

Add your plugin to delicious, Digg, and Stumble Upon. Get your friends to help. If your plugin is good enough, the referrals will start coming in.

Promote On Your Own Blog

If your plugin is something that people will notice, use it on your blog. People may start asking what plugin you are using. Word of mouth is a powerful ally, especially in the blogosphere.

Conclusion

You can have the best plugin in the world, but if it isn’t released and promoted correctly, very few people will download it. Once you start the promotion process, it is important to listen to feature and bug requests, especially if your plugin is very young. If your plugin doesn’t work, or too many people have problems with it, people will be wary of downloading your plugin. It’s important to get those bugs fixed and the crucial features added in early. Most of these problems can be solved during testing, but some bugs just don’t seem to crop up until after the official release.

The End of the ‘How to Write a WordPress Plugin’ Series

Thank you for reading the final post in the plugin series. Hopefully this series proved beneficial to you and helped establish a foundation for you to write your own plugins. Thank you very much for reading.

Feature
Post

Category
Design Focus

Friday Focus #32

It’s incredibly hot where I am as we enter into the last weekend of May, a three day weekend for many of us. As May draws to an end we get closer to the new Devlounge design and a surge of new content. I want to personally thank Ronald, as his WordPress plugin series (which I promise will be getting it’s own “table of contents” page this weekend) has restored Devlounge visitors to what they were a few weeks back before we began the decline. If you’ve been following the series (which he has left a note about at the end of this week’s focus), please leave your comments in the series finale on how helpful the series was to you. We have had a lot of trackbacks, but little comment feedback on the series itself. It’s always nice to know our readers appreciate the effort of hard working writers.

Let’s kick this weeks focus off. Enjoy the weekend everyone.

Sites of the Week

Up first this week is StayDecent, the personal portfolio of Adrian Unger. For this one, I love how the display of work is put together. There is also Ajax used here and there, and lots and lots of big, bold fonts.

Stay Decent

Next up is another portfolio, this one for Jason Julien. The portfolio is neat and clean, and there’s is a very nice collection of work that goes along with it. Worth a look.

Jason Julien

Digg Weekly

Favorites from the past 7 days

Design: 60 Elegant and Visually Appealing Designs
From the list-creating-masters of Smashing Magazine comes an entirely new list, this time with 60 “visually appealing and elegant designs”.

Programming: The top 10 dead (or dying) Computer Skills
While not directly related to design, most of us understand computers a bit more than our average friends, so I thought it might be interesting to know what is and isn’t needed anymore.

Up and Coming

Software10 Open Source Apps You Can’t Live Without
A nice collection of open source apps including the usual suspects Firefox and Open Office.

Design20 Killer Resources Every Good Web Designer Should See : May
Within the post are twenty resources from icons, to CSS, to Web 2.0 layer styles.

Design Dilemma

What would be your approach for finding a color scheme if you are color challenged?

WordPress Plugin Spotlight

The Devlounge Plugin Series is drawing to a close with the last post scheduled to be published Sunday. It has been quite a journey and a few people have e-mailed in saying that the series has been helpful. If you have yet to check out the series and are a WordPress user, please start with the introduction.

Feature
Post

Category
Code

Using AJAX with your WordPress Plugin

How To Write a WordPress Plugin Series

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

More and more plugins are starting to use AJAX techniques. I personally don’t see a use for most cases of AJAX, but it may be necessary for your plugin to use AJAX to accomplish a task. This post will show you how to use AJAX with your WordPress plugin.

This post will be building on the last one where we added in a JavaScript and Stylesheet file.

Set Up a new PHP File

The Devlounge Plugin Series plugin has the following directory structure:

  • devlounge-plugin-series
    • devlounge-plugin-series.php (main plugin file)
    • js
      • devlounge-plugin-series.js.php
    • css
      • devlounge-plugin-series.css
    • php
      • dl-plugin-ajax.php (new php file for AJAX calls)

Notice I have a php extension at the end of my JavaScript file. I’ll explain the change a little later in this post.

I’ve created a new file and placed it in the php directory and have called it dl-plugin-ajax.php. I have placed the following code inside the file:

<?php
if (!function_exists('add_action'))
{
	require_once("../../../../wp-config.php");
}
if (isset($dl_pluginSeries)) {
	$dl_pluginSeries->showComments();
}
?>

This code is simple enough and is used solely for AJAX calls. It makes sure that config structure is present so we can call our class object dl_pluginSeries and reference other WordPress functions and variables. However, the showComments function hasn’t been created yet, so that is the next item on our agenda.

Set up the showComments function

The showComments function is placed inside our DevloungePluginSeries class:

function showComments() {
					global $wpdb;
					$devloungecomments = $wpdb->get_row("SELECT count(comment_approved) comments_count FROM $wpdb->comments where comment_approved = '1' group by comment_approved", ARRAY_A);
					echo "You have " . $devloungecomments['comments_count'] . " comments on your blog";
				}

You might recognize this bit of code from the database interaction post. This function outputs the number of comments made on your blog.

Allow JavaScript to Know Where Your Blog is Located

One pesky thing about AJAX is that the external JavaScript file has no idea where your blog is installed. I get around this by adding a PHP extension to my included JavaScript file so that I can access WordPress functions. Within the addHeaderCode function, I changed the code from this:

if (function_exists('wp_enqueue_script')) {
				wp_enqueue_script('devlounge_plugin_series', get_bloginfo('wpurl') . '/wp-content/plugins/devlounge-plugin-series/js/devlounge-plugin-series.js', array('prototype'), '0.1');
			}

to this:

if (function_exists('wp_enqueue_script')) {
				wp_enqueue_script('devlounge_plugin_seriess', get_bloginfo('wpurl') . '/wp-content/plugins/devlounge-plugin-series/js/devlounge-plugin-series.js.php', array('prototype'), '0.3');
			} 

The only thing I changed was the version number and added a PHP extension to the end of the JavaScript file.

Now JavaScript has a way of finding out where our blog is for AJAX calls. Let’s now set up the JavaScript.

Setting up the JavaScript

The purpose of this script (which is located in devlounge-plugin-series.js.php) is to find the blog’s URL, call the PHP file, and return a result to the user.

<?php
if (!function_exists('add_action'))
{
	require_once("../../../../wp-config.php");
}
?>
Event.observe(window, 'load', devloungePluginSeriesInit, false);
function devloungePluginSeriesInit() {
	$('devlounge-link').onclick = devloungePluginSeriesClick;
}
function devloungePluginSeriesClick(evt) {
	var url =  "<?php bloginfo('wpurl') ?>/wp-content/plugins/devlounge-plugin-series/php/dl-plugin-ajax.php";
	var success = function(t){devloungePluginSeriesClickComplete(t);}
	var myAjax = new Ajax.Request(url, {method:'post', onSuccess:success});
	return false;
}
function devloungePluginSeriesClickComplete(t) {
	alert(t.responseText);	
}

The above code does the following (keep in mind we are using Prototype):

  • Makes sure that config structure is present so we can access WordPress functions and variables.
  • After the document has loaded, the devloungePluginSeriesInit is called.
  • An event is set up for the link you added at the end of a post (line 7). If you forgot, now is the time to add the link in. Simply find a post and add this code to the bottom of it: <a href="#" id="devlounge-link">Get the Number of Blog Comments</a>
  • The absolute URL to the PHP file is found (line 12).
  • The PHP file is called (line 14).
  • The response is outputted to the user (line 18).

The Result

This next step assumes you are at the post where the link was added. When clicking on the link “Get the Number of Blog Comments“, the script uses AJAX to call a function in the DevloungePluginSeries class and returns the result to you in the form of an alert box.

AJAX Alert Box

As you can see, I don’t have many comments on my local installation.

Conclusion

This post demonstrated a very bare-bones example of how to use AJAX (using Prototype) for your WordPress plugin. Please download the code used in this post: Devlounge Plugin Series Using Ajax.

Download the Code Used In This Post

For some related reading regarding Prototype, please check out the following links:

Thank you for reading.

Feature
Post

Category
Code

Using JavaScript and CSS with your WordPress Plugin

How To Write a WordPress Plugin Series

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

A lot of plugins nowadays are more reliant on JavaScript and Cascading Style Sheets. It is important to separate your JavaScript and CSS into separate files so that the plugin is easier to maintain. This portion of the series will cover how to load JavaScript and CSS files for your plugin.

Add your JavaScript

Your plugin might need to load the Prototype library or perhaps a custom script. This section will show you a few WordPress functions that will allow you to load scripts and avoid script conflicts.

The wp_register_script function

The wp_register_script function allows you to register your script for calling and can allow you to set pre-requisites. For example, if your script requires Prototype to have been loaded, you can specify this.

Here are the parameters for wp_register_script: wp_register_script( $handle, $src, $deps = array(), $ver = false )

  • The handle is a unique name that you will use to reference your script later. This variable is required.
  • The src is the absolute source to your JavaScript file. This variable is required.
  • The deps variable is an array of dependencies. For example, if your script requires prototype, you would list it here. This variable is optional.
  • The ver variable is a string version of the script. This variable is optional.

Say for example you had a script that was located at: http://yourdomain.com/wp-content/plugins/your-plugin-directory/js/script.js

Let’s make a few assumptions:

  • You want to name the handle ‘my_script_handle’.
  • Your script depends on the Prototype library.
  • Your version is 1.0

You would likely call the function in your plugin code initialization or after a wp_head action:

wp_register_script('my_script_handle', 'http://yourdomain.com/wp-content/plugins/your-plugin-directory/js/script.js', array('prototype'), '1.0');

The wp_enqueue_script Function

The wp_enqueue_script function does the same thing as wp_register_script except that the src variable is optional. If an src is provided, the enqueue function automatically registers the script for you, thus making the wp_register_script function somewhat unnecessary. However, the wp_register_script allows you to register your scripts manually so you can load all of your JavaScripts using one wp_enqueue_script function.

If we were to call the same custom script as before, it would be called like this:

wp_enqueue_script('my_script_handle', 'http://yourdomain.com/wp-content/plugins/your-plugin-directory/js/script.js', array('prototype'), '1.0');

A JavaScript Example

For the Devlounge Plugin Series plugin, we’re going to add in a dummy JavaScript file that will be used in a later post. The purpose of this file is to demonstrate how to use the wp_enqueue_script function.

  • This file is located at the following location: http://yourdomain.com/wp-content/plugins/devlounge-plugin-series/js/devlounge-plugin-series.js
  • The file is dependent upon prototype.
  • The version is 0.1

You might recall that in a previous post in this series, we added an action for wp_head. The function that was run as a result of that action was called addHeaderCode. Let’s modify this function to add in our new JavaScript:

function addHeaderCode() {
			if (function_exists('wp_enqueue_script')) {
				wp_enqueue_script('devlounge_plugin_series', get_bloginfo('wpurl') . '/wp-content/plugins/devlounge-plugin-series/js/devlounge-plugin-series.js', array('prototype'), '0.1');
			}
			$devOptions = $this->getAdminOptions();
			if ($devOptions['show_header'] == "false") { return; }
			?>
<!-- Devlounge Was Here -->
			<?
		
		}

The above code does the following:

  • The wp_enqueue_script function is checked for existence.
  • The wp_enqueue_script is called with the src, dependencies, and version.
  • We use the get_bloginfo(‘wpurl’) to get the location of the WordPress installation and hard-code the rest.

When you go to a post and view-source, the devlounge-plugin-series.js will have loaded as well as the Prototype library, which is conveniently included along with WordPress (versions 2.1.x and up I believe).

Loading in the Cascading Style Sheets

I’ve added a new style sheet to my styles directory. Here are my assumptions:

  • This file is located at the following location: http://yourdomain.com/wp-content/plugins/devlounge-plugin-series/css/devlounge-plugin-series.css
  • I specified an ID called #devlounge-link in the CSS file.
  • You have added in the following code at the end of a post: <a href="#" id="devlounge-link">Get the Number of Blog Comments</a>

In the style sheet file, I have added in the following ID:

#devlounge-link {
	background-color:#006;
	color: #FFF; 
}

Adding in the style sheet for the plugin is as simple as adding a line to the addHeaderCode function:

function addHeaderCode() {
			echo '<link type="text/css" rel="stylesheet" href="' . get_bloginfo('wpurl') . '/wp-content/plugins/devlounge-plugin-series/css/devlounge-plugin-series.css" />' . "\n";
			if (function_exists('wp_enqueue_script')) {
				wp_enqueue_script('devlounge_plugin_series', get_bloginfo('wpurl') . '/wp-content/plugins/devlounge-plugin-series/js/devlounge-plugin-series.js', array('prototype'), '0.1');
			}
			$devOptions = $this->getAdminOptions();
			if ($devOptions['show_header'] == "false") { return; }
			?>
<!-- Devlounge Was Here -->
			<?
		
		}

On line 2, I simply echo out a reference to the new style sheet.

Number of Comments Link

Conclusion

Within this post you learned how to allow your plugin to have external JavaScript and CSS files. As always, you can download the current version of the code and try it out yourself: Using JavaScript and CSS with your WordPress Plugin

Download the Code Used In This Post

For further reading, please check out these links:

Feature
Post

Category
Code

WordPress Plugins and Database Interaction

How To Write a WordPress Plugin Series

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

When you are writing a plugin, you will inevitably have to store variables in a database and retrieve them. Fortunately WordPress makes data retrieval simple with options and a database object. This post will cover storing and retrieving data from a WordPress database.

Storing Data in a Database

There are two main ways to store data in the WordPress database:

  1. Create your own table.
  2. Use Options

Since most plugins will not require their own database table, I will only cover options. However, the WordPress codex has detailed instructions on how to set up your own table.
WordPress Options

With WordPress options, saving and retrieving data from the database is as simple as a function call. WordPress has four functions for options:

  • add_option
  • get_option
  • update_option
  • delete_option

add_option

The add_option function accepts four variables, with the name of the option being required. The variables are: add_option($name, $value, $description, $autoload);

This function is beneficial for adding data to the database for retrieval later.

The $name variable should be unique so that you don’t overwrite someone else’s option, or someone else doesn’t write over yours.

I usually don’t use this function because update_option pretty much does the same thing.

get_option

The get_option function allows you to retrieve a previously stored option from the database. It accepts only one variable, which is the name of the option to retrieve. The function format is: get_option($option_name);

update_option

The update_option function works about the same as the add_option function except that it also updates an option if it already exists. I personally like the double functionality of the function and prefer it over add_option when storing data to the database.

The function format is: update_option($option_name, $new_value);

delete_option

The delete_option function deletes options from the database. The function format is: delete_option($option_name);

A Code Example

You might recall from previous posts in this series that I stored options in the database as an array. Here is a sample function followed by a brief explanation:

//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;
}

On lines 3 – 6, I begin an associative array that will eventually be stored in the WordPress database as an option (line 12). I do this so I don’t have to store multiple options (each a database call). This technique helps with code bloat, database queries, and naming collisions with other plugin authors.

The WordPress Database Class

Another powerful method of storing and retrieving data from the WordPress database is using the WordPress Database class object. In a function, a reference to the class would look like:

function sample_function() {
global $wpdb;
}

After this variable is referenced, you can access the many useful functions of the wpdb class.

For example, say we want to retrieve the total number of comments for our WordPress installation. Here’s a function that does that using the WPDB class:

function sample_function() {
global $wpdb;
$comments = $wpdb->get_row("SELECT count(comment_approved) comments_count FROM $wpdb->comments where comment_approved = '1' group by comment_approved", ARRAY_A);
echo $comments['comments_count'];
}

Here’s what the function does:

  • On line 2, we add a reference to the $wpdb variable.
  • On line 3, we call a function inside the wpdb class called get_row.
  • On line 3, we retrieve data from the comments table ($wpdb->comments).
    We specify that we want the data returned as an associative array (ARRAY_A).
  • On line 4, we echo out the result. Since I wanted the results returned as an associative array, I simply call the variable I assigned the results in SQL, which was comments_count.

The wpdb class is a very large class with a lot of functionality. I suggest heading over the WPDB Class page and looking over what the wpdb class is capable of.

Conclusion

The purpose of this post was to give you a glimpse into storing and retrieving variables from the WordPress database.

For further reading, please check out these links:

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
Design Focus

Friday Focus #31

Here we are with only a few more weeks left in May, and we get closer and closer to the brand spanking new Devlounge design and a ton of new features. Friday Focuses will play a much bigger impact in the next version of Devlounge (slated for early – mid June), so you can continue to expect even bigger things in the weeks to come for FF. Let’s get started, and enjoy the weekend everyone!

Sites of the Week

Starting off this week is 18Seconds from Yahoo. The purpose – to get people to buy new environmentally friendly CFL light bulbs and help the world wide global warming issue while doing it. Check and see how helpful your state has been in conserving electricity and helping the environment.

18Seconds

Next up is The Big Noob. After being dormant for a very very long time, our buddy Ryan Sims and crew have relaunched their blog called The Big Noob. Now that they are back, I’m sure you can expect a lot of (great) fresh stuff.

The Big Noob

And rounding out this week is Design By Grid, another niche design gallery from Every5Weeks creator, along with design help from Climax Designs.

Design by Grid

Digg Weekly

The best of the last 7 days in design and programming

DesignRediscovering the button element
Button styling constantly goes forgotten in the standards-driven world we live in today. Don’t let your poor buttons take on their own styles based on browsers and operating systems – style them today.

Programming14 Rules for fast Web Pages
A lead-in page for a very long Powerpoint presentation featuring 14 rules for optimizing your web pages. Powerpoint was created by Steve Souders of Yahoo’s “Exceptional Performance Team”.

Feature
Post

Category
Homepage News

Two Hundred Thousand

Earlier today we successfully passed the 200,000 unique visitor mark. Just a quick thank you to all our readers and contributors for helping make this possible. In other news, progress is quickly being made on the next Devlounge. I’m about 80% done with the new homepage, and once the homepage is completed, other pages should be completed fairly quickly. As an additional note, DL is now running out WordPress 2.2 – which once again completed with a flawless upgrade process. Until next time, have a great day!

Note: I’ve emailed a few people regarding possible illustration contributions for the next DL design. If you have an extensive illustration portfolio and would consider contributing, please feel free to drop me a line.

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: