How to theme the User Login page in Maintenance Mode

A recent client wanted to remove everything from the user login page when the site was in maintenance (or Site off-line as its referred to in most system messages and documentation). Just showing the user login form when the site is off-line actually makes a lot of sense because whats the point of showing things like primary links, search block or whatever else might show on your normal user login page.

You would think Drupal wouldn't show these things by default, or at the very least load the maintenance-page.tpl.php file for all pages while offline - but no, Drupal does not do this and you have to tell Drupal to not load the extra stuff.

What we were really trying to do is theme the offline user login page to look like Wordpress or CPanel login screens - just a simple login form. We wanted to keep the logo, site name and set a message to the user in case they landed there directly.

I have to admit this took me about 2 hours to figure out. There is no "$in_maintenance" variable to work with and template_preprocess_maintenance_page and maintenance-page.tpl.php are not used when we're on Drupal's user login page.

After a bit of digging about in theme.maintenance.inc I realized that Drupal defines a named constant called MAINTENANCE_MODE, fantastic, now I can man-handle Drupal to get the job done.

What Needs to Happen to get this to Work

  1. Set your theme as the maintenance theme in settings.php
  2. Add a maintenance-page.tpl.php to your theme and add a body class so we can theme it independently from the normal page-user.
  3. Add some tricky code to template_preprocess_page to tell Drupal to use the maintenance-page.tpl.php file when the user login page loads
  4. Probably want to reset the title and set a message

Set your theme as the maintenance theme in settings.php

Pretty easy, open up settings.php, find the conf array(), un-comment it and change the theme from minnelli to your theme (the following code snippet is truncated to include only the relevant bits we need to think about):

<?php
$conf
= array(
 
'maintenance_theme' => 'my_theme_name',
);
?>

If you don't do this Drupal 6 will keep on using minnelli when the site is set to offline, so you must figure this out first and get it done before moving on.

Add a maintenance-page.tpl.php to your theme

Two options here - there's a default maintenance-page.tpl.php in the Systems module you can copy into your theme, or more commonly you'd copy your own themes page.tpl.php file, rename the copy to "maintenance-page.tpl.php" and remove everything you don't want. Be careful here though, some themes page.tpl.php files can include stuff that won't work in maintenance mode.

Whatever route you take you must take out sidebars, other regions, the footer ect, everything you don't want. Here is the maintenance page from Adaptivetheme.

The only thing that's really different from a "normal" maintenance page is that we're controlling where $messages can show up and setting a class on the body element when we're looking at a user page - this is because the "in-maintenance" class is not added for the user pages by default. You could be much more aggressive about removing stuff than I am showing here - such as removing $scripts and even $styles and hard coding a link to a stylesheet so you're not loading a whole lot of useless CSS. I've been conservative since this is from our starter theme:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
<head>
  <title><?php print $head_title; ?></title>
  <?php print $head; ?>
  <?php print $styles; ?>
  <?php print $scripts; ?>
</head>
<body class="<?php print $body_classes; ?><?php if(arg(0) == 'user'): print ' in-maintenance'; endif;?>">
  <div id="container">
    <div id="header" class="clearfix">
      <?php if ($logo or $site_name or $site_slogan): ?>
        <div id="branding">
          <?php if ($logo or $site_name): ?>
            <div class="logo-site-name"><strong>
              <?php if (!empty($logo)): ?>
                <span id="logo">
                  <a href="<?php print $base_path; ?>" title="<?php print t('Home page'); ?>" rel="home">
                    <img src="<?php print $logo; ?>" alt="<?php print t('Home page'); ?>" />
                  </a>
                </span>
              <?php endif; ?>
              <?php if (!empty($site_name)): ?>
                <span id="site-name">
                  <a href="<?php print $base_path ?>" title="<?php print t('Home page'); ?>" rel="home">
                    <?php print $site_name; ?>
                  </a>
                </span>
              <?php endif; ?>
            </strong></div> <!-- /logo and site name -->
            <?php if ($site_slogan): ?>
              <div id="site-slogan"><?php print $site_slogan; ?></div>
            <?php endif; ?> <!-- /slogan -->
          <?php endif; ?>
        </div> <!-- /branding -->
      <?php endif; ?>
    </div> <!-- /header -->
    <div id="main-content">
      <?php if ($title): ?><h1 id="page-title"><?php print $title; ?></h1><?php endif; ?>
      <div id="content">
        <?php if(arg(0) == 'user'): print $messages; endif; ?>
        <?php print $content; ?>
      </div>
    </div> <!-- /main-content -->
  </div> <!-- /container -->
  <?php print $closure ?>
</body>
</html>

Add some tricky code to template_preprocess_page

Time for the magic to happen. Lets dive right into the code and walk through it to see whats happening.

If you don't know already you need a template.php file for your theme and to add a preprocess function to it, which is a tricky sort of variable-preprocessor thing that allows us to do cool stuff with variables before they get to the template.

Add this to your themes template.php file (replace my_theme with your themes name):

<?php
function my_theme_preprocess_page(&$vars) {
 
// First check if we're in the right mode, not logged in and looking at a /user* page
 
if(MAINTENANCE_MODE && !$vars['logged_in'] && arg(0) == 'user') {
   
// If the above conditions are true, force Drupal to use the maintenance-page template
   
$vars['template_files'][] = 'maintenance-page';
   
// The title is normally "User account", lets change it to "User Login"
   
$vars['title'] = drupal_set_title(t('User Login'));
   
// Set a message in case uses land here directly so they know whats going on
   
drupal_set_message(t('%sitename is currently in maintenance mode. Login using your normal user-name and password.', array('%sitename' => $vars['site_name'])), 'warning');
  }
}
?>

Finally clear the theme registry and caches etc so this all kicks in - put the site into maintenance mode, logout and go to the user login page and you should see something like the attached image.

Now recall that I mentioned something about an $in_maintenance variable and Drupal not setting one - well if you're smart you could set your own and use it instead of the defined constant - e.g.:

<?php
function mytheme_preprocess(&$vars, $hook) {
 
$vars['in_maintenance'] = MAINTENANCE_MODE;
}
?>

AttachmentSize
Image icon at-in-maintenance-user-page.png29.24 KB

Last updated 9th August, 2010 - 4:46pm

Authored by Jeff Burnz on