logo
  • Home
  • About
  • Plugins

Subscribe to Articles

Configurable Plugins

Author: andrew Category: Uncategorized Tags: Plugin-Practices

Wednesday
Oct 8, 2008

In my last post I asked the question: should plugins should be written to be as extensible, if not more, as the core WordPress code; i.e. should we expect a plugin to be written with the expectation that someone will write a plugin to further modify it? I promised an example so here it is.

I have written a very basic page menu plugin using the principles I outlined yesterday. I will explain each section and include the code here but the plugin can be downloaded at the bottom of the post.

The basic plugin

Initialisation

The plugin uses the template redirect hook to trigger just before the blog’s theme is loaded. At this point it sets default values for the home page URL, the title of the home page in the menu, and the arguments that will be used to fetch the pages (what to sort by and in what order).

At this point the first set of filters will run:

  1. Filter the home page information
  2. Filter the page selection arguments
  3. Filter the details of the callback function that will be used to filter the pages afterwards.

After those filters the pages are fetched using the WordPress get_pages function and the array of pages that is returned is passed to the callback function. We now have the final list of pages that the plugin will display.

Following that the plugin checks the current theme folder for a template file called ‘fun_menu_template.php’. If it finds it, it will use the file path to that, otherwise it will use the default template. Whichever path is chosen this is then passed through a filter and the result is stored.

Here is the code:

function menu_init(){
 
	$home_page_url = get_option('home');
	$home_page_default_text = 'Home';
 
	//set the default arguments
	$default_arguments = array(
		'sort_order'    =>  "ASC",
		'sort_column'   =>  "menu_order"
		);
 
	//apply filters
	$this->home_page_link = apply_filters('fun_menu_home',array($home_page_default_text,$home_page_url));
	$page_array_arguments = apply_filters('fun_menu_page_arguments',$default_arguments);
	$pages_filter_callback = apply_filters('fun_menu_pages_filter',array($this,'process_pages'));
 
	//start the processing
	$retrieved_pages = get_pages($page_array_arguments);
	$this->filtered_pages = array_filter( $retrieved_pages , $pages_filter_callback );
 
	//check the themes directory for an alternative template
	if (file_exists( TEMPLATEPATH . '/fun_menu_template.php') ){
		$template_url = TEMPLATEPATH . '/fun_menu_template.php';
	} else {
		$template_url = dirname(__FILE__) . '/fun_menu_template.php';
	}
 
	//use either the supplied, alternate, or result of filter
	$this->template_url = apply_filters( 'fun_menu_template' , $template_url );
 
}

There are only two more functions in the plugin:

Filtering

The pages filter. This filter checks every page to see if it should be included. In this plugin it simple returns true to indicate that the page should be included.

function process_pages($page){
 
	return true;
 
}

Outputing

The last function is called from within the users theme although it could just as easily be called from a widget. This gives the variables more useful names and the includes the template.

function display_menu(){
 
	//setup the variables
	$home_permalink = $this->home_page_link[1];
	$home_title = $this->home_page_link[0];
	$fun_menu_pages = $this->filtered_pages;
 
	//include the template
	include($this->template_url);
 
}

The template itself is just a very simple bulleted list. In the real world this plugin would certainly be including some CSS and maybe even some javascript as well to make it into a proper menu:

<div id="menu">
	<ul id="nav">
		<li><a href="<?php echo $home_permalink; ?>" title="<?php echo $home_title; ?>"><?php echo $home_title; ?></a></li>
		<?php foreach( $fun_menu_pages as $fmp ) { ?>
			<li><a href="<?php echo get_permalink($fmp->ID); ?>" title="<?php echo $fmp->post_title; ?>"><?php echo $fmp->post_title; ?></a></li>
		<?php } ?>
	</ul>
</div>

The end result when this plugin is activated and a call to the display_menu function added to the theme is a small bulleted list of links:

The child plugin

The child plugin is very simple. In the constructor three hooks are used to filter the appropriate information:

add_filter('fun_menu_home',array($this,'change_home_page_title'));
add_filter('fun_menu_pages_filter',array($this,'change_pages_filter_callback'));
add_filter('fun_menu_template',array($this,'change_template_path'));

These hooks call three functions. Number one changes the title shown for the home page:

function change_home_page_title($home_page){
 
	//update the array
	$home_page[0] = 'Go Home';
 
	//send it back
	return $home_page;
 
}

The second function changes the page filter callback to point to a filter function in this plugin. This filter doesn’t just pass back true, it checks each page for a custom field that tells the system to exclude the page from the menu:

function change_pages_filter_callback($callback){
 
	//no need to edit just send back a different one
	return array($this,'process_pages');
 
}
 
function process_pages($page){
 
	//check against a custom field to see if it should be excluded
	if ( get_post_meta($page->ID, 'menu', $single = true) == 'exclude' ) { return false;}
 
	return true;
 
}

The last function changes the template path to point to a template in this plugin’s folder.

function change_template_path($path){
	return dirname(__FILE__) . '/menu_template.php';
}

The results are clear to see:

The revised template is an ordered list instead of an unordered list, the home page no reads ‘Ho Home’ instead of simple ‘Home’ and one the pages has been filtered out.

I hope you can see from this where the potential lies. With so many options it would be easy for a plugin, or a theme, to produce something quite different without replicating the serious bits of the code. It also feels like a very neat solution. Of course there are a lot of plugins that wouldn’t suit this approach but if you can add filters, callbacks and templates you should consider it at least.

Note: I am becoming quite inspired by Habari at the moment. Habari uses the template system in themes but in a more integrated way. If you want to see it in action, in the next few days I will be writing about plugin templates at Fun with Habari.

Downloads

Download both the sample plugins in one zip file.


Share:
image image image image image

Comments


Should all plugins expect to be reconfigured?
Don’t mess with my Toot Toot

Recommended

wordpress unlimited

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