From ba0ff1a9b7805cde4521d07ca0f039506173bb6b Mon Sep 17 00:00:00 2001 From: Steven Wittens Date: Fri, 2 Mar 2007 09:40:27 +0000 Subject: #117018: Use Garland theme for installer/maintenance pages, and add task list in the sidebar. - Refactor partial-page handling for the maintenance page. It's an exotic quirk for update.php and belongs there. --- CHANGELOG.txt | 1 + includes/theme.inc | 124 ++++++++++++++++++++++++------------ install.php | 60 +++++++++++++++-- misc/maintenance.css | 40 ------------ misc/maintenance.tpl.php | 59 +++++++++++++++++ modules/system/system.css | 3 + themes/garland/images/task-list.png | Bin 0 -> 128 bytes themes/garland/style.css | 33 +++++++++- update.php | 52 ++++++++++++--- 9 files changed, 274 insertions(+), 98 deletions(-) create mode 100644 misc/maintenance.tpl.php create mode 100644 themes/garland/images/task-list.png diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9e880fe3d..6d6de4ee5 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,6 +6,7 @@ Drupal 6.0, xxxx-xx-xx (development version) - Made it easier to theme the forum overview page. - Drupal works with error reporting set to E_ALL. - Added scripts/drupal.sh to execute Drupal code from the command line. Useful to use Drupal as a framework to build command-line tools. +- Used the Garland theme for the installation and maintenance pages. Drupal 5.0, 2007-01-15 ---------------------- diff --git a/includes/theme.inc b/includes/theme.inc index 7d1972ac8..d4a412751 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -423,72 +423,116 @@ function theme_page($content) { return $output; } -function theme_maintenance_page($content, $messages = TRUE, $partial = FALSE) { +/** + * Generate a themed maintenance page. + * + * Note: this function is not themable. + * + * @param $content + * The page content to show. + * @param $messages + * Whether to output status and error messages. + */ +function theme_maintenance_page($content, $messages = TRUE) { + // Set required headers. drupal_set_header('Content-Type: text/html; charset=utf-8'); drupal_set_html_head(''); drupal_set_html_head(''); drupal_set_html_head(''); drupal_set_html_head(''); - $output = "\n"; - $output .= ''; - $output .= ''; - $output .= ' '. strip_tags(drupal_get_title()) .''; - $output .= drupal_get_html_head(); - $output .= drupal_get_js(); - $output .= ''; - $output .= ''; - $output .= '

' . drupal_get_title() . '

'; - - if ($messages) { - $output .= theme('status_messages'); - } + // Prepare variables. + $variables = array( + 'head_title' => strip_tags(drupal_get_title()), + 'head' => drupal_get_html_head(), + 'styles' => '', + 'scripts' => drupal_get_js(), + 'sidebar_left' => drupal_get_content('left'), + 'sidebar_right' => drupal_get_content('right'), + 'base_path' => base_path(), + 'path_to_theme' => base_path() .'themes/garland/minnelli', + 'logo' => base_path() .'themes/garland/minnelli/logo.png', + 'site_title' => t('Drupal'), + 'title' => drupal_get_title(), + 'messages' => theme('status_messages'), + 'content' => $content, + ); - $output .= "\n\n"; - $output .= $content; - $output .= "\n\n"; - - if (!$partial) { - $output .= ''; - } + // Render simplified PHPTemplate. + include_once './themes/engines/phptemplate/phptemplate.engine'; + $output = _phptemplate_render('misc/maintenance.tpl.php', $variables); return $output; } +/** + * Generate a themed installation page. + * + * Note: this function is not themable. + * + * @param $content + * The page content to show. + */ function theme_install_page($content) { drupal_set_header('Content-Type: text/html; charset=utf-8'); drupal_add_css('misc/maintenance.css', 'module', 'all', FALSE); drupal_set_html_head(''); - $output = "\n"; - $output .= ''; - $output .= ''; - $output .= ' '. strip_tags(drupal_get_title()) .''; - $output .= drupal_get_html_head(); - $output .= drupal_get_css(); - $output .= drupal_get_js(); - $output .= ''; - $output .= ''; - $output .= '

' . drupal_get_title() . '

'; + $variables = array( + 'head_title' => strip_tags(drupal_get_title()), + 'head' => drupal_get_html_head(), + 'styles' => drupal_get_css(), + 'scripts' => drupal_get_js(), + 'sidebar_left' => drupal_get_content('left'), + 'sidebar_right' => drupal_get_content('right'), + 'base_path' => base_path(), + 'path_to_theme' => base_path() .'themes/garland/minnelli', + 'logo' => base_path() .'themes/garland/minnelli/logo.png', + 'site_title' => st('Drupal Installation'), + 'title' => drupal_get_title(), + 'messages' => '', + 'content' => $content, + ); + + // Special handling of error messages $messages = drupal_set_message(); if (isset($messages['error'])) { $title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process'); - $output .= '

' .$title. ':

'; - $output .= theme('status_messages', 'error'); + $variables['messages'] .= '

'. $title .':

'; + $variables['messages'] .= theme('status_messages', 'error'); } + // Special handling of status messages if (isset($messages['status'])) { $warnings = count($messages['status']) > 1 ? st('The following installation warnings should be carefully reviewed, but in most cases may be safely ignored') : st('The following installation warning should be carefully reviewed, but in most cases may be safely ignored'); - $output .= '

' .$title. ':

'; - $output .= theme('status_messages', 'status'); + $variables['messages'] .= '

'. $title .':

'; + $variables['messages'] .= theme('status_messages', 'status'); } - $output .= "\n\n"; - $output .= $content; - $output .= "\n\n"; - - $output .= ''; + // Render simplified PHPTemplate. + include_once './themes/engines/phptemplate/phptemplate.engine'; + return _phptemplate_render('misc/maintenance.tpl.php', $variables); +} +/** + * Return a themed list of maintenance tasks to perform. + * + * Note: this function is not themable. + */ +function theme_task_list($items, $active = NULL) { + $done = isset($items[$active]) || $active == NULL; + $output = '
    '; + foreach ($items as $k => $item) { + if ($active == $k) { + $class = 'active'; + $done = false; + } + else { + $class = $done ? 'done' : ''; + } + $output .= '
  1. '. $item .'
  2. '; + } + $output .= '
'; return $output; } diff --git a/install.php b/install.php index bc2d4c335..a0a7c717b 100644 --- a/install.php +++ b/install.php @@ -151,6 +151,7 @@ function install_change_settings($profile = 'default', $install_locale = '') { // We always need this because we want to run form_get_errors. include_once './includes/form.inc'; drupal_maintenance_theme(); + install_task_list('database'); // The existing database settings are not working, so we need write access // to settings.php to change them. @@ -375,7 +376,14 @@ function install_settings_form_submit($form_id, $form_values) { } /** - * Find all .profile files and allow admin to select which to install. + * Find all .profile files. + */ +function install_find_profiles() { + return file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0); +} + +/** + * Allow admin to select which profile to install. * * @return * The selected profile. @@ -383,7 +391,7 @@ function install_settings_form_submit($form_id, $form_values) { function install_select_profile() { include_once './includes/form.inc'; - $profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0); + $profiles = install_find_profiles(); // Don't need to choose profile if only one available. if (sizeof($profiles) == 1) { $profile = array_pop($profiles); @@ -398,6 +406,7 @@ function install_select_profile() { } drupal_maintenance_theme(); + install_task_list('profile'); drupal_set_title(st('Select an installation profile')); print theme('install_page', drupal_get_form('install_select_profile_form', $profiles)); @@ -432,7 +441,16 @@ function install_select_profile_form($profiles) { } /** - * Find all .po files for the current profile and allow admin to select which to use. + * Find all .po files for the current profile. + */ +function install_find_locales($profilename) { + $locales = file_scan_directory('./profiles/'. $profilename, '\.po$', array('.', '..', 'CVS'), 0, FALSE); + array_unshift($locales, (object) array('name' => 'en')); + return $locales; +} + +/** + * Allow admin to select which locale to use for the current profile. * * @return * The selected language. @@ -441,9 +459,8 @@ function install_select_locale($profilename) { include_once './includes/file.inc'; include_once './includes/form.inc'; - // Collect possible locales, add default - $locales = file_scan_directory('./profiles/' . $profilename, '\.po$', array('.', '..', 'CVS'), 0, FALSE); - array_unshift($locales, (object) array('name' => 'en')); + // Find all available locales. + $locales = install_find_locales($profilename); // Don't need to choose locale if only one (English) is available. if (sizeof($locales) == 1) { @@ -456,6 +473,7 @@ function install_select_locale($profilename) { } drupal_maintenance_theme(); + install_task_list('locale'); drupal_set_title(st('Choose your preferred language')); print theme('install_page', drupal_get_form('install_select_locale_form', $locales)); @@ -492,6 +510,7 @@ function install_select_locale_form($locales) { */ function install_no_profile_error() { drupal_maintenance_theme(); + install_task_list('profile'); drupal_set_title(st('No profiles available')); print theme('install_page', '

'. st('We were unable to find any installer profiles. Installer profiles tell us what modules to enable and what schema to install in the database. A profile is necessary to continue with the installation process.') .'

'); exit; @@ -517,6 +536,7 @@ function install_missing_modules_error($profile) { global $base_url; drupal_maintenance_theme(); + install_task_list('install'); drupal_set_title(st('Modules missing')); print theme('install_page', '

'. st('One or more required modules are missing. Please check the error messages and try again.', array('!url' => "install.php?profile=$profile")) .'

'); exit; @@ -537,6 +557,7 @@ function install_complete($profile) { // Build final page. drupal_maintenance_theme(); + install_task_list(); drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_name()))); $output .= '

'. st('Congratulations, @drupal has been successfully installed.', array('@drupal' => drupal_install_profile_name())) .'

'; @@ -570,6 +591,7 @@ function install_check_requirements($profile) { // If there are issues, report them. if ($severity == REQUIREMENT_ERROR) { drupal_maintenance_theme(); + install_task_list('requirements'); foreach ($requirements as $requirement) { if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) { @@ -583,4 +605,30 @@ function install_check_requirements($profile) { } } +/** + * Add the installation task list to the current page. + */ +function install_task_list($active = NULL) { + // Default list of tasks. + $tasks = array( + 'profile' => st('Choose profile'), + 'locale' => st('Choose language'), + 'requirements' => st('Verify requirements'), + 'database' => st('Database setup'), + 'install' => st('Installation'), + ); + + // Remove profiles if only one profile exists. + if (count(install_find_profiles()) == 1) { + unset($tasks['profile']); + } + + // Remove locale if no install profiles use them. + if (count(install_find_locales('.')) == 1) { + unset($tasks['locale']); + } + + drupal_set_content('left', theme_task_list($tasks, $active)); +} + install_main(); diff --git a/misc/maintenance.css b/misc/maintenance.css index 032d56c37..a18f10c1a 100644 --- a/misc/maintenance.css +++ b/misc/maintenance.css @@ -1,45 +1,5 @@ /* $Id$ */ -body { - background: url(druplicon.png) 4.2em 4em no-repeat #fff; - color: #000; - border: 1px solid #bbb; - margin: 3em; - padding: 1em 1em 1em 128px; - line-height: 1.2; -} -h1 { - margin: 1.6em 0 1.1em 0; -} -h1, h2, h3, h4, h5, h6 { - font-family: sans-serif; -} -:link { - color: #0073ba; - font-weight: bold; -} -:visited { - color: #004975; - font-weight: bold; -} - -div.messages { - border: 1px solid #ddd; - padding: 0.4em; - margin-top: 1em; -} - -div.messages li { - margin-top: 0.5em; - margin-bottom: 0.5em; -} - -div.error { - background: #fdd; - border: 1px solid #daa; - color: #400; -} - /* Update styles */ #update-results { margin-top: 3em; diff --git a/misc/maintenance.tpl.php b/misc/maintenance.tpl.php new file mode 100644 index 000000000..8e580a5e2 --- /dev/null +++ b/misc/maintenance.tpl.php @@ -0,0 +1,59 @@ + + + + <?php print $head_title ?> + + + + + + + + + +
+ +
+
+ + + + + + + +
+ '. $title .''; endif; ?> + + + + + + + +
+ + + + + +
+
+ + + + diff --git a/modules/system/system.css b/modules/system/system.css index f69583db7..c78d52127 100644 --- a/modules/system/system.css +++ b/modules/system/system.css @@ -66,6 +66,9 @@ div.ok, tr.ok { padding: 0; list-style: disc; } +ol.task-list li.active { + font-weight: bold; +} .form-item { margin-top: 1em; margin-bottom: 1em; diff --git a/themes/garland/images/task-list.png b/themes/garland/images/task-list.png new file mode 100644 index 000000000..3f9b74f2b Binary files /dev/null and b/themes/garland/images/task-list.png differ diff --git a/themes/garland/style.css b/themes/garland/style.css index e4e73e059..717e1ffff 100644 --- a/themes/garland/style.css +++ b/themes/garland/style.css @@ -96,7 +96,12 @@ ul { padding: 0; } -ul li { +ol { + margin: 0.75em 0 1.25em; + padding: 0; +} + +ol li, ul li { margin: 0.4em 0 0.4em .5em; } @@ -109,7 +114,7 @@ ul.menu ul, .item-list ul ul { margin-left: 0em; } -ul li, ul.menu li, .item-list ul li, li.leaf { +ol li, ul li, ul.menu li, .item-list ul li, li.leaf { margin: 0.15em 0 0.15em .5em; } @@ -120,6 +125,11 @@ ul li, ul.menu li, .item-list ul li, li.leaf { background: transparent url(images/menu-leaf.gif) no-repeat 1px .35em; } +ol li { + padding: 0 0 .3em; + margin-left: 2em; +} + ul li.expanded { background: transparent url(images/menu-expanded.gif) no-repeat 1px .35em; } @@ -138,6 +148,25 @@ ul.inline li { padding: 0 1em 0 0; } +ol.task-list { + margin-left: 0; + list-style-type: none; + list-style-image: none; +} +ol.task-list li { + padding: 0.5em 1em 0.5em 2em; +} +ol.task-list li.active { + background: transparent url(images/task-list.png) no-repeat 3px 50%; +} +ol.task-list li.done { + color: #393; + background: transparent url(../../misc/watchdog-ok.png) no-repeat 0px 50%; +} +ol.task-list li.active { + margin-right: 1em; +} + fieldset ul.clear-block li { margin: 0; padding: 0; diff --git a/update.php b/update.php index fb07f0458..d26c96f14 100644 --- a/update.php +++ b/update.php @@ -325,6 +325,8 @@ function update_selection_page() { drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE); $output .= drupal_get_form('update_script_selection_form'); + update_task_list('select'); + return $output; } @@ -475,28 +477,41 @@ function update_do_update_page() { */ function update_progress_page_nojs() { drupal_set_title('Updating'); + update_task_list('run'); $new_op = 'do_update_nojs'; - if ($_SERVER['REQUEST_METHOD'] == 'GET') { - // Error handling: if PHP dies, it will output whatever is in the output - // buffer, followed by the error message. + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + // This is the first page so return some output immediately. + $percentage = 0; + $message = 'Starting updates'; + } + else { + // This is one of the later requests: do some updates first. + + // Error handling: if PHP dies due to a fatal error (e.g. non-existant + // function), it will output whatever is in the output buffer, + // followed by the error message. So, we put an explanation in the + // buffer to guide the user when an error happens. ob_start(); $fallback = '

An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference. Please continue to the update summary.

'; - print theme('maintenance_page', $fallback, FALSE, TRUE); + $fallback = theme('maintenance_page', $fallback, FALSE); + + // We strip the end of the page using a marker in the template, so any + // additional HTML output by PHP shows up inside the page rather than + // below it. While this causes invalid HTML, the same would be true if + // we didn't, as content is not allowed to appear after anyway. + list($fallback) = explode('', $fallback); + print $fallback; + // Do updates list($percentage, $message) = update_do_updates(); if ($percentage == 100) { $new_op = 'finished'; } - // Updates successful; remove fallback + // Updates were successful; wipe the output buffer as it's unneeded. ob_end_clean(); } - else { - // This is the first page so return some output immediately. - $percentage = 0; - $message = 'Starting updates'; - } drupal_set_html_head(''); $output = theme('progress_bar', $percentage, $message); @@ -513,6 +528,7 @@ function update_finished_page($success) { $links[] = 'main page'; $links[] = 'administration pages'; + update_task_list(); // Report end result if ($success) { $output = '

Updates were attempted. If you see no failures below, you may proceed happily to the administration pages. Otherwise, you may need to update your database manually. All errors have been logged.

'; @@ -559,6 +575,7 @@ function update_finished_page($success) { } function update_info_page() { + update_task_list('info'); drupal_set_title('Drupal database update'); $output = "
    \n"; $output .= "
  1. Use this script to upgrade an existing Drupal installation. You don't need this script when installing Drupal from scratch.
  2. "; @@ -759,6 +776,21 @@ function update_create_cache_tables() { return $ret; } +/** + * Add the update task list to the current page. + */ +function update_task_list($active = NULL) { + // Default list of tasks. + $tasks = array( + 'info' => 'Overview', + 'select' => 'Select updates', + 'run' => 'Run updates', + 'finished' => 'Review log', + ); + + drupal_set_content('left', theme_task_list($tasks, $active)); +} + // Some unavoidable errors happen because the database is not yet up-to-date. // Our custom error handler is not yet installed, so we just suppress them. ini_set('display_errors', FALSE); -- cgit v1.2.3