I am trying to create a login link in Drupal 7 that will

  • keep the destination if set

  • generate a destination based on the page on which the link was clicked if not set

  • persist if set on subsequent clicks of the login link

  • not be generated if not already set AND the currently viewed page is an undesirable destination (such as user/logout)

I have written the following code and put it into to the body of a block only shown to anonymous users, however, as I am new to Drupal's api can someone more knowledgable here check to see if this is OK or can be optimized, and/or what other destinations other than user/* should NOT generate a destination if the destination is not already set:

<a href="/user<?php $curpath = current_path();
if (strpos($curpath, 'user/') === 0 && !isset($_GET['destination'])) { 
  print '';
else {
  $newdest = drupal_get_destination();
  $newdestimplode = implode('', $newdest);
  print '?destination=' . drupal_get_path_alias($newdestimplode);
} ?>">Login</a>

Alternatively if you know of a setting that puts the login link on pages for anonymous users with the above conditions or a LIGHTWEIGHT module (please don't suggest LoginTobboggan) that does this, let me know here.

1 Answer 1


I wrote this THEME_menu_link override to add a destination parameter to login links:

e.g in template.php:

 * THEME_menu_link override
 * Add unique class (mlid) to all menu items.
 * Add destination param to login link
function THEMENAME_menu_link($variables) {

  $element = $variables['element'];
  $sub_menu = '';

  $element['#attributes']['class'][] = 'menu-' . $element['#original_link']['mlid'];

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  // Add destination to login link
  if ($element['#href'] == 'user/login') {
    $status = drupal_get_http_header('status');
    // don't add dest back to 403 etc..
    if(strpos($status, '403') !== FALSE){
      $dest = drupal_get_destination();
    }elseif(strpos($status, '404') !== FALSE){
      $dest = array('destination' => 'home');
    }elseif(strpos($_GET['q'], 'user/register') !== FALSE){
      $dest = array('destination' => 'home');
    }elseif(strpos($_GET['q'], 'user/login') !== FALSE){
      $dest = array('destination' => 'home');
    }elseif(strpos($_GET['q'], 'user/logout') !== FALSE){
      $dest = array('destination' => 'home');
      $dest = array('destination' => drupal_get_path_alias());
    $element['#localized_options']['query'] = $dest;
    $element['#attributes']['class'][] = 'login';

  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
  • Thanks for this, it looks pretty good. However, for some of your strpos conditions I would use === 0 as opposed to !=== FALSE because the former also ensures that the pattern occures at the beginning of the string, not anywhere in it.
    – user13104
    Commented Jan 27, 2013 at 3:57
  • Fair enough, === 0 will work fine also. Commented Jan 27, 2013 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.