888888.888888.88""Yb..dP"Yb..8888b..Yb..dP.88b.88....db....8b....d8.88..dP""b8..dP"Y8
88__...88__...88__dP.dP...Yb..8I..Yb.YbdP..88Yb88...dPYb...88b..d88.88.dP...`".`Ybo."
88""...88""...88"Yb..Yb...dP..8I..dY..8P...88.Y88..dP__Yb..88YbdP88.88.Yb......o.`Y8b
88.....888888.88..Yb..YbodP..8888Y"..dP....88..Y8.dP""""Yb.88.YY.88.88..YboodP.8bodP'


88b.88.888888.888888.Yb........dP.dP"Yb..88""Yb.88..dP
88Yb88.88__.....88....Yb..db..dP.dP...Yb.88__dP.88odP.
88.Y88.88"".....88.....YbdPYbdP..Yb...dP.88"Yb..88"Yb.
88..Y8.888888...88......YP..YP....YbodP..88..Yb.88..Yb

October 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:

[php]
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.

[php]
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.

[php]
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:

[html]

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:

[php]
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:

[php]
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:

[php]
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.

[php]
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.

Fun Without Cliches
Fun cliches?
12 comments
page 861
Wordpress Chat
Wp chat themes?
3 comments
page 1308
Post Image The Easy Peasy Way
Wp custom field arrau thumbnails?
26 comments
page 1065
Dont Mess With My Toot Toot
Custom content types wordpress?
15 comments
page 599
Post Image The Easy Peasy Way
Wp change post image size?
26 comments
page 1065
Using Your Own Url Shortener
Use your domain as a url shortner?
4 comments
page 1190
Dont Mess With My Toot Toot
Dont mess with my toot toot?
15 comments
page 599
Six Million Ways To Die Choose One
Simply ways to die?
14 comments
page 1128
3 Ways To Speed Up Your Blog Without A Cache Plugin
Speed up disqus?
one comment
page 1321
Updating Code Snippets Here
Fun with plugins?
no comment
page 1338
Easy Peasy Images Suggestion Roundup
Display attached images within loop?
21 comments
page 1073
Html 5 Gallery
Wordpress and html5?
6 comments
page 1305
Post Image The Easy Peasy Way
Wp get attachment?
26 comments
page 1065
Post Image The Easy Peasy Way
Post image gallery wp?
26 comments
page 1065
Why I Ditched Disqus
Better than disqus?
5 comments
page 1175
Updating Code Snippets Here
Andy dp?
no comment
page 1338
Post Image The Easy Peasy Way
Get images attached to a post all images?
26 comments
page 1065
Why I Ditched Disqus
Disqus vs wordpress comments?
5 comments
page 1175
Poll Daddy Reviewed
Wordpress pie chart poll?
2 comments
page 42
Html 5 Gallery
Html 5 wordpress theme gallery?
6 comments
page 1305
Html 5 Gallery
Html 5 photo album?
6 comments
page 1305
Dont Mess With My Toot Toot
Dont mess with my toot toot?
15 comments
page 599
Why You Should Try Netbeans
Function of netbeans?
6 comments
page 973
Quick N Dirty Admin Login Screen
Css login screen?
no comment
page 128
Why I Ditched Disqus
Disqus wordpress static page?
5 comments
page 1175
Fun With Sidebar Tabs Styling
Sidebar vertical tab wordpress?
2 comments
page 336
Quick N Dirty Admin Login Screen
Login page css html?
no comment
page 128
Using Wordpress As A Php Framework
Wordpress php framework?
2 comments
page 335
Using Your Own Url Shortener
Url for your category in wordpress?
4 comments
page 1190
3 Ways To Speed Up Your Blog Without A Cache Plugin
Speed up web with html5 cache?
one comment
page 1321
My Experience Of Flexx
Why flexx is used?
4 comments
page 1026
Wpunlimited The Ultimate Wordpress Theme
Wordpress premium theme html 5?
3 comments
page 1141
Post Image The Easy Peasy Way
Image post?
26 comments
page 1065
  1 query every 3724 seconds, updated 1 seconds ago.
Wednesday, 7pm
 __
(__)
   `

 Where Is That Settings Page? | Wordpress Blog NL

[...] the weekend, I happened to come across a post written by Andrew Rickmann which showcased an idea to create a configure link next next to the usual Activate/Deactivate Edit [...]

Wednesday, 12pm
 __
(__)
   `

 links for 2008-10-08 « Tom Altman’s Wedia Conversation

[...] Configurable Plugins | WP FUN 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. (tags: wordpress plugins programming) [...]