Web Design & Development • eCommerce • Content Management • Internet Marketing • Nottingham
blog section

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.

To do this, I’ve added a small helper module to my site. In there, I’ve added a function to implement Drupal’s hook_link_alter() function. Here’s the code to do it:

<?php
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;
    }
  }
}
?>

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

Theming purists are probably screaming that this belongs in the theme layer… well, that’s probably right. You can also achieve the same effect in the template.php file. I’ll post that too, if I can get it working…

Nice piece of code.

And, yes, you're right, template.php is better place.

Posted by Drupal Theme Garden on Wednesday, 12 March, 2008 - 11:38.

Great idea!

Another example is adding the following in node.tpl.php
This example replaces the words “Printer-friendly version” with “printer.png”

<?php
$links
= str_replace('>Printer-friendly version<', ' title="Click to view a printer-friendly version of this document."><img src="images/printer.png"><',$links);
?>
Posted by lgm on Wednesday, 9 April, 2008 - 18:36.

Well… you could do that, but there’s a number of reasons why not to. Firstly, by using a snippet like the one above in the template.php, you are providing a solution to all your node types. Secondly, in the example above, you’re not using standard Drupal functions such as l() and t(), which you really ought to for reasons of coding standards, availability for translation and server security.

Just so you know…

Posted by Nik on Wednesday, 9 April, 2008 - 23:38.

As the print module maintainer, I would like to point out that there's better solutions in the case of the print module than either of the above. You can theme the $links link of the print module to your heart's content using the theme_print_format_link() function.

See more about that in #4 of http://drupal.org/node/190173.

Posted by Joao on Monday, 14 April, 2008 - 10:59.

Thanks for the tip, Joao – the technique I used above is really only meant as an indicator of a generic solution. A lot of modules, including forward (aobve) and taxonomy (core), do not have such theme functions. As such, this technique is probably the next most favourable.

Good news that the print module is becoming more configurable and accessible though!

Posted by Nik on Monday, 14 April, 2008 - 12:32.

hi,

is it possible to do this without making a module? somewhere in phptemplate for example.

Posted by krunar on Thursday, 1 May, 2008 - 20:08.

It certainly is – I haven’t had enough free time to juggle the example above into theme-based code (that works for me…!) yet though.

The $links variable is available from within _phptemplate_variables, so you can alter this in template.php in the case: 'node' bit of that. If you read this article that last bit will be clearer, if you don’t already know what I mean.

So, thed code below should work in a similar fashion, although I’ve had mixed luck – it had otherwise been my intention to publish the full code for that method also.

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch (
$hook) {
    case
'node':
    foreach (
$vars['node']->links as $module => $link) {
      if (
$module == 'forward_links') {
       
// alter stuff here
     
}
    }
  }
}
?>
Posted by Nik on Thursday, 1 May, 2008 - 20:23.

hi, I want to theme $links in comments

in _phptemplate_variables function, I add following code

case 'comment':
print_r($vars['comment']->links);
break;
nothing shows up, probably theres no such variable called $vars['comment']->links.

can you please show me how theme it in comment. I got stuck here for 2 days.

thank you so much for ur help.

Posted by feelexit on Wednesday, 14 May, 2008 - 03:30.

Post new comment