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:


  1. By Glenn posted on April 24, 2008 at 10:05 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi,
    I’ve been using this technique for options (the array) since I first read your tutorial several months ago. I was wondering if you know of a way to store my options in an array like above with the new way that 2.5 is handling the option page (http://codex.wordpress.org/Creating_Options_Pages). They process the options for you and use the field names for the options names.

  2. By Seree posted on May 19, 2008 at 11:00 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi Ronald,

    It would be great if you can modify your example to use only a single option as I’m confuse on this thing when follow your example.

    But the overall is GREAT. This is a real content!

    Thanks,

  3. By Tjamps posted on July 29, 2008 at 11:14 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi,

    thank you very much for this “HowTo”, it’s really complete and easy to understand (I’ve been learning PHP for 5 months…), moreover it does cover ALL we should know about developping plugins for WordPress.
    I’m developping (trying actually…) a very ‘simple-to-use’ thumbnail generator for WordPress, just as ‘Post-Thumb Revisited’ does (but it’s to hard to configure in my opinion), I’ll come back here when it’s over.

    Best regards.

  4. By scribe posted on December 31, 2008 at 11:07 am
    Want an avatar? Get a gravatar! • You can link to this comment

    this is an EXTREMELY helpful article. i’ve been trying to design my initial plugin with an admin panel and it has been taken a ‘bit to long. this “how to” has been a big help.

  5. By totallyconfused posted on April 23, 2009 at 5:18 am
    Want an avatar? Get a gravatar! • You can link to this comment

    “Building a administration panel isn’t all that difficult”

    It is now THAT difficult thanks to you!

  6. By Paul Kaiser posted on April 23, 2009 at 9:05 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Fantastic tutorial!
    Question: Do you recommend now using:

    register_activation_hook()

    … for registering functions that are to be run only when the plugin is activated?

  7. By delayedinsanity posted on June 7, 2009 at 1:40 am
    Want an avatar? Get a gravatar! • You can link to this comment

    I’m not sure what totallyconfused is talking about. I’m comfortable with all the technologies used by WordPress (PHP, MySQL, etc) but if it wasn’t for this tutorial I’d probably still be on a fishing expedition in the codex trying to figure it all out.

    Anywho… due to the size of the CSS included with WordPress it’d be really nice if they had an easy to use and in depth API on ways to include formatting in your admin pages. Other than div id=”wrap” and using h2 elements, that is! Anybody know where to find one?

  8. By Gary posted on October 6, 2009 at 11:19 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi,

    I have followd your tutorial exactly as it is, but I don’t see any adming panel in my WP Plugins section. Where can I get it?

    Regards,

    Gary.

  9. By Bojan posted on October 22, 2009 at 6:53 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    I really like this series of post. Thank you

  10. By Saggoardkadia posted on November 23, 2009 at 10:27 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Outstanding Article , I considered it phenomenal

    I look ahead to more innovative postings like this one. Does This Site have a RSS I can subscribe to for new postings?

  11. By Ahmed posted on November 29, 2009 at 3:34 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Thanks for your nice effort to teach how to make plugin ,i have an error about following the above code ,i get “Call to undefined function add_options_page()” error

  12. By Shawn posted on December 1, 2009 at 5:03 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Wow this article is awesome. I tried reading the wordpress documentation but it was to general. Your article focuses on a specific topic and does hell of a job on it.

  13. Trackback  Nasıl Wordpress Eklentisi Yazılır ? by # YaMTaRConstructing a WordPress Plugin Admin Panel Devlounge | Shed KitsAll my bookmarks ever | Daniel John GayleEssential Wordpress Plugin Development Resources, Tutorials and Guides : Speckyboy Design Magazine