Here is an example how to build unified login page in CTools Automodal. Note that we need to handle form building by ourselves but we are using ctools_automodal_get_page() to render the final output.


/**
 * Implement hook_menu()
 */
function mymodule_menu() {
  $items = array();

  $items['user/m/signup'] = array(
    'title' => 'Signup',
    'page callback' => 'mymodule_unified_login_page',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_NORMAL_ITEM,
    'modal' => TRUE,
    'menu_name' => 'user-menu',
  );

  return $items;
}

/**
 * Menu callback for user/login creates a unified login/registration form.
 * Inspired by logintobbogan's logintoboggan_unified_login_page().
 * @see logintoboggan_unified_login_page()
 */
function mymodule_unified_login_page() {
  global $user;
  $ajax = FALSE;

  if (substr(request_path(), -5) == '/ajax') {
    $ajax = 'ajax';
  }

  // User is logged in already.
  if ($user->uid) {
    if ($ajax) {
      $commands[] = ctools_modal_command_dismiss();
      $commands[] = ctools_ajax_command_redirect('<front>');
      print ajax_render($commands);
      exit();
    }
    else {
      drupal_goto('<front>');
    }
  }

  // User is not logged in.
  if ($ajax) {
    ctools_include('modal');
    ctools_include('ajax');
    ctools_add_js('ajax-responder');

    $form_state_1 = $form_state_2 = array(
      'ajax' => $ajax,
      'build_info' => array('args' => array()),
      're_render' => FALSE,
      'no_redirect' => TRUE,
    );

    $login_form = drupal_build_form('user_login', $form_state_1);

    // Build the second form only when the first form isnt executed. Otherwise
    // we will be redirected, because both form builders contains drupal_goto()
    // for already logged-in users.
    if (empty($form_state_1['executed'])) {
      $register_form = drupal_build_form('user_register_form', $form_state_2);
    }

    // Handle submitted form.
    if (!empty($form_state_1['executed']) || !empty($form_state_2['executed'])) {
      $commands[] = ctools_modal_command_dismiss();
      $commands[] = ctools_ajax_command_reload();

      print ajax_render($commands);
      exit();
    }

    // If there are messages for the form, render them.
    if ($messages = theme('status_messages')) {
      $messages = '<div class="messages">' . $messages . '</div>';
    }

    $variables = array(
      'login_form' => drupal_render($login_form),
      'register_form' => drupal_render($register_form),
    );

    return $messages . theme('mymodule_unified_login_page', $variables);
  }
  else {
    $login_form = drupal_get_form('user_login');
    $register_form = drupal_get_form('user_register_form');
    $rendered_login_form = drupal_render($login_form);
    $rendered_register_form = drupal_render($register_form);
    $variables = array(
      'login_form' => $rendered_login_form,
      'register_form' => $rendered_register_form,
    );
    return theme('mymodule_unified_login_page', $variables);
  }
}

/**
 * Implemenation of hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'mymodule_unified_login_page' => array(
      'variables' => array(
        'login_form' => NULL,
        'register_form' => NULL,
      ),
    ),
  );
}

/**
 * Theme function for unified login page.
 * Inspired by logintoboggan theme_lt_unified_login_page()
 * @see theme_lt_unified_login_page()
 */
function theme_mymodule_unified_login_page($variables) {
  $output = '';

  $login_form = $variables['login_form'];
  $register_form = $variables['register_form'];

  $output .= '<div id="login-message">' . t('You are not logged in.') . '</div>';

  // Add the login and registration forms in.
  $output .= '<div id="register-form">' . $register_form . '</div>';
  $output .= '<div id="login-form">' . $login_form . '</div>';

  $output .= '</div>';

  return $output;
}

Comments

wojtha’s picture

Title: How to: How to handle two forms in one modal » How to: How to handle two forms in one modal (unified login page)

Better title

nikkubhai’s picture

Thank you so much for this code. Worked perfectly.

I was thinking what could be the best way to display the modal automatically on pageload without clicking on the link. Can you help me?

wojtha’s picture

Hi,

I will try to emulate the user click on the link.

(function ($) {

/**
 * Drupal behaviors
 */

Drupal.behaviors.login_autostart = {};

Drupal.behaviors.login_autostart.attach = function(context) {
    $('#id-of-the-ctools-signup-link', context).click();
}

})(jQuery);

To get more control when to display the form, it might be better to use http://drupal.org/project/splashify. I dont have experience with this one, but I was using its predecessor http://drupal.org/project/splash.

IA’s picture

Thanks a lot for the code. It is still actual.