Extend the number of services

Implementing a hook helps third part developer to build their customs link to new social networks without overwrite the main module avoiding accidental overwritings when the main module is updated, that's the main feature available from the version 2.x of Service Links.

Implementing hook_service_links()

The hook_service_links() allow to extend easily the number of services without modify the files provided by Service Links, but to make it works is important write a custom module following the steps described below.

First of all implement a hook mean write a function composed by the module filename and the name of the hook, it have to return an associative array composed by three standard fields: name, description and link.

<?php
/**
 * @file
 * Extend the number of services in my_module.module.
 * 
 * This small example show how to implement
 * hook_service_links() within a module.
 *
 */

/**
 * Implements hook_service_links().
 */
function my_module_service_links() {
  $links = array();

  $links['service_id'] = array(
    'name' => 'Service Name',
    'description' => t('Share this content in my new service!'),
    'link' => 'http://service-domain.org/?add_url=<encoded-url>&t=<encoded-title>',
  );

  return $links;
}
?>

The basic fields

In details the field used are:

service_id
This field represent an univoque id used internally by Service Links engine, don't use spaces and capital character here, dont' use an existing id, but lower case chars, numbers and underscores are allowed. This same id is used also to determine the name of the default associated icon: service_id.png
name
The real name of your service, here you can use all the chars avoided for service_id, it will be used when the link is rendered with text.
description
It's used to fill the title attribute within an anchor HTML tag and it appears like a tooltip when the mouse goes over it.
link
Maybe this is the part most difficult to code, but most of services provide an info page explaining what parameter to use, otherwise another approach could be use Google to catch the blogs or websites using successful the same social network as link ;).

Filling the link field

A link is a structured string which follow some basic rules: every social network provides a specified page reserved to add any allowed content on the main page of the user who is going to share it, that would result on a simple bookmarking, a link on the main page, or whatever the social network allows to share with your followers or friends.

"http://service-domain.com/path/submit?url=<content-url>&title=<content-t..."

What Service Links does is provide the placeholders for every parameter needed which in most of cases are: title, url, summary (also know as teaser from Drupalers), corresponding to: <[raw-]encoded-title>, <[raw-]encoded-url>, <[raw-]encoded-teaser>.

The squares indicate an optional string, i.e. for the title we have: <raw-encoded-title> and <encoded-title> the difference is in the kind of decoding function used by the service itself. To understand what's the right one, is useful to look how the spaces are encoded in any working example: if they are substituted by %20 then a <raw-encoded-xxx> tag is needed otherwise when it's substituted by a + an <encoded-xxx> tag is better.

Service Links provides other placeholders like:

<[raw-]encoded-source>
the name of the current website
<node-id>
the current node id
<[raw-]encoded-short-url>
specify that a short url would be preferable for this service, look how enable short url at the general settings page
<[raw-]encoded-long-url>
this is useful when an url should never be shortened
<[raw-]encoded-query>
this is reserved to some internal services which make use of a portion of url instead of the full one
<front-page>
this is the link to the front page

Custom tags can be added using the field called preset which specify the name of the function to be executed before the tag substitution start, this field will be explained in the further section.

Advanced array fields

Beside the standard fields there are others created to support special services called widgets. Widgets are dynamic buttons which allow to submit a content but also display the number of times the content has been shared or popup small windows within the same page, to achieve that they make use of javascripts, that's why they are called dynamic.

<?php
/**
 * @file
 * Extend the number of services in mymodule.module.
 * 
 * This small example show how to implement
 * hook_service_links() within a module.
 *
 */

/**
 * Implements hook_service_links().
 */
function mymodule_service_links() {
  $links = array();

  $links['service_id'] = array(
    'name' => 'Service Name',
    'description' => t('Share this content in my new service!'),
    'link' => 'http://service-domain.org/?add_url=<encoded-url>&t=<encoded-title>',
    'javascript' => array(
      'http://service-domain.org/somepath/javascript.js',
      'my-javascript.js',
    ),
    'css' => array(
      'http://service-domain.org/somepath/css.css',
      'my-css.css',
    ),
    'attributes' => array(
      'class' => array(
        'class-name',
        'class-name-2',
      ),
    ),
    'preset' => 'my_preset_function',
    'callback' => 'my_callback_function',
  );

  return $links;
}
?>
javascript
Most of times widgets requires an external javascript and using not standard tags or attributes a second one could be used to replace them dinamycally.
css
This work the same as the previous but load css instead of javascript files.
attributes
Additional attributes like class can be specified here, better put here only XHTML standard attributes and load the other ones using the callback field.
preset
Here goes the name of a function which can be used to add more tags to be substituted within the link, or every operation executed before the tags substitution.
<?php
function my_preset_function(&$service, &$settings, $node = NULL) {
  $settings['tags']['my-tag'] = '';
  // You can evaluate the string to substitute using the $node object
  // or other settings available in the array.
  $settings['subst']['my-tag'] = 'Whatever you want';
}
?>
callback
The callback function is executed after the parameters have been substituted to the link. Usually this is used to load javascript settings or change the values of attributes.
<?php
/**
 * This is the callback function used by Pinterest widget.
 */
function ws_pinterest_button_data(&$service, &$settings) {
  static $pb_settings;

  if (!isset($pb_settings)) {
    $pb_settings = array(
      'countlayout' => check_plain(variable_get('service_links_pb_countlayout', 'horizontal')),
    );
    drupal_add_js(array('ws_pb' => $pb_settings), 'setting');
  }
}
?>