? logintoboggan.patch
Index: logintoboggan.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/logintoboggan/logintoboggan.css,v
retrieving revision 1.2
diff -u -p -r1.2 logintoboggan.css
--- logintoboggan.css	22 Nov 2007 00:51:45 -0000	1.2
+++ logintoboggan.css	30 May 2008 00:38:19 -0000
@@ -1,3 +1,5 @@
+/* $Id$ */
+
 div.toboggan-container {
   text-align: center;
 }
@@ -20,4 +22,40 @@ div.user-login-block {
 
 div.user-login-block a {
   text-align: left;
+}
+
+.toboggan-unified #login-message {
+  text-align: center;
+  font-size: 2em;
+  line-height: 1.2;
+}
+
+.toboggan-unified #login-links {
+  text-align: center;
+  font-size: 1.5em;
+  line-height: 2.7;
+}
+
+.toboggan-unified #login-links a {
+  padding: .5em;
+  border: 1px #666 solid;
+  background-color: #EEE;
+}
+
+.toboggan-unified #login-links a:hover {
+  background-color: #DDD;
+}
+
+.toboggan-unified #login-links a.lt-active,
+.toboggan-unified #login-links a.lt-active:hover {
+  background-color: #FFF19A;
+  border: 2px #333 solid;
+}
+
+.toboggan-unified.login #register-form {
+  display: none;
+}
+
+.toboggan-unified.register #login-form {
+  display: none;
 }
\ No newline at end of file
Index: logintoboggan.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/logintoboggan/logintoboggan.module,v
retrieving revision 1.131
diff -u -p -r1.131 logintoboggan.module
--- logintoboggan.module	9 May 2008 00:34:22 -0000	1.131
+++ logintoboggan.module	30 May 2008 00:38:20 -0000
@@ -70,6 +70,8 @@ function logintoboggan_help($path, $arg)
       <li>Optionally redirect the user to a specific page when using the 'Immediate login' feature.</li>
       <li>Optionally redirect the user to a specific page upon validation of their e-mail address.</li>
       <li>Optionally display a user message indicating a successful login.</li>
+      <li>Optionally combine both the login and registration form on one page.</li>
+      <li>Optionally display an 'I forgot my password' link on the user login form.</li>
       </ol>
       These features may be turned on or off in the Login Toboggan <a href=\"!url\">settings</a>.</p>
       <p>Because this module completely reorients the Drupal login process you will probably want to edit the welcome e-mail on the user settings page. For instance if you have enabled the 'Set password & Immediate Login' option, you probably should not send the user's password out in the welcome e-mail (also note when the 'Set password & Immediate Login' option is enabled, the !login_url becomes a verification url that the user MUST visit in order to enable authenticated status). The following is an example welcome e-mail:</p>
@@ -162,6 +164,11 @@ function logintoboggan_form_alter(&$form
       break;
 
     case 'user_login':
+      if (variable_get('logintoboggan_forgot_pass_link', 0)  || variable_get('logintoboggan_unified_login', 0)) {
+        $form['lost_password'] = array(
+          '#value' => '<div class="login-forgot">' . l(t('I forgot my password'), 'user/password') . '</div>',
+        );
+      }
     case 'user_login_block':
       // Grab the message from settings for display at the top of the login block.
       if ($login_msg = variable_get('logintoboggan_login_block_message', '')) {
@@ -489,6 +496,79 @@ function logintoboggan_menu() {
 }
 
 /**
+ * Implementation of hook_menu_alter().
+ */
+function logintoboggan_menu_alter(&$callbacks) {
+  if (variable_get('logintoboggan_unified_login', 0)) {
+    // Kill the tabs on the login pages.
+    $callbacks['user/register']['type'] = MENU_CALLBACK;
+    $callbacks['user/register']['page callback'] = 'logintoboggan_unified_login_page';
+    $callbacks['user/register']['page arguments'] = array('register');
+    $callbacks['user/login']['page callback'] = 'logintoboggan_unified_login_page';
+    $callbacks['user/password']['type'] = MENU_CALLBACK;
+    $callbacks['user']['page callback'] = 'logintoboggan_unified_login_page';
+  }
+}
+
+/**
+ * Menu callback for user/login
+ *   creates a unified login/registration form (without tabs)
+ */
+function logintoboggan_unified_login_page($active_form = 'login') {
+  global $user;
+  if ($user->uid) {
+    menu_set_active_item('user/'. $user->uid);
+    return menu_execute_active_handler();
+  }
+  else {
+    $login_form = drupal_get_form('user_login');
+    $register_form = drupal_get_form('user_register');
+    // TODO: Somehow add a class of "default" to whichever form is the default.
+    // Then, in the JS, remove hard-coding of hiding the register form, and instead
+    // hide the one not marked 'default'
+    $output = theme('lt_unified_login_page', $login_form, $register_form, $active_form);
+
+    return $output;
+  }
+}
+
+/**
+ * Theme function for unified login page.
+ *
+ * @ingroup themable
+ */
+function theme_lt_unified_login_page($login_form, $register_form, $active_form) {
+  // Add some JS and CSS loveliness.
+  $path = drupal_get_path('module', 'logintoboggan');
+  drupal_add_css($path . '/logintoboggan.css');
+  drupal_add_js(array('lt' => array('activeForm' => $active_form)), 'setting');
+  drupal_add_js($path . '/unifiedlogin.js');
+  drupal_set_title('');
+  $output = '';
+
+  $output .= '<div class="toboggan-unified '.$active_form.'">';
+
+  // Create the initial message and links that people can click on.
+  $output .= '<div id="login-message">' . t('You are not logged in.') . '</div>';
+  $output .= '<div id="login-links">';
+  $output .= l(t('I have an account'), 'user/login', array('attributes' => array('class' => 'login-link', 'id' => 'login-link')));
+  $output .= ' ';
+  $output .= l(t('I want to create an account'), 'user/register', array('attributes' => array('class' => 'login-link', 'id' => 'register-link')));
+
+  $output .= '</div>';
+
+  // Add the login and registration forms in.
+  $output .= '<div id="login-form">';
+  $output .= $login_form;
+  $output .= '</div>';
+  $output .= '<div id="register-form">' . $register_form . '</div>';
+
+  $output .= '</div>';
+
+  return $output;
+}
+
+/**
  * Access check for user revalidation.
  */
 function logintoboggan_revalidate_access($uid) {
@@ -525,6 +605,9 @@ function logintoboggan_theme() {
     'lt_login_link' => array(
       'arguments' => array(),
     ),
+    'lt_unified_login_page' => array(
+      'arguments' => array('login_form' => NULL, 'register_form' => NULL),
+    ),
   );
 }
 
@@ -617,6 +700,22 @@ function logintoboggan_main_settings(&$f
     '#description' => t('Users will be able to enter EITHER their username OR their e-mail address to log in.'),
   );
 
+  $form['login']['logintoboggan_unified_login'] = array(
+    '#type' => 'radios',
+    '#title' => t('Present a unified login and registration page'),
+    '#default_value' => variable_get('logintoboggan_unified_login', 0),
+    '#options' => array($_disabled, $_enabled),
+    '#description' => t("Use one page for both login and register instead of Drupal's tabbed login/registration/password pages."),
+  );
+
+  $form['login']['logintoboggan_forgot_pass_link'] = array(
+    '#type' => 'radios',
+    '#title' => t('Show a "forgot password" link on the login form'),
+    '#default_value' => variable_get('logintoboggan_forgot_pass_link', 0),
+    '#options' => array($_disabled, $_enabled),
+    '#description' => t("Display a link on the user login form that allows a user to request their password. If the unified login option is enabled, this will automatically be enabled as well."),
+  );
+
   $form['registration'] = array(
     '#type' => 'fieldset',
     '#title' => t('Registration'),
Index: unifiedlogin.js
===================================================================
RCS file: unifiedlogin.js
diff -N unifiedlogin.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ unifiedlogin.js	30 May 2008 00:38:20 -0000
@@ -0,0 +1,43 @@
+/* $Id$ */
+
+if (Drupal.jsEnabled) {
+  
+  // For compatibility with non-js browsers, we hide the #register-form here
+  // it is important that this CSS gets added early so the form doesn't
+  // appear while the page is loading (before $(document).ready() fires)
+  $('<style type="text/css">.toboggan-unified #register-form, .toboggan-unified #login-form {display:none;}</style>').appendTo('head');
+    
+  $(document).ready(function() {
+    var login_url = $('.toboggan-unified #login-link').attr('href');
+    var register_url = $('.toboggan-unified #register-link').attr('href');
+    
+    $('.toboggan-unified #login-link').attr('href', login_url + '#login-form'); //login-form
+    $('.toboggan-unified #register-link').attr('href', register_url + '#register-form'); //register-form
+    // Attach behaviors to the links so that they show/hide forms appropriately.
+    $('.toboggan-unified #register-link').click(function() {
+      $(this).addClass('lt-active').blur();
+      $('.toboggan-unified #login-link').removeClass('lt-active');
+      $('.toboggan-unified #register-form').show();
+      $('.toboggan-unified #login-form').hide();
+      return false;
+    });
+    $('.toboggan-unified #login-link').click(function() {
+      $(this).addClass('lt-active').blur();
+      $('.toboggan-unified #register-link').removeClass('lt-active');
+      $('.toboggan-unified #login-form').show();
+      $('.toboggan-unified #register-form').hide();
+      return false;
+    });
+    
+    switch(Drupal.settings.lt.activeForm) {
+      case 'register':
+        $('.toboggan-unified #register-link').click();
+        break;
+      case 'login':
+      default:
+        $('.toboggan-unified #login-link').click();
+        break;
+    }
+    
+  });
+}
\ No newline at end of file
