Theming the $links variable in Drupal nodes

This snippet of code gives a brief example of how to rewrite components of the $links variable to make them prettier :) Specifically, here I’m overwriting the link generated by the Forward module. You can see the result below: the little envelope icon labelled “Email”. Normally, this would just say “Forward this page”, which is a bit… well, it could be better. Obviously, it’s nice to be able to change these things to taste.

There are two ways to achieve this result: using theme code in template.php, or inside of a helper module. First, I’ll discuss the module approach.

The helper module method is what I had originally used. It’s a little neater, in that you code it once and forget about it, and it doesn’t clutter up template.php’s _phptemplate_variables function, which can easily become bloated with code.

In the module, I’ve added a function to implement Drupal’s hook_link_alter() function. Here’s the code to do it:

function mymodule_link_alter(&$node, &$links) {
  foreach (
$links as $module => $link) {   // iterate over the $links array
    //drupal_set_message(print_r($links)); // uncomment to display your $links array

    // check if this element is the forward module's link
if ($module == 'forward_links') {
$title = t('Email this page to a friend');    // change the title to suit
$path = path_to_theme() . '/images/email.png'// make an image path

      // now update the links array
      // set the title to some html of the image and choice of link text
$links[$module]['title'] = theme('image', $path, $title, $title) . ' Email';

// let's set some attributes on the link
$links[$module]['attributes'] = array(
'title' => $title,
'class' => 'forward-page',
'rel' => 'nofollow',

// this must be set, so that l() interprets the image tag correctly
$links[$module]['html'] = TRUE;

Ok so really, this ought to be done in the theme layer. Like I said, it’s perhaps not as compact and neat, but here’s the code. It’s mostly the same, but note a couple of additions and changes: firstly, we are not changing $links – this is a pre-rendered string by the time it gets to the template.php. We need to get to the original goodies! Hence, we use $vars[&#039;node&#039;]-&gt;links[module-name][field-name].

Secondly, note that because we have now altered the value of one of the original links’ values, does not mean that the node’s $links is correct. This is the bit that caught me out! We must now regenerate the $links variable using the theme_links() function, as per the last line of code below. This mimics what phptemplate.engine does in core.

function _phptemplate_variables($hook, $vars = array()) {
  switch (
$hook) {
      foreach (
$vars['node']->links as $module => $link) {
        if (
$module == 'forward_links') {
$title = t('Email this page to a friend');
$path = path_to_theme() . '/images/email.png';
$vars['node']->links[$module]['title'] =
theme('image', $path, $title, $title) . ' Email';
$vars['node']->links[$module]['attributes'] =
'title' => $title, 'class' => 'forward-page', 'rel' => 'nofollow');
$vars['node']->links[$module]['html'] = TRUE;
$vars['links'] = theme('links', $vars['node']->links,
'class' => 'links inline'));

You can achieve this effect for anything that’s in the $links array. On this page (below), you can see the link I’ve described here, another for print-friendly pages and also a themed comment link.

Blog Tags: DrupalThemesModules