1. Hello World!

OK, so this isn’t really a ‘hello world1‘ example, rather a ‘let’s investigate and extend the FD Footnote Plugin’.

Onwards and Upwards…!

The original code

Let us start with the original code2:

<?php
/*
Plugin Name: FD Footnotes
Plugin URI: http://flagrantdisregard.com/footnotes-plugin
Description: Elegant and easy to use footnotes
Author: John Watson
Version: 1.2
Author URI: http://flagrantdisregard.com

Copyright (C) 2008 John Watson
john@flagrantdisregard.com3
http://flagrantdisregard.com/footnotes-plugin

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

// Converts footnote markup into actual footnotes
function fdfootnote_convert($content) {
  $post_id = get_the_ID();

  $n = 1;
  $notes = array();
  if (preg_match_all('/\[(\d+\. .*?)\]/s', $content, $matches)) {
    foreach($matches[0] as $fn) {
      $note = preg_replace('/\[\d+\. (.*?)\]/s', '\1', $fn);
      $notes[$n] = $note;

      $content = str_replace($fn, "<sup class='footnote'><a href='#fn-$post_id-$n' id='fnref-$post_id-$n'>$n</a></sup>", $content);
      $n++;
    }

    $content .= "<div class='footnotes'>";
    $content .= "<div class='footnotedivider'></div>";
    $content .= "<ol>";
    for($i=1; $i<$n; $i++) {
      $content .= "<li id='fn-$post_id-$i'>$notes[$i] <span class='footnotereverse'><a href='#fnref-$post_id-$i'>&#8617;</a></span></li>";
    }
    $content .= "</ol>";
    $content .= "</div>";
  }

  return($content);
}

add_action('the_content', 'fdfootnote_convert', 1);
?>

Code comments

They are all very nice – take a look at the first six or so lines of the comments. These are all self explanatory, however they are used to populate the information within the ‘Plugins’ section of the WordPress installation.

Plugin Name: FD Footnotes
Plugin URI: http://flagrantdisregard.com/footnotes-plugin
Description: Elegant and easy to use footnotes
Author: John Watson
Version: 1.2
Author URI: http://flagrantdisregard.com

The GPL comes next – which is a good thing, meaning that I can modify and redistribute the code freely – with one caveat – it must be under the same license, which is fine by me.

Next up we have the code, which is elegant, simple and compact – perfect for modification.

The last line:
add_action('the_content', 'fdfootnote_convert', 1);

Is where WordPress is notified that an action should be added to the hook named ‘the_content‘, by calling the function ‘fdfootnote_convert‘ with a priority of 1. We want a high priority so that we can get to the content before any other plugin does.

the_content is actually a filter hook which is explained thusly:

applied to the post content retrieved from the database, prior to printing on the screen (also used in some other operations, such as trackbacks).4

And that, surprisingly is it!

Administration shmadministration5

What we need at this point is to add an administration section to the code so that we can start implementing the extra desired functionality.

Due to WordPress’s plugin architecture – it is easy to add menu items in whichever section you would like. You can add them to the following sections:

  • Add a new submenu under Options
  • Add a new submenu under Manage
  • Add a new top-level menu (ill-advised)
  • Add a submenu to the custom top-level menu
  • Add a second submenu to the custom top-level menu

The section that we are most interested in is the new submenu under the options page – this will appear when you click on the ‘Settings’ tab. The following code will do just nicely:

add_options_page('Footnotes Reloaded', 'Footnotes Reloaded', 8, 'footnotesreloaded', 'fr_options_page');

The arguments are as follows:
Footnotes Reloaded: This is the title for the page – I.e. what appears in the Browser bar
Footnotes Reloaded: This is the title of the menu item
8: This is the access_level/capability
footnotesreloaded: This is the file
fr_options_page: This is the function to call (albeit optional)

We then add an action hook so that WordPress knows about it, and we have the following code:

// action function for hook
function mt_add_pages() {
  // Add a new submenu under Options:
  add_options_page('Footnotes Reloaded', 'Footnotes Reloaded', 8, 'footnotesreloaded', 'fr_options_page');
}

// Hook for adding admin menus
add_action('admin_menu', 'mt_add_pages');

I won’t go into too much detail about the function that is called – suffice it to say it prints out the HTML that makes up the options screen – the best place to get an idea is to view the official documentation on the subject.

Here is a screenshot of what we are trying to display:

Screenshot of the Footnotes Reloaded Options page

Screenshot of the Footnotes Reloaded Options page

WordPress really is quite nifty, it is easy to add and save options for the specific plugin – I would recommend that you do view the official documentation on the subject as it gives you a complete working example of how to set up an options page.

Retrieving the aforementioned options

Now that we have options set and saving properly, we need to be able to extract them for use within the parsing function for the footnote generator.

We use the same function to print out the options in the <textarea /> element, namely the get_option() function call.

For the header information:


if(get_option('freload_header') != "") {
  $content .= get_option('freload_header');
}

For the footer information:


if(get_option('freload_footer') != "") {
  $content .= get_option('freload_footer');
}

The trickier part comes from the options drop down menu, some custom JavaScript will be required – luckily for us, scriptaculous and prototype are both contained within the distribution, so we just need to add some custom effects.

That is what is up next.

Footnotes:

  1. Not really sure whether non-geeks will be reading this – but the ‘hello world’ is generally the first programme that you write in any new language.
  2. still looking for a nice code highlighter plugin.
  3. For those who are interested, this is using the reCAPTCHA mailhide API for WordPress – which I think is pretty nifty. If you haven’t clicked on it, feel free to do so.
  4. see WordPress Filter Reference for more details of other filters that may be used. Alternatively, the WordPress Action Reference lists all of the action hook names that may be applied.
  5. In WordPress nomenclature, this is known as ‘options’ see the full development documentation

Like my footnotes?
Want to add footnotes to your blog?
They can be added easily to your WordPress installation