Freelinking ver. 3 uses a plugin system to enhance the freelinking syntax and enable different kinds of links. Plugins can be simple URL constructors, or can use more sophisticated methods and have complete control over the link and target text. The output of plugins can also be customized through various hooks and theme functions for better integration with other modules and site design.
Having a small set of generally useful “easy-linking” plugins bundled with the project is only the first step Freelinking takes to help authors create links. Freelinking also has a framework that help developers quickly create new “easy-linking” plugins for custom websites.
Plugins can be created in two different ways. The recommended method is to create a new module, as a submodule of freelinking. However, you may also create a plugin as an include file.
By packaging your plugin as a module, you may distribute it as a project through Drupal.org, make use of other modules with proper tracking of requirements, and make use of any Drupal hook functions without worrying about collisions with Freelinking's own behavior.
If you publish your submodule on Drupal.org, post a message in the Freelinking issue queue, calling attention to your project so it can be linked to from Freelinking's project page.
A submodule can create a plugin for Freelinking by
implementing
hook_freelinking()
to return the definition of
your plugin as an element of an array, like so:
function mymodule_freelinking() { $freelinking['myplugin'] => array( 'indicator' => '/myplugin/', 'translate' => array(' ' => '_'), 'replacement' => 'http://example.com/node/%1', ); return $freelinking; }
To create a simple freelinking plugin, just drop a “.inc” file in the plugins/ directory under Freelinking. By convention, these should be named “freelinking_plugin.inc”, where “plugin” is the name of the plugin.
Each file should at least define one indicator, where the long
version of the indicator is identical to the name of the plugin.
However, it is possible to define multiple plugin indicators per file
to denote slightly changed semantics. See for example
freelinking_wiki.inc
for an example of this.
The only difference in structure between an include file and a
submodule is the lack of a hook_freelinking()
function
wrapper around the freelinking array that defines your plugin. In an
include file, the example above would simple be:
$freelinking['myplugin'] => array( 'indicator' => '/myplugin/', 'translate' => array(' ' => '_'), 'replacement' => 'http://example.com/node/%1', );
This functionality primarily exists for the ease of packaging default plugins with the Freelinking module, and to allow developers to add custom plugins to their site without going to the trouble of wrapping it in a module.
However, if you create a format you think others may want to use, please create a new issue (“Contributed plugin …”) and upload the plugin code to the Freelinking issue queue. If it passes community review, it will be included as a plugin with the next release of Freelinking.
$freelinking
arrayThe plugin's element in the $freelinking
array is
named after the plugin. In the example above of a plugin called
“myplugin”, the element your plugin would add to the array would be
$freelinking['myplugin']
. Your element defines an
array, with the following elements:
indicator
[REQUIRED] '/myplugin/'
. This means that freelinks for this plugin will look
like [[myplugin:something]]
. Freelinking uses the colon (“:”) as
the separator between the indicator and the link text. It should not
be part of the indicator string.translate
[OPTIONAL]'translate'
of
array(' ' => '_')
. For reference, this array will be run through
the PHP function
[strtr()](http://http://us.php.net/manual/en/function.strtr.php).replacement
[REQUIRED (unless callback
exists)]replacement
is a string for the URL, where the special string %1
gets replaced by the link text in the freelink. For our example, if
we're going to https://www.drupal.org/node/something, we'd use the
replacement string “https://www.drupal.org/node/%1” and our freelink
text would be put in place of the %1. If you are using a URL
replacement style of freelink, the replacement
string
is required.callback
[REQUIRED (unless replacement
exists)] $target[1]
. This function is expected to return an html fragment
(most likely a link, but it wouldn't have to be a link). If your
plugin is not using replacement,
then the callback
element is
required.settings
[OPTIONAL]html
[OPTIONAL]tip
[OPTIONAL]t()
for
localization as demonstrated below. This is used as the default text
for filter tooltips (HTML title
attribute).weight
[OPTIONAL]enabled
[OPTIONAL]failover
[OPTIONAL]variable_get('freelinking_pluginname_failover', '…')
in
the callback code. If you set it to a single value, that value will
be displayed in a disabled textfield in the configuration of the
plugin.So, a simple freelinking plugin only needs to include this array. Here's an entire plugin one might see in a very simple .inc file to link to a wiki page and some specific site:
$freelinking['myplugin'] => array( 'indicator' => '/my(plugin)/', 'translate' => array(' ' => '-'), 'replacement' => 'http://example.org/wiki/%1', 'tip' => t('Click to visit a wiki page at example.org.'), );
The plugins in freelinking_wiki.inc
are examples of
this type of plugin.
The callback
element of
your $freelinking['plugin']
array can define a
PHP function that will be used to create the link. This function will
get the target value for the link, and is expected to return a link.
Freelinking will make the substition based on the return value of this
function.
By default, the target value passed to the callback function looks like this:
array( 'target' => target, 'dest' => target, );
However, if the text uses the vertical bar (“|”) to separate the elements, it more elements is added to the array. This is the expanded usage:
array( 'target' => target match, 'dest' => destination, 'text' => anchor link text, 'tooltip' => tool tip (title attribute), 'other' => array(miscellaneous arguments), );
The syntax is:
[[indicator:target|title|tooltip|arg1|arg2|…]]
Most of the plugins that ship with freelinking use the callback. You may want to look at them to learn from example.
Your plugin callback may specify a “failover” or fallback action in the event they choke. For example: If the specified node title cannot be found in the database, a link to create a node with that title can be put in place as a failover fallback action.
Plugins specify failover by returning;
array( 'plugin' => 'failover plugin' );
When lookup fails or access is denied. the failover plugin is
triggered to take over trying to process the target. You can pass a
modified target in this way by just adding 'target' =>
$target
to the return array. You may also specify:
array( 'error' => 'error message' );
to provide an error message.
You can use
variable_get('freelinking_pluginname_failover', '…')
to get the preferred failover for your plugin. This is based on the
failover element in the plugin definition or on creating a form
element by that name in your settings.
If your plugin will require some settings, they can be defined in a
“freelinking_plugin_settings” function in your include file,
or explicitly using the settings
element of the plugin's
freelinking array (necessary for modules). This function should return
a Drupal FormAPI array of the various settings your plugin will
need. The module will add these form controls to the project'
settings page. Your plugin can use these settings in
the $freelinking
array, or the callback function, as
necessary.
A simple example of how to use settings is part of the wiki plugins
(freelinking_wiki.inc
). It uses one setting to control
the language code that the URL to Wikipedia should use. The setting is
used in the
$freelinking['wikipedia']['replacement']
element, using the language
code as part of the URL.
The freelinking_nodetitle.inc
plugin also uses the
settings array. This plugin has settings to control what happens when
a link cannot be found, and is able to restrict the lookup of content
to certain content types. This is an example of using settings within
the callback function.
The Freelinking API allows you to customize freelinking plugins you create specfically for your site.
For API functions and examples of their use, see freelinking.api.php
.
They are also suumarized below:
By implementing this function, you can adjust the elements of the link array before it is rendered into an HTML link. For example:
function mymodule_freelink_alter(&$link, $target, $plugin_name, $plugin) { static $count; $link[2]['attributes']['name'] = 'freelink-' . $count++; }
This function will alter every link created by freelinking to insert the number of links found in the filtered text as an anchor. You might also make a more targeted alteration:
function mymodule_freelink_alter(&$link, $target, $plugin_name, $plugin) { if ($plugin_name == 'google') { $link[2]['attributes']['title'] .= ' Isn't Google nifty?'; } }
For documentation on the structure of the $link
array
here, read up on the
API entry for the l()
function.
theme('freelink', $plugin, $link);
This is the function that renders the $link
array we
“altered” above into HTML. You can override this, like any theme
function.
theme('freelink_error', $plugin, $message);
This function renders an error message provided by a plugin for display in the page.