Tuesday, May 25, 2010

Theming Drupal [Node] Links

I spent ages trawling the internet trying to find easy ways to change the little links that Drupal attaches to each node ('Add new comment') and either remove them, change them to icons or shuffle the order.  Options available include:
  1. Write a custom helper module that implements hook_link_alter()
  2. Make the changes inside the theme's template.php preprocess_node
  3. Overwrite the li a attribute with CSS
Option #1 just didn't work for me - it kept outputting the updated links in both the links ($links) and the categories ($terms).Option #3 was just bad. So I settled on #2:

I wanted to create custom icons (rather than text) and remove a few links generated by the Feed API module; I also was using the Add this module and wanted that to be the last link at the bottom of the page. So created some nice icons (I used the wonderful FamFamFam Silk icons and a few custom drawn ones) and added them to the /images directory of my theme.  I then edited the template.php file in my theme and added the following function:

function mytheme_preprocess_node(&$variables) {
    $patheme = drupal_get_path('theme','mytheme');
    $links = $variables['node']->links;
    global $user;
   
    //Repeat following for each $links item you wish to change
    if($links['comment_add']){
      $links['comment_add']['title'] = theme('image', $patheme.'/images/comments_add.png', t('Add a comment'),t('Add a comment'));
      $links['comment_add']['html'] = true;
    }
   
    //Remove link example: removes link to 'Original Feed' (Feed API)
    unset($links['feedapi_feed']);
   
    //Removes 'Login to post comments' link for anon users
    if (!$user->uid) {
      unset($links['comment_forbidden']);
    }
   
    //Simple way to affect order that links are rendered
    //Move addthis to end of $links
    if( isset($links['addthis']) ) {
      $addthis = $links['addthis'];
      unset($links['addthis']);
      $links = array_merge($links, array('addthis' => $addthis));
    }

    //Reset node template links
    $variables['links'] = theme_links($links, array('class' => 'links'));
}



And you should obviously customize accordingly. There's a little more explanation in 'Front End Drupal' (Hogbin/Kafer - Prentice Hall 2009) pp163-165 which I highly recommend. I was also using the Print module and there is advice on customizing the module's icons at http://drupal.org/node/190173#themeicon.

And this is the end result (Left to right: Add new comment, print-friendly view and 'Add This' button). 

3 comments:

  1. BTW replace 'mytheme' with the name of your own theme

    ReplyDelete
  2. Nice! Would you like to present this at one of the upcoming LA Drupal meetups?

    ReplyDelete
  3. Sure - bit tight for a lightning talk, but 10 mins ought to do it

    ReplyDelete