logo
  • Home
  • About
  • Plugins

Subscribe to Articles

Plugin Config: WordPress vs Habari

Author: andrew Category: Uncategorized Tags: Habari, Plugin-Practices, plugins

Sunday
Sep 7, 2008

In my last Habari plugins post I highlighted the differences, and similarities, in the way plugins are created for WordPress and Habari. In this post I am going to look at the differences in how the user is given configuration options.

WordPress

In WordPress, plugin options require you to create an admin page. It is entirely up to you where this page sits and there is an habitual discussion as to whether options should sit under ’settings’ or under ‘plugins’. Either way the admin page will look like any other admin page and won’t be visibly connected to your plugin.

The process is fairly simple. Here is some code. I will discuss it below:

/*
Plugin Name: My WordPress Plugin
Plugin URI: http://example.com
Description: Very basic example of adding a plugin config page
Author: Andrew Rickmann
Version: 0
Author URI: http://www.wp-fun.co.uk
*/
 
 
class myWordPressPlugin
{
 
/**
* PHP4 Constructor
*/
function myWordPressPlugin(){
	$this->__construct();
}
 
/**
* The actual constructor
*/
function __construct(){
 
	//this hook will call the function that adds the item to the menu
	add_action("admin_menu", array(&$this,"add_menu_item"));
 
	//this hook will call the form handler
	add_action("admin_post_mywordpressplugin-update_options", array(&$this,"handle_form_data"));
 
}
 
/**
 * Add the menu item
 */
function add_menu_item(){
	add_submenu_page('plugins.php', "My WordPress Plugin Options", "My WordPress Plugin Options", 10, "mywordpresspluginoptions", array(&$this,"configuration_page_content"));
}
 
/**
* Get and deal with the data submitted by the user
*/
function handle_form_data(){
 
	//missing lots of validation and nonce checks etc.
 
	//options array
	$options = array();
 
	//get the form data
	if ( isset($_POST['quote']) ) { $options['quote'] = $_POST['quote']; }
 
	update_option('myWordPressPluginOptions', $options);
 
	//redirect back to the plugin page
	$url = get_bloginfo('wpurl') . '/wp-admin/admin.php?page=mywordpresspluginoptions';
	wp_redirect($url);
}
 
/**
 * Output the content for the admin page.
 */
function configuration_page_content(){
 
	$pluginOptions = get_option('myWordPressPluginOptions');
 
	//get the saved values
	$option_quote = ( isset($pluginOptions['quote']) ) ? $pluginOptions['quote'] : '';
 
	//output the form
	?>
	<div class="wrap">
		<h2>My Plugin Configuration Page</h2>
		<form method="post" action="admin-post.php" >
			<input type="hidden" name="action" value="mywordpressplugin-update_options" />
			<label for="quotes">Enter Quote</label>
			<input type="text" name="quote" value="<?php echo $option_quote; ?>" />
			<p>
			<input value="Save Settings" name="saveSettings" class="button-secondary update" type="submit">
			</p>
		</form>
	</div>
	<?php
 
}
 
 
}
 
$myWordPressPlugin = new myWordPressPlugin();

So what is going on here?

add_action

When the plugin runs, the constructor adds an action (admin_menu) that fires when the admin menu is generated.

add_submenu_page

That action runs the add_submenu_page function which inserts the new menu item.

The menu item points to the function to output the content that we want for the configuration page.

configuration_page_content

The configuration page loads the options from the database using the get_option function and then we hardcode the form to gather the data.

The content of the form doesn’t really matter, it us just a texbox asking a question. What matters is that the form points to ‘admin-post.php’ and has a hidden field called action with a value of ‘mywordpressplugin-update_options’. This value is important.

When the plugin ran it added a second hook. That hook takes the form ‘admin_post’ + the value of the action field (admin_post_mywordpressplugin-update_options), so when this specific form is submitted the hook calls the form handler function in this plugin.

handle_form_data

The form handler gets the form data and saves it back to the database using the update_option function. It then redirects the user back to the plugin page. Note that I have left out validation and nonce verification for ease of reading.

In this example I have added the configuration page under the plugins menu but one change could move it to sit under the manage, or settings page.

I won’t explain it any further than this. For details of what each function does check out the WordPress Codex: Writing a plugin, Adding an administration panel, Plugin API, Function Reference, or

Habari

Habari is quite different in its approach to plugin configuration pages. The image below shows the plugins page. When you select configure for each plugin the configuration options are included as part of the page. You are not left to create your own pages; although, if it is more appropriate to do that you certainly can do.

Here is the code for essentially the same plugin for Habari. I will explain it below:

class my_first_plugin extends Plugin
{
function info()
{
return array(
  'name' => 'My Habari Plugin',
  'version' => '0.1',
  'url' => '[insert the plugin url here]',
  'author' => 'Andrew Rickmann',
  'authorurl' => 'http://www.wp-fun.co.uk',
  'license' => 'Apache License 2.0',
  'description' => 'Very basic example of adding a plugin config page');
}
 
/**
 * This is the function that adds options to the plugin dropdown
 */
public function filter_plugin_config( $actions, $plugin_id ){
	//if we are dealing with our plugin
	if ( $plugin_id == $this->plugin_id() ) {
		//add a new action to the dropdown box
		$actions[]= _t('Lick');
	}
	return $actions;
}
 
public function action_plugin_ui( $plugin_id, $action ){
	//if we are dealing with out plugin
	if ( $plugin_id == $this->plugin_id() ) {
		//carry out action depending on dropdown
		switch ( $action ) {
		case _t('Lick') :
			//add the form details
			$ui = new FormUI( 'myHabariPluginUID82738' );
			$ui->append( 'text', 'quote', 'myhabariplugin__quote', _t('Enter Quote:') );
			$ui->quote->add_validator( 'validate_regex' , '/^[a-zA-Z]*\s*$/' );
			$ui->append('submit', 'save', _t( 'Save' ) );
			$ui->set_option('success_message', _t('Quote licked'));
			$ui->out();
		break;
    	}
  	}
}
 
public function filter_post_content_out( $content ){
	//get the value entered into the text box
	$myQuote = Options::get( 'myhabariplugin__quote' );
	//add it to the end of the post content
	return $content . '<p>' . $myQuote . '</p>';
 
}
 
}

There are a few things in this plugin that I need to explain. So I will address them a function at a time.

filter_plugin_config

This fires when the plugins page is being loaded. It allows you to filter the options that are assigned to each plugin. It will fire once for each plugin.

In this case I first check to make sure that it is my plugin that is being checked, then I add a new action. I have used the action ‘Lick’ to make the point that it doesn’t have to say configure. You can can add any, and any number of actions here.

action_plugin_ui

This fires when the UI for a plugin has been requested. As with the previous function I only want it to run for my plugin so I check that first. Next, using a switch statement, I decide what to output when the ‘Lick’ action is chosen, and this is where it gets really interesting.

Habari has a helper class called FormUI which in simple terms is a form builder. In most cases this means not only that it isn’t necessary to write any HTML, but also that most of the functionality you want is already included.

Taking my example line by line:

First I create a new FormUI object using a UniqueID (see the link below for more on methods of generating this). Then I append to that a textbox called quote, with a label of ‘Enter quote’.

Then I add a validator to the text box to limit the content that can be entered.

Finally, I add a submit button and a success message and call the out method to send the form to the screent: $ui->out();

The beauty of this is that the form is now complete and fully functional. Not only will it add the form and the form fields it will also process the result, check it against my regular expression and save it to an option for later use. Here is an example to show how it looks when the input fails the validation:

You can read a lot more about FormUI on the Habari Project Wiki, There is also an excellent demonstration screencast of FormUI in action.

filter_post_content_out

This function wasn’t included in my WordPress version. I include here only to show you how to access the value of the form again after it has been saved. The FormUI sorts that out so my code didn’t need to cover it thus far.

This filter retrieves the value by using: Options::get( ‘myhabariplugin__quote’ );. Notice that the name of the option is the same as the third variable I passed to FormUI when I added the textbox. I think add it to the content and return to add the quote to the end of every post.

Summation

In some parts of Habari it is very similar to WordPress and you can see the influence. In others like this the influence is shown in making fairly common tasks not only easier but also by ensuring consistency. Habari is promoted as being the next generation. The blog platform built from the ground to meet challenges that older platforms like WordPress have to work around.

In my opinion Habari is some way ahead when it comes to plugin config.


Share:
image image image image image

Comments

Owen (http://asymptomatic.net)

September 7th, 2008 at 8:02 pm

One of the many design considerations when building the plugin functionality in Habari was explicitly that WordPress made you create whole options pages for your plugins when you might have one checkbox to configure things. We try to handle this in Habari by making the config of the plugin integrate better with the software as a whole.

Something you might have overlooked while you were describing this is the significance of this line in your Habari plugin:

if ( $plugin_id == $this->plugin_id() )

Yes, your plugin can actually add configuration options to other plugins. Users may appreciate this powerful feature when coupled with our upcoming dependency functionality. A plugin could require that another plugin exist, and then add to its functionality.

For example, you could install a core spam-checking plugin, and then extend its capabilities and configuration options without providing a separate interface to do so. Easily integrated, simple to code, fun to use.

I think it’s great to emphasize that all of these forms are built programmatically, rather than using hard-to-alter, fixed templates. For the effort, plugins have a consistent look, validation, uniform storage, and the immediate ability to be modified and extended easily by other plugins.

The examples in this post are a good comparison of features. I hope that you might write something on the use of sub-templates in themes, where a plugin provides its own output by default, but can be overridden by a template in the current theme. This (output) would even be the next logical step for the plugin you’ve produced above!

I am pleased that Habari is giving WordPress a good showing. Thanks again for another great article!

Andrew Rickmann (http://www.arickmann.co.uk)

September 7th, 2008 at 10:14 pm

Thanks Owen.

I am pretty much deciding on something I want to do then finding out how to do it so there are probably significances that I am missing. I hadn’t though to extend the functionality of another plugin but it sounds like an excelllent idea.

I noticed the sub-template thing in the documentation so I will certainly be taking a closer look. I am making a conscious decision to make posts a direct comparison to WordPress features so I will need to see where it takes me before I know whether to write it up or not.


WordPress Plugin: Fun with Widget Structures
What is the future of WordPress

Recommended

WP Remix Banner

Archives

  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007

Tags

2.7 2.8 Admin Advertising Air Blogging blogs Cache Cliche Coding Comments Content Types CSS Curry Death development Disqus Features Habari image Interview Licensing Modes Monday Poll New Features Organisation Personal Platform Plugin Plugin-Practices plugins Plugin update Poll premium Readers Reviews Search Simplification Snippets Spam Themery Themes tools User Interface Widgets WLTC

Copyright 2009 Fun with WordPress - All Rights reserved.

Wordpress theme by: WPUnlimited