Index: install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.53 diff -u -p -r1.53 install.php --- install.php 22 May 2007 07:42:36 -0000 1.53 +++ install.php 24 May 2007 01:09:32 -0000 @@ -811,7 +811,7 @@ function install_task_list($active = NUL if (in_array($active, array('finished', 'done'))) { $active = NULL; } - drupal_set_content('left', theme_task_list($tasks, $active)); + drupal_set_content('left', theme('task_list', $tasks, $active)); } function install_configure_form() { Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.222 diff -u -p -r1.222 update.php --- update.php 16 May 2007 07:56:19 -0000 1.222 +++ update.php 24 May 2007 01:09:32 -0000 @@ -718,7 +718,7 @@ function update_task_list($active = NULL 'finished' => 'Review log', ); - drupal_set_content('left', theme_task_list($tasks, $active)); + drupal_set_content('left', theme('task_list', $tasks, $active)); } // Some unavoidable errors happen because the database is not yet up-to-date. @@ -726,10 +726,10 @@ function update_task_list($active = NULL ini_set('display_errors', FALSE); include_once './includes/bootstrap.inc'; +drupal_maintenance_theme(); update_fix_system_table(); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); -drupal_maintenance_theme(); // This must happen *after* drupal_bootstrap(), since it calls // variable_(get|set), which only works after a full bootstrap. Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.165 diff -u -p -r1.165 bootstrap.inc --- includes/bootstrap.inc 8 May 2007 16:36:55 -0000 1.165 +++ includes/bootstrap.inc 24 May 2007 01:09:33 -0000 @@ -961,28 +961,12 @@ function _drupal_cache_init($phase) { * unavailable and theme_maintenance_page() must be used in its place. */ function drupal_maintenance_theme() { - global $theme; - require_once './includes/path.inc'; - require_once './includes/theme.inc'; - require_once './includes/common.inc'; - require_once './includes/unicode.inc'; - require_once './modules/filter/filter.module'; - unicode_check(); - drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module'); - drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module'); - $theme = ''; - - // Special case registry of theme functions used by the installer - $themes = drupal_common_themes(); - foreach ($themes as $hook => $info) { - if (!isset($info['file']) && !isset($info['function'])) { - $themes[$hook]['function'] = 'theme_'. $hook; - $themes[$hook]['theme path'] = 'misc'; - } - } - _theme_set_registry($themes); + require_once './includes/maintenance.inc'; + require_once './includes/theme.admin.inc'; + _drupal_maintenance_theme(); } + /** * Return the name of the localisation function. Use in code that needs to * run both during installation and normal operation. Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.641 diff -u -p -r1.641 common.inc --- includes/common.inc 15 May 2007 20:19:47 -0000 1.641 +++ includes/common.inc 24 May 2007 01:09:34 -0000 @@ -2325,7 +2325,7 @@ function element_children($element) { /** * Provide theme registration for themes across .inc files. */ -function drupal_common_themes() { +function drupal_common_theme() { return array( // theme.inc 'placeholder' => array( @@ -2335,12 +2335,6 @@ function drupal_common_themes() { 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), 'file' => 'page', ), - 'maintenance_page' => array( - 'arguments' => array('content' => NULL, 'show_messages' => TRUE), - ), - 'install_page' => array( - 'arguments' => array('content' => NULL), - ), 'task_list' => array( 'arguments' => array('items' => NULL, 'active' => NULL), ), Index: includes/maintenance.inc =================================================================== RCS file: includes/maintenance.inc diff -N includes/maintenance.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/maintenance.inc 24 May 2007 01:09:34 -0000 @@ -0,0 +1,188 @@ +info['stylesheet'])) { + $theme->stylesheet = $theme->info['stylesheet']; + } + if (isset($theme->info['engine'])) { + $theme->engine = $theme->info['engine']; + } + if (isset($theme->info['base theme'])) { + $theme->base_theme = $theme->info['base theme']; + } + + _init_theme($theme, array(), 'drupal_maintenance_registry'); + + drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module'); + global $theme; + $theme = ''; +} + +/** + * Special function to create the theme registry. Since there isn't a database + * we have to build it from components we know will be loaded. + */ +function drupal_maintenance_registry($theme) { + // The maintenance theme MUST be a 'base' theme. + + // Special case building of the registry when we have no modules + // and no database. + $registry = array(); + _theme_process_registry($registry, 'drupal_common', 'module', 'system', 'includes'); + _theme_process_registry($registry, 'drupal_maintenance_common', 'module', 'system', 'modules/system'); + + if ($theme->engine) { + _theme_process_registry($registry, $theme->engine, 'theme_engine', $theme->name, dirname($theme->filename)); + } + _theme_process_registry($registry, $theme->name, 'theme', $theme->name, dirname($theme->filename)); + + return $registry; +} + +/** + * Specific implementation of hook_theme. Specifies maintenance-only theme + * implementations. + */ +function drupal_maintenance_common_theme() { + return array( + 'maintenance_page' => array( + 'arguments' => array('content' => NULL, 'show_messages' => TRUE), + 'path' => 'includes', + 'file' => 'maintenance_page', + ), + 'install_page' => array( + 'arguments' => array('content' => NULL), + 'path' => 'includes', + 'file' => 'maintenance_page', + ), + ); +} + +/** + * Generate a themed maintenance page. + * + * Note: Listed params are for theme('maintenance_page') + * + * @param $content + * The page content to show. + * @param $show_messages + * Whether to output status and error messages. + * FALSE can be useful to postpone the messages to a subsequent page. + */ +function template_preprocess_maintenance_page(&$variables) { + // 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(''); + + // 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' => !empty($variables['show_messages']) ? theme('status_messages') : '', + ); +} + +/** + * Preprocess the install page. + * + * Note: Listed params are for theme('install_page') + * + * @param $content + * The page content to show. + */ +function template_preprocess_install_page(&$variables) { + drupal_set_header('Content-Type: text/html; charset=utf-8'); + drupal_add_css('misc/maintenance.css', 'module', 'all', FALSE); + drupal_set_html_head(''); + + $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' => '', + ); + + // 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'); + $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'); + $variables['messages'] .= '

'. $title .':

'; + $variables['messages'] .= theme('status_messages', 'status'); + } +} + +/** + * Return a themed list of maintenance tasks to perform. + */ +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; +} + Index: includes/maintenance_page.tpl.php =================================================================== RCS file: includes/maintenance_page.tpl.php diff -N includes/maintenance_page.tpl.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/maintenance_page.tpl.php 24 May 2007 01:09:34 -0000 @@ -0,0 +1,59 @@ + + + + <?php print $head_title ?> + + + + + + + + + +
+ +
+
+ + + + + + + +
+ '. $title .''; endif; ?> + + + + + + + +
+ + + + + +
+
+ + + + Index: includes/theme.admin.inc =================================================================== RCS file: includes/theme.admin.inc diff -N includes/theme.admin.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/theme.admin.inc 24 May 2007 01:09:34 -0000 @@ -0,0 +1,246 @@ + array( + 'left' => 'Left sidebar', + 'right' => 'Right sidebar', + 'content' => 'Content', + 'header' => 'Header', + 'footer' => 'Footer', + ), + 'description' => '', + 'features' => array( + 'comment_user_picture', + 'favicon', + 'mission', + 'logo', + 'name', + 'node_user_picture', + 'search', + 'slogan' + ), + 'stylesheet' => 'style.css', + 'screenshot' => 'screenshot.png', + ); +} + +/** + * Recursive function to find the top level base theme. Themes can inherit + * templates and function implementations from earlier themes; this function + * finds the top level parent that has no ancestor, or returns NULL if there + * isn't a valid parent. + */ +function drupal_find_base_theme($themes, $key, $used_keys = array()) { + $base_key = $themes[$key]->info['base theme']; + // Does the base theme exist? + if (!isset($themes[$base_key])) { + return NULL; + } + + // Is the base theme itself a child of another theme? + if (isset($themes[$base_key]->info['base theme'])) { + // Prevent loops. + if ($used_keys[$base_key]) { + return NULL; + } + $used_keys[$base_key] = TRUE; + return drupal_find_base_theme($themes, $base_key, $used_keys); + } + // If we get here, then this is our parent theme. + return $base_key; +} + +/** + * Read Drupal's theme info from the themes directories. No database required. + * Since this returns two pieces of data, call this function like this: + * list($themes, $engines) = drupal_theme_data(); + * + * @return array($themes, $engines) + * An array containing first the themes info and second the theme engine info. + */ +function drupal_theme_data() { + // Find themes + $themes = drupal_system_listing('\.info$', 'themes'); + + // Find theme engines + $engines = drupal_system_listing('\.engine$', 'themes/engines'); + + $defaults = drupal_theme_default(); + + $sub_themes = array(); + // Read info files for each theme + foreach ($themes as $key => $theme) { + $themes[$key]->info = drupal_parse_info_file($theme->filename) + $defaults; + if (!empty($themes[$key]->info['base theme'])) { + $sub_themes[] = $key; + } + if (empty($themes[$key]->info['engine'])) { + $filename = dirname($themes[$key]->filename) .'/'. $themes[$key]->name .'.theme'; + if (file_exists($filename)) { + $themes[$key]->owner = $filename; + $themes[$key]->prefix = $key; + } + } + else { + $engine = $themes[$key]->info['engine']; + if (isset($engines[$engine])) { + $themes[$key]->owner = $engines[$engine]->filename; + $themes[$key]->prefix = $engines[$engine]->name; + $themes[$key]->template = TRUE; + } + } + + // Give the stylesheet proper path information. + if (!empty($themes[$key]->info['stylesheet'])) { + $themes[$key]->info['stylesheet'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['stylesheet']; + } + // Give the screenshot proper path information. + if (!empty($themes[$key]->info['screenshot'])) { + $themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot']; + } + } + + // Now that we've established all our master themes, go back and fill in + // data for subthemes. + foreach ($sub_themes as $key) { + $base_key = drupal_find_base_theme($themes, $key); + if (!$base_key) { + continue; + } + // Copy the 'owner' and 'engine' over if the top level theme uses a + // theme engine. + if (isset($themes[$base_key]->owner)) { + if (isset($themes[$base_key]->info['engine'])) { + $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; + $themes[$key]->owner = $themes[$base_key]->owner; + $themes[$key]->prefix = $themes[$base_key]->prefix; + } + else { + $themes[$key]->prefix = $key; + } + } + } + + return array($themes, $engines); +} + + +/** + * Process a single invocation of the theme hook. $type will be one + * of 'module', 'theme_engine' or 'theme' and it tells us some + * important information. + * + * Because $cache is a reference, the cache will be continually + * expanded upon; new entries will replace old entries in the + * array_merge, but we are careful to ensure some data is carried + * forward, such as the arguments a theme hook needs. + */ +function _theme_process_registry(&$cache, $name, $type, $theme, $path) { + $function = $name .'_theme'; + if (function_exists($function)) { + $result = $function($cache, $type, $theme, $path); + + foreach ($result as $hook => $info) { + $result[$hook]['type'] = $type; + $result[$hook]['theme path'] = $path; + // if function and file are left out, default to standard naming + // conventions. + if (!isset($info['file']) && !isset($info['function'])) { + $result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name .'_') . $hook; + } + // If a path is set in the info, use what was set. Otherwise use the + // default path. This is mostly so system.module can declare theme + // functions on behalf of core .include files. + if (isset($info['file']) && !isset($info['path'])) { + $result[$hook]['file'] = $path .'/'. $info['file']; + } + // If 'arguments' have been defined previously, carry them forward. + // This should happen if a theme overrides a Drupal defined theme + // function, for example. + if (!isset($info['arguments']) && isset($cache[$hook])) { + $result[$hook]['arguments'] = $cache[$hook]['arguments']; + } + // Check for default _preprocess_ functions. Ensure arrayness. + if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) { + $info['preprocess functions'] = array(); + $prefix = ($type == 'module' ? 'template' : $name); + // theme engines get an extra set that come before the normally named preprocess. + if ($type == 'theme_engine') { + if (function_exists($prefix .'_engine_preprocess')) { + $info['preprocess functions'][] = $prefix .'_engine_preprocess'; + } + if (function_exists($prefix .'_engine_preprocess_'. $hook)) { + $info['preprocess functions'][] = $prefix .'_engine_preprocess_'. $hook; + } + } + + // It would be too much of a performance hit to let every module have + // a generic preprocess function; themes and theme engines can do that. + if ($type != 'module' && function_exists($prefix .'_preprocess')) { + $info['preprocess functions'][] = $prefix .'_preprocess'; + } + if (function_exists($prefix .'_preprocess_'. $hook)) { + $info['preprocess functions'][] = $prefix .'_preprocess_'. $hook; + } + } + if (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions']) && empty($cache[$hook]['override preprocess functions'])) { + $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']); + } + $result[$hook]['preprocess functions'] = $info['preprocess functions']; + } + + // Merge the newly created theme hooks into the existing cache. + $cache = array_merge($cache, $result); + } +} + +/** + * Rebuild the hook theme_registry cache. + * + * @param $theme + * The loaded $theme object. + * @param $base_theme + * An array of loaded $theme objects representing the ancestor themes in + * oldest first order. + * @param theme_engine + * The name of the theme engine. + */ +function _theme_build_registry($theme, $base_theme, $theme_engine) { + $cache = array(); + // First, process the theme hooks advertised by modules. This will + // serve as the basic registry. + foreach (module_implements('theme') as $module) { + _theme_process_registry($cache, $module, 'module', $module, drupal_get_path('module', $module)); + } + + // Process each base theme. + foreach ($base_theme as $base) { + // If the theme uses a theme engine, process its hooks. + $base_path = dirname($base->filename); + if ($theme_engine) { + _theme_process_registry($cache, $theme_engine, 'base_theme_engine', $base->name, $base_path); + } + _theme_process_registry($cache, $base->name, 'base_theme', $base->name, $base_path); + } + + // And then the same thing, but for the theme. + if ($theme_engine) { + _theme_process_registry($cache, $theme_engine, 'theme_engine', $theme->name, dirname($theme->filename)); + } + + // Finally, hooks provided by the theme itself. + _theme_process_registry($cache, $theme->name, 'theme', $theme->name, dirname($theme->filename)); + + return $cache; +} Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.356 diff -u -p -r1.356 theme.inc --- includes/theme.inc 22 May 2007 19:56:00 -0000 1.356 +++ includes/theme.inc 24 May 2007 01:09:35 -0000 @@ -92,9 +92,12 @@ function init_theme() { * the same information as the $theme object. It should be in * 'oldest first' order, meaning the top level of the chain will * be first. + * @param $database_available + * Set to false if there is no database available; if no database is + * available, the theme registry will not be loaded from cache. */ -function _init_theme($theme, $base_theme = array()) { - global $theme_info, $base_theme_info, $theme_engine, $theme_path; +function _init_theme($theme, $base_theme = array(), $registry_callback = NULL) { + global $theme_info, $base_theme_info, $theme_engine, $theme_path, $theme_no_database; $theme_info = $theme; $base_theme_info = $base_theme; @@ -116,7 +119,6 @@ function _init_theme($theme, $base_theme } $theme_engine = NULL; - // Initialize the theme. if (isset($theme->engine)) { // Include the engine. @@ -143,7 +145,15 @@ function _init_theme($theme, $base_theme include_once './'. $theme->owner; } } - _theme_load_registry($theme, $base_theme, $theme_engine); + + if (isset($registry_callback) && function_exists($registry_callback)) { + $theme_no_database = TRUE; + _theme_set_registry($registry_callback($theme)); + } + else { + $theme_no_database = FALSE; + _theme_load_registry($theme, $base_theme, $theme_engine); + } } /** @@ -189,6 +199,7 @@ function _theme_load_registry($theme, $b } else { // If not, build one and cache it. + require_once './includes/theme.admin.inc'; $registry = _theme_build_registry($theme, $base_theme, $theme_engine); _theme_save_registry($theme, $registry); } @@ -212,115 +223,6 @@ function drupal_rebuild_theme_registry() } /** - * Process a single invocation of the theme hook. $type will be one - * of 'module', 'theme_engine' or 'theme' and it tells us some - * important information. - * - * Because $cache is a reference, the cache will be continually - * expanded upon; new entries will replace old entries in the - * array_merge, but we are careful to ensure some data is carried - * forward, such as the arguments a theme hook needs. - */ -function _theme_process_registry(&$cache, $name, $type, $theme, $path) { - $function = $name .'_theme'; - if (function_exists($function)) { - $result = $function($cache, $type, $theme, $path); - - foreach ($result as $hook => $info) { - $result[$hook]['type'] = $type; - $result[$hook]['theme path'] = $path; - // if function and file are left out, default to standard naming - // conventions. - if (!isset($info['file']) && !isset($info['function'])) { - $result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name .'_') . $hook; - } - // If a path is set in the info, use what was set. Otherwise use the - // default path. This is mostly so system.module can declare theme - // functions on behalf of core .include files. - if (isset($info['file']) && !isset($info['path'])) { - $result[$hook]['file'] = $path .'/'. $info['file']; - } - // If 'arguments' have been defined previously, carry them forward. - // This should happen if a theme overrides a Drupal defined theme - // function, for example. - if (!isset($info['arguments']) && isset($cache[$hook])) { - $result[$hook]['arguments'] = $cache[$hook]['arguments']; - } - // Check for default _preprocess_ functions. Ensure arrayness. - if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) { - $info['preprocess functions'] = array(); - $prefix = ($type == 'module' ? 'template' : $name); - // theme engines get an extra set that come before the normally named preprocess. - if ($type == 'theme_engine') { - if (function_exists($prefix .'_engine_preprocess')) { - $info['preprocess functions'][] = $prefix .'_engine_preprocess'; - } - if (function_exists($prefix .'_engine_preprocess_'. $hook)) { - $info['preprocess functions'][] = $prefix .'_engine_preprocess_'. $hook; - } - } - - // It would be too much of a performance hit to let every module have - // a generic preprocess function; themes and theme engines can do that. - if ($type != 'module' && function_exists($prefix .'_preprocess')) { - $info['preprocess functions'][] = $prefix .'_preprocess'; - } - if (function_exists($prefix .'_preprocess_'. $hook)) { - $info['preprocess functions'][] = $prefix .'_preprocess_'. $hook; - } - } - if (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions']) && empty($cache[$hook]['override preprocess functions'])) { - $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']); - } - $result[$hook]['preprocess functions'] = $info['preprocess functions']; - } - - // Merge the newly created theme hooks into the existing cache. - $cache = array_merge($cache, $result); - } -} - -/** - * Rebuild the hook theme_registry cache. - * - * @param $theme - * The loaded $theme object. - * @param $base_theme - * An array of loaded $theme objects representing the ancestor themes in - * oldest first order. - * @param theme_engine - * The name of the theme engine. - */ -function _theme_build_registry($theme, $base_theme, $theme_engine) { - $cache = array(); - // First, process the theme hooks advertised by modules. This will - // serve as the basic registry. - foreach (module_implements('theme') as $module) { - _theme_process_registry($cache, $module, 'module', $module, drupal_get_path('module', $module)); - } - - // Process each base theme. - foreach ($base_theme as $base) { - // If the theme uses a theme engine, process its hooks. - $base_path = dirname($base->filename); - if ($theme_engine) { - _theme_process_registry($cache, $theme_engine, 'base_theme_engine', $base->name, $base_path); - } - _theme_process_registry($cache, $base->name, 'base_theme', $base->name, $base_path); - } - - // And then the same thing, but for the theme. - if ($theme_engine) { - _theme_process_registry($cache, $theme_engine, 'theme_engine', $theme->name, dirname($theme->filename)); - } - - // Finally, hooks provided by the theme itself. - _theme_process_registry($cache, $theme->name, 'theme', $theme->name, dirname($theme->filename)); - - return $cache; -} - -/** * Provides a list of currently available themes. * * @param $refresh @@ -488,7 +390,7 @@ function theme() { } // default render function and extension. - $render_function = 'theme_render_template'; + $render_function = 'drupal_render_template'; $extension = '.tpl.php'; // Run through the theme engine variables, if necessary @@ -705,7 +607,7 @@ function theme_get_setting($setting_name * @return * The output generated by the template. */ -function theme_render_template($file, $variables) { +function drupal_render_template($file, $variables) { extract($variables, EXTR_SKIP); // Extract the variables to a local namespace ob_start(); // Start output buffering include "./$file"; // Include the file @@ -786,116 +688,6 @@ function theme_placeholder($text) { } /** - * Generate a themed maintenance page. - * - * Note: this function is not themable. - * - * @param $content - * The page content to show. - * @param $show_messages - * Whether to output status and error messages. - * FALSE can be useful to postpone the messages to a subsequent page. - */ -function theme_maintenance_page($content, $show_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(''); - - // 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' => $show_messages ? theme('status_messages') : '', - 'content' => $content, - ); - - $output = theme_render_template('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(''); - - $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'); - $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'); - $variables['messages'] .= '

'. $title .':

'; - $variables['messages'] .= theme('status_messages', 'status'); - } - - return theme_render_template('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; -} - -/** * Return a themed set of status and/or error messages. The messages are grouped * by type. * @@ -1614,3 +1406,4 @@ function template_preprocess_block(&$var $variables['template_files'][] = 'block-' . $variables['block']->module; $variables['template_files'][] = 'block-' . $variables['block']->module .'-'. $variables['block']->delta; } + Index: misc/maintenance.tpl.php =================================================================== RCS file: misc/maintenance.tpl.php diff -N misc/maintenance.tpl.php --- misc/maintenance.tpl.php 5 Mar 2007 16:15:22 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,59 +0,0 @@ - - - - <?php print $head_title ?> - - - - - - - - - -
- -
-
- - - - - - - -
- '. $title .''; endif; ?> - - - - - - - -
- - - - - -
-
- - - - Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.481 diff -u -p -r1.481 system.module --- modules/system/system.module 23 May 2007 08:00:46 -0000 1.481 +++ modules/system/system.module 24 May 2007 01:09:37 -0000 @@ -49,7 +49,7 @@ function system_help($section) { } function system_theme() { - return array_merge(drupal_common_themes(), array( + return array_merge(drupal_common_theme(), array( 'system_theme_select_form' => array( 'arguments' => array('form' => NULL), ), @@ -999,42 +999,12 @@ function system_get_files_database(&$fil } } -function system_theme_default() { - // Prepare defaults for themes. - return array( - 'regions' => array( - 'left' => 'Left sidebar', - 'right' => 'Right sidebar', - 'content' => 'Content', - 'header' => 'Header', - 'footer' => 'Footer', - ), - 'description' => '', - 'features' => array( - 'comment_user_picture', - 'favicon', - 'mission', - 'logo', - 'name', - 'node_user_picture', - 'search', - 'slogan' - ), - 'stylesheet' => 'style.css', - 'screenshot' => 'screenshot.png', - ); -} - /** * Collect data about all currently available themes */ function system_theme_data() { - // Find themes - $themes = drupal_system_listing('\.info$', 'themes'); - - // Find theme engines - $engines = drupal_system_listing('\.engine$', 'themes/engines'); - + require_once './includes/theme.admin.inc'; + list($themes, $engines) = drupal_theme_data(); // Remove all theme engines from the system table db_query("DELETE FROM {system} WHERE type = 'theme_engine'"); @@ -1045,62 +1015,6 @@ function system_theme_data() { db_query("INSERT INTO {system} (name, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', %d, %d, %d)", $engine->name, 'theme_engine', $engine->filename, 1, 0, 0); } - $defaults = system_theme_default(); - - $sub_themes = array(); - // Read info files for each theme - foreach ($themes as $key => $theme) { - $themes[$key]->info = drupal_parse_info_file($theme->filename) + $defaults; - if (!empty($themes[$key]->info['base theme'])) { - $sub_themes[] = $key; - } - if (empty($themes[$key]->info['engine'])) { - $filename = dirname($themes[$key]->filename) .'/'. $themes[$key]->name .'.theme'; - if (file_exists($filename)) { - $themes[$key]->owner = $filename; - $themes[$key]->prefix = $key; - } - } - else { - $engine = $themes[$key]->info['engine']; - if (isset($engines[$engine])) { - $themes[$key]->owner = $engines[$engine]->filename; - $themes[$key]->prefix = $engines[$engine]->name; - $themes[$key]->template = TRUE; - } - } - - // Give the stylesheet proper path information. - if (!empty($themes[$key]->info['stylesheet'])) { - $themes[$key]->info['stylesheet'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['stylesheet']; - } - // Give the screenshot proper path information. - if (!empty($themes[$key]->info['screenshot'])) { - $themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot']; - } - } - - // Now that we've established all our master themes, go back and fill in - // data for subthemes. - foreach ($sub_themes as $key) { - $base_key = system_find_base_theme($themes, $key); - if (!$base_key) { - continue; - } - // Copy the 'owner' and 'engine' over if the top level theme uses a - // theme engine. - if (isset($themes[$base_key]->owner)) { - if (isset($themes[$base_key]->info['engine'])) { - $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; - $themes[$key]->owner = $themes[$base_key]->owner; - $themes[$key]->prefix = $themes[$base_key]->prefix; - } - else { - $themes[$key]->prefix = $key; - } - } - } - // Extract current files from database. system_get_files_database($themes, 'theme'); @@ -1118,32 +1032,6 @@ function system_theme_data() { } /** - * Recursive function to find the top level base theme. Themes can inherit - * templates and function implementations from earlier themes; this function - * finds the top level parent that has no ancestor, or returns NULL if there - * isn't a valid parent. - */ -function system_find_base_theme($themes, $key, $used_keys = array()) { - $base_key = $themes[$key]->info['base theme']; - // Does the base theme exist? - if (!isset($themes[$base_key])) { - return NULL; - } - - // Is the base theme itself a child of another theme? - if (isset($themes[$base_key]->info['base theme'])) { - // Prevent loops. - if ($used_keys[$base_key]) { - return NULL; - } - $used_keys[$base_key] = TRUE; - return system_find_base_theme($themes, $base_key, $used_keys); - } - // If we get here, then this is our parent theme. - return $base_key; -} - -/** * Get a list of available regions from a specified theme. * * @param $theme_key Index: sites/default/default.settings.php =================================================================== RCS file: /cvs/drupal/drupal/sites/default/default.settings.php,v retrieving revision 1.1 diff -u -p -r1.1 default.settings.php --- sites/default/default.settings.php 8 May 2007 16:36:55 -0000 1.1 +++ sites/default/default.settings.php 24 May 2007 01:09:37 -0000 @@ -165,6 +165,17 @@ ini_set('url_rewriter.tags', ''); # ); /** + * Maintenance theme: + * + * The maintenance theme can only be set in settings.php, since it is used + * when a database is not guaranteed to be present. To change your maintenance + * theme, copy maintenance_page.tpl.php into your theme, and modify as it suits + * you. Remember, there is no database guaranteed, and not all of the Drupal API + * will be available, so be careful what you put in it. + */ +# $conf['maintenance_theme'] = 'garland'; + +/** * String overrides: * * To override specific strings on your site with or without enabling locale Index: themes/engines/phptemplate/phptemplate.engine =================================================================== RCS file: /cvs/drupal/drupal/themes/engines/phptemplate/phptemplate.engine,v retrieving revision 1.65 diff -u -p -r1.65 phptemplate.engine --- themes/engines/phptemplate/phptemplate.engine 6 May 2007 05:47:52 -0000 1.65 +++ themes/engines/phptemplate/phptemplate.engine 24 May 2007 01:09:37 -0000 @@ -73,5 +73,8 @@ function phptemplate_engine_preprocess(& // Tell all templates where they are located. $variables['directory'] = path_to_theme(); - $variables['is_front'] = drupal_is_front_page(); + global $theme_no_database; + if (!$theme_no_database) { + $variables['is_front'] = drupal_is_front_page(); + } }