one inch frame
the personal site of eric a. Farris

Creating FL3 plugins

Plugins for Freelinking3 are short little PHP include files that can modify the behavior of the module to allow for richer freelinks. While the format is still in flux, as FL3 is in its very early stages still, the primary use of a plugin is to define an element of the $freelinking[] array. Simple plugins will need nothing more.

Freelinks in FL3 are made up of text surrounded by double-square brackets, like this. FL3 also includes an (optional) handler, called an indicator, which is given before the link. The indicator and link are separated by a colon. So, a freelink using the “nodetitle” plugin would look like this: [ [nodetitle:This is a node title]].

The structure of the $freelinking() array

(again, just to point out, this is still in development)

A FL3 include file will define its own element of the $freelinking array. The key for this element will be the name of the plugin. I will show a couple examples of completed plugins later in this post.

The elements of the array that a plugin can define are as follows:

  • 'indicator' — This element is required. It defines a regular expression that will be used to indicate that the link is to be handled by this plugin.

  • 'translate' — This element is optional, and defines an array of characters in the form of from=>to which tells FL3 that the link’s text should be run through strtr() before continuing. Things like changing spaces to underscores or dashes are handled here.

  • 'replacement' — This element, or the callback element, is required. Simple plugins can use the replacement element to define what a target freelink should look like. The replacment text is a URL, with a %1 where the translated link text should go.

  • 'callback' — This is for more complicated FL3 plugins. This is the name of a function, which is also defined in the plugin file, which will get the text portion of the freelink and is expected to return the replacement text. This gives the plugin full control over what the completed link should look like, including control not only of the returned target (href) of the link, but also the text of the link itself.

A simple FL3 plugin

Here is what the complete plugin for wikipedia looks like. The plugin wants a freelink that looks like [ [w:something]], and will turn it into a link to Wikipedia’s article on ‘something.’

<?php
$freelinking['wikipedia'] = array(
  'indicator' => '/w(iki(pedia)?|p)?/',
  'translate' => array(' ' => '_'),
  'replacement' => 'http://en.wikipedia.org/wiki/%1',
);

(that’s without comments and other header information, of course. And there’s probably going to be a ‘description’ element, but there’s no support for it as yet.)

A more complicated FL3 plugin

Here is a plugin that takes links that looks like [[[drupalorgnid:111]] and returns a link to the node on Drupal.org. This plugin uses a callback function to look up the title of the node and uses it as part of the link text that gets returned.

<?php
$freelinking['drupalorgnid'] = array(
  'indicator' => '/d(rupal)?o(rg)?nid/',
  'callback' => 'freelinking_drupalorgnid_callback',
);

function freelinking_drupalorgnid_callback($target) { // resolve nid to a node title
  $url = 'http://drupal.org/node/' . $target[1];
  $result = drupal_http_request($url, array(), 'GET');
  $found_title = preg_match('/<h1.*>(.*)<\/h1>/', $result->data, $matches);
  if ($found_title) { // regex worked to scarf title of page
    $replacement = l('Drupal.org: "' . $matches[1] . '"', $url);
  }
  return $replacement;
} // endfunction freelinking_drupalorgnid_callback

Default plugins

Currently, the following plugins are written and working:

  • Wikipedia
  • One Inch Frame (yeah, shameless plug, but also a good example. Probably won’t ship with the finished module)
  • Drupal.org project
  • Drupal.org nid
  • nodetitle (ie., the behavior of versions 1 and 2 of freelinking)

What’s working (and not working) right now

The plugins above are working. The nodetitle plugin supports linking to content that doesn’t yet exist, presenting a node/add form, but doesn’t run through the /freelinking space, which is good (for SEO), but also bad in that it does not know if content has been created after the fact. This will require some sort of nodeapi call, I believe, but I’m still looking in to the best way to do that with the least amount of overhead.

Also working now is a settings page where the site admin can set up which plugin to use if there is no indicator. Ships with ‘nodetitle’ as the default plugin, which mimics the behavior of older versions of freelinking.

The main thing to add at this point is some per-plugin settings. At least the nodetitle plugin will have to expose some settings, like a node-type restriction, what to do when users don’t have the necessary access to get to a node creation form, and so forth. I want to do this without adding unnecessary bloat to the plugin file nor the admin/settings/freelinking form.

-->