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). 

Tuesday, April 06, 2010

Creating a Custom 404 (Page Not Found) Page in Drupal

In the event of an HTTP 404 error ("Page not found") this PHP snippet will render a site search form, but will take keywords from the user's erroneous URL and prepopulate.

Create a new node (node/add/page), and ensure you can enter PHP code in your page body (check input filters).

Insert the following code into the body of your new page:


<p>I'm sorry the page you are looking for cannot be found.</p>
<div id="error-search-box">
<?php
// check that the search module exists and the user has permission to hit the form
if (module_exists('search') && user_access('search content')) {
$path = $_REQUEST['destination'];
$keys = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', ' ', $path));
print drupal_get_form('search_form', NULL, $keys, 'node', 'Search this site');
}
?>
</div>


Save this new page (ideally with a custom URL of your choice: such as /page-not-found) and tweak your CSS accordingly.

So that Drupal will send users there when HTTP 404 errors are generated, go to admin > settings > error reporting (/admin/settings/error-reporting), and set the default 404 error page to page-not-found (or whatever). (You might want to do a 403 error page while you're here too).

If the above phases you out, as with all problems Drupal, there's a module for that... the thrifty404 module will do exactly the above, but you'll need to do a bit of cunningness in the Drupal theming layer to customize it.

And Bob's your aunty's live-in lover..!

Monday, November 02, 2009

Drupal/Drush on Windows

Spent the past 3 years getting very comfortable using a Mac/Unix environment, but have mainly been using a Windows Server at work for hosting my sites. Now striving to reach Drupal ninja status, thought it was time to use Drush on the Windows [2003] server instead of just my DEV machines.

Pretty easy to get the basics of Drush running, although kept getting these annoying 'Cannot find module (IP-MIB): At line 0 in (none)' errors in every command being executed on the MS-DOS CLI... Bit of Googling found that this is a PHP error because the MIB files need to be on every Windows drive that you are executing PHP scripts. Even though my main website directories are on the D: drive, Drush is on my C: drive.

So, solution is to find the \USR folder, then copy \USR\mibs to the root of each drive you want to execute Drush (or, indeed, any PHP scripts) from. If you know tons about PHP (and I don't) you can probably disable the offending PHP extensions in php.ini - but in my case 'it ain't broke' so I'm going to leave as much of my PHP configuration alone as possible.