Posts filed under 'Programming'

How to Give Your Plugin Settings a Submenu

While rebuilding the posts plugins for WordPress 2.5 I became frustrated by the excessive length of their settings pages and more than a little envious of other plugins which managed to split their settings into subpages accessible from a submenu.

I pored through more opaque code than is comfortable and eventually decided I should try and build an easy, reusable solution. Here’s the end result (download code):


class PluginSubpages {
  var $pages = array();
  var $parent_page = '';
  var $current_page = array();

  function PluginSubpages() {
    $this->__construct();
  }	

  function __construct() {
    $this->parent_page = $_SERVER['QUERY_STRING'];
    $p1 = strpos($this->parent_page, 'page=');
    $p2 = strpos($this->parent_page, '&');
    if ($p2 === false) {
      $this->parent_page = substr($this->parent_page, $p1+5);
    } else {
      $this->parent_page = substr($this->parent_page, $p1+5, $p2-$p1-5);
    }
  }
	
  function add_subpage( $title, $slug, $view ) {
    $this->pages[] = array('title' => $title, 'slug' => $slug, 'view' => $view);
  }
	
  function page_from_slug( $slug ) {
    if (!isset($slug)) {
      return $this->pages[0];
    }
    foreach ($this->pages as $page) {
      if ($page['slug'] === $slug) {
        return $page;
      }
    }
    die('non-existent slug');
  }
	
  function display() {
    echo "\n<ul id=\"submenu\" style=\"display: block\">\n";
    $base = $_SERVER['PHP_SELF'] . '?page=' . $this->parent_page . '&subpage=';
    $this->current_page = $this->page_from_slug($_GET['subpage']);
    foreach($this->pages as $page) {	
      if($page === $this->current_page) {
        echo "<li><a href=\"$base{$page['slug']}\" class=\"current\">{$page['title']}</a></li>\n";
      } else {
        echo "<li><a href=\"$base{$page['slug']}\">{$page['title']}</a></li>\n";
      }
    }
    echo "</ul>\n";
    $this->current_page['view']();
  }
	
}

There’s one nasty trick in there which I’ll come to but first … how to use it.

You’ll already have the code to register your admin settings page:


function plugin_option_menu() {
  add_options_page('Plugin Options', 'Plugin', 8,'plugin-file', 'plugin_options_page');
}

add_action('admin_menu', 'plugin_option_menu', 1);

function plugin_options_page(){
...
}

Instead of filling ‘plugin_options_page’ with all your settings code you use PluginSubpages to delegate the hard work.


function plugin_options_page(){
  echo '<div class="wrap"><h2>Plugin</h2></div>';
  $m = new PluginSubpages();
  // register the subpages
  $m->add_subpage('General', 'general', 'plugin_general_options_subpage');
  ...
  $m->add_subpage('Other', 'other', 'plugin_other_options_subpage');
  // show them!
  $m->display();
}

Each of the subpage functions behaves independently, e.g.,


function plugin_general_options_subpage(){
  $options = get_option('plugin-general');
  if (isset($_POST['update_options'])) {
    ...
  } 
  ?>
    <div class="wrap">
    <h2>General Settings</h2>
    <form method="post" action="">
    ...
    <div class="submit">
      <input type="submit" name="update_options" value="Save General Settings" />
    </div>
    </form>  
    </div>
  <?php	
}

Now about that ‘nasty trick’… PluginSubpages->display() spits out the HTML for the menu as an unordered list. How should the menu list be styled? I could include specific inline CSS styles for the menu but I thought it would be better if the subpage menu looked like the preexisting admin menu.

This is the evil bit. I found that giving the subpage menu the id of ‘submenu’, the id of the admin menu I could steal all its styles and the subpage menu would fit into its surrounding seamlessly. The only catch is that CSS ids cannot be duplicated — each must be unique. In practice, though, every browser I tried coped without a squeak. Just don’t expect your admin pages to validate if you use this technique.

1 comment March 27th, 2008

Novice Notes on the Official WordPress Plugin Directory

As I’ve said I’ve been wrestling with the plugin directory and, as I suspected, the trouble is down to my lack of smarts. Two things to be aware of if you are wanting to host your plugins at the official site:

  • When they say that you should name your tags/releases using only numbers and periods they mean it. I was using 2.5 bxx not thinking a space would cause an issue but of course it did when the automatic updater kept giving up on the zip files it downloaded. From now on, 2.5bxx until I can drop the beta designation.
  • That stray space thing managed to keep hidden for a few days because I couldn’t even get that far. I’ve been grumbling that my installation instructions were not showing correctly and trying, in vain, to get help… well, a little while ago as I was poring over the readme.txt for the umpteenth time I was struck by lightning (OK I’m exaggerating) and thought to check the encoding of the file. I don’t know how but the readme.txt files I’d uploaded were encoded as utf-8. The Readme Validator hadn’t caught the problem but it was enough to make the directory ignore the files.

So no spaces in release tags and just plain old ANSI in the readme.

3 comments March 25th, 2008

Still Fighting the Official Plugins Directory…

I haven’t got a response from the official WordPress plugin directory to work out why the proper instructions are not displaying and meanwhile I am getting a lot of folks wondering what on earth is going on and why the post plugins are no longer working.

Here are some emergency directions for the interim…

First follow these links to download the latest versions of Similar Posts, Recent Posts, Random Posts, or Recent Comments. You will also need a new copy of the Post Plugin Library which is now configured as a plugin.

Load stuff up to the plugins directory (you will notice that some of the folder names have been changed to accommodate the requirements of the WordPress folks) and activate as normal. The library should be automatically activated when any of the other plugins is activated.

Hopefully after all this hullabaloo future updating will happen smoothly and automatically (wishful thinking!).

Please get in touch if you are still having problems. The report-a-bug option under the settings menu is a helpful way of doing so … or just leave a comment.

March 24th, 2008

WordPress 2.5 and Automatic Plugin Updates

Update: Check out this post for some extra instructions.

Well I’m wrestling with the new ability of WordPress 2.5 to notify when a fresh version of a plugin is available on the official directory. Up until now I haven’t used the directory but today I tried to get my post plugins up and running over there so that the automated update functionality could be used.

It is working … just. Please bear with me if you have problems.

  • I have had to make the Post-Plugin Library into a plugin in its own right.
  • The folders the plugins go into has changed in some cases: similar-posts remains the same but recent-posts has become recent-posts-plugin and so on. This is because I had to find a unique name for each plugin at the directory.
  • After the first automatic update you might need to re-activate the plugin.
  • … and who knows what else …

And, by the way, Happy Easter!

2 comments March 23rd, 2008

WordPress Plugins Updated: Similar Posts, Recent Posts, Random Posts, and Recent Comments

Finally! I have posted the updated (2.5) versions of my post plugins and they are full of enhancements and even the odd fix… Check them out from the plugins page but please take note:

  • They are still beta releases and, given the number of modifications I have made, I am sure I will have a few issues to correct. If you have any problems try reporting them through the in-built bug-reporting tool. Other comments are, of course, welcome on each plugin’s own page.
  • The plugin code has been substantially refactored to minimise duplication and, as a result, the four plugins now share a library. Please take care to read the upgrade directions rather than blundering ahead (the way I usually do myself!).
  • If you have been using the Plugin Output Cache you will need to update to the latest version.

So … new features, new options, and new output tags … and a few bug fixes as well.

New Features

  • Ready for WordPress 2.5 with a new matching admin interface.
  • Random Posts is about twice as fast as before.
  • Similar Posts has had a lot of work. It now uses its own table instead of using custom fields. Tag-based similarity has been added and the balance between content, title, and tags is fully adjustable. You can now add similar posts to your feeds without an extra plugin (Similar Posts Feed has been discontinued). I have supplied stop lists for English, French, German, Spanish, and Italian (with more to come) — and stemming algorithms to match. I also have plans for various refinements and extensions of the similarity algorithm, including some support for Japanese, Chinese and Korean.
  • When used as widgets the plugins have a new option to only show under certain circumstances by using WordPress Conditional Tags like ‘is_single(), e.g.,
    is_single() && is_paged()
  • The plugin display can now be injected on a post-by-post basis by using embedded tags, e.g., <!--SimilarPosts-->.
  • You can now report bugs from the plugin settings pages and automatically send along basic information to aid debugging, like what version of PHP, MySQL etc. are in use.
  • There is now an option to completely remove the plugins and all their settings without having to fiddle with phpMyAdmin.
  • Increased security with proper nonce-protection and better screening of settings.
  • A much better memory footprint, especially when more than one of the plugins is installed.
  • The plugins are set up for internationalisation … but as of yet not translated.
  • It is now much easier to extend the plugins with your own output template tags.
  • The plugins are much more careful of how they handle multi-byte character sets.

New Options (or settings as WP 2.5 calls them)

  • It is now possible to have no output at all if the plugin finds no matching posts.
  • The fallback text when no posts are listed can now contain embedded output tags.
  • You can now choose to only include posts that are more than, or less than, a certain number of days, months, or years old.
  • A content filter can be turned on to expand tags embedded in posts so that plugin output can be injected on a post-by-post basis.
  • The Recent Comments’ option to exclude certain comment authors (which never worked properly!) has been replaced with the option to omit comments left by the post’s author.
  • It is now possible to include ‘&’ in parameters passed by query-string.

New Output Tags

  • {totalposts} and {totalpages}
  • {postid}
  • {postviews}
  • alternate {commentlink2}
  • alternate {excerpt} preserving HTML etc.
  • a variety of ways to crop {title} etc.
  • {image}
  • {categoryid}
  • {commenterip}
  • and {php} which lets you insert your own code!

Bug Fixes

  • Better validation of settings.
  • Fixed an ordering bug in Recent Comments when grouped by post.
  • Fixed a problem on some systems with ‘include’ of relative paths.
  • No longer troubled by the awkward bug in MySQL version 4.1.21.

That should be plenty to play with!

24 comments March 17th, 2008

Due an Update to WordPress Post Plugins

Version 2.3.7 of the post plugins should be out soon. I’ve been making a bunch of little changes to provide some asked for features. The delay has been in the next version of Similar Posts which has undergone some major revisions including stemming and global word weighting. It also lets you configure the balance of content, title and tags (new) to get the most relevant posts for your particular blog. That’s meant some major architectural changes which I am trying to test before releasing. Also, since tag-based relevance is now included I’ve scrapped the ability to add keywords to a custom field. I have actually never heard of anyone using the feature but I’m bracing myself for a host of users rising up in revolt!

Any feature requests for upcoming versions?

3 comments December 13th, 2007

Post Plugins and More on Tags

Version 2.3.5 of the plugins is a rebuild to avoid all the admin page code being loaded when not needed. It also allows posts to be matched according to the current post’s tags.

Update

Version 2.3.6 restores the widgetiness I managed to remove in 2.3.5! Please if you downloaded a version 2.3.5 plugin download the 2.3.6.

November 3rd, 2007

WordPress Post Plugins Now Widgets

I have long intended to make my post plugins into widgets but have only just got to it. In fact it turned out to be an easy process.

Version 2.3.4 of the plugins also adds the option to exclude or include the current post from the output.

October 25th, 2007

WordPress Plugin: Highlight Author Comments

Just posted a rather simple plugin to highlight the comments made by the author of a post among all the other comments.

I’ve seen lots of ways of doing the job but they all seem to involve hacking the code of your template or of WordPress files. The new plugin does the job automatically — all you have to do is provide a snippet of CSS to apply to the special comments.

4 comments October 20th, 2007

WordPress, Tagging, and the Post Plugins

Version 2.3.3 beta of my post plugins adds support for WordPress 2.3′s built-in tagging.

You can find recent posts with a particular tag, similar posts that have any of a bunch of tags, random posts sharing all specified tags, or whatever permutation you like.

The new version also adds the much requested ability to include as well as exclude posts by category.

1 comment October 14th, 2007

Next Posts Previous Posts


Calendar

July 2014
M T W T F S S
« Jun    
 123456
78910111213
14151617181920
21222324252627
28293031  

Posts by Month

Posts by Category