Index: modules/system/system.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v retrieving revision 1.197 diff -u -p -r1.197 system.admin.inc --- modules/system/system.admin.inc 26 Aug 2009 10:53:45 -0000 1.197 +++ modules/system/system.admin.inc 27 Aug 2009 08:16:26 -0000 @@ -194,21 +194,22 @@ function system_settings_overview() { /** * Menu callback; displays a listing of all themes. - * - * @ingroup forms - * @see system_themes_form_submit() */ -function system_themes_form() { +function system_themes_page() { $themes = system_get_theme_data(); uasort($themes, 'system_sort_modules_by_info_name'); - $status = array(); - $incompatible_core = array(); - $incompatible_php = array(); + $theme_default = variable_get('theme_default', 'garland'); + $theme_groups = array(); + + foreach ($themes as $key => $theme) { - foreach ($themes as $theme) { - $screenshot = NULL; + $admin_theme_options[$key] = $theme->name; + $theme->is_default = ($theme->name == $theme_default); + + // Identify theme screenshot. + $theme->screenshot = NULL; // Create a list which includes the current theme and all its base themes. if (isset($themes[$theme->name]->base_themes)) { $theme_keys = array_keys($themes[$theme->name]->base_themes); @@ -220,55 +221,55 @@ function system_themes_form() { // Look for a screenshot in the current theme or in its closest ancestor. foreach (array_reverse($theme_keys) as $theme_key) { if (isset($themes[$theme_key]) && file_exists($themes[$theme_key]->info['screenshot'])) { - $screenshot = $themes[$theme_key]->info['screenshot']; + $theme->screenshot = $themes[$theme_key]->info['screenshot']; break; } } - $screenshot = $screenshot ? theme('image', $screenshot, t('Screenshot for %theme theme', array('%theme' => $theme->info['name'])), '', array('class' => array('screenshot')), FALSE) : t('no screenshot'); - - $form[$theme->name]['screenshot'] = array('#markup' => $screenshot); - $form[$theme->name]['info'] = array( - '#type' => 'value', - '#value' => $theme->info, - ); - $options[$theme->name] = $theme->info['name']; - if (!empty($theme->status) || $theme->name == variable_get('admin_theme', 0)) { - $form[$theme->name]['operations'] = array('#markup' => l(t('configure'), 'admin/appearance/settings/' . $theme->name) ); + if (!empty($theme->status)) { + $theme->operations = array( + l(t('Configure'), 'admin/appearance/settings/' . $theme->name), + l(t('Disable'), 'admin/appearance/disable/' . $theme->name), + ); + if (!$theme->is_default) { + $theme->operations[] = l(t('Set default'), 'admin/appearance/default/' . $theme->name); + } } else { - // Dummy element for drupal_render. Cleaner than adding a check in the theme function. - $form[$theme->name]['operations'] = array(); + $theme->operations = array( + l(t('Enable'), 'admin/appearance/enable/' . $theme->name), + l(t('Set default'), 'admin/appearance/default/' . $theme->name), + ); } - if (!empty($theme->status)) { - $status[] = $theme->name; + + if (empty($theme->status)) { + // Ensure this theme is compatible with this version of core. + // Require the 'content' region to make sure the main page + // content has a common place in all themes. + $theme->incompatible_core = !isset($theme->info['core']) || ($theme->info['core'] != DRUPAL_CORE_COMPATIBILITY) || (!isset($theme->info['regions']['content'])); + $theme->incompatible_php = version_compare(phpversion(), $theme->info['php']) < 0; } - else { - // Ensure this theme is compatible with this version of core. - // Require the 'content' region to make sure the main page - // content has a common place in all themes. - if (!isset($theme->info['core']) || ($theme->info['core'] != DRUPAL_CORE_COMPATIBILITY) || (!isset($theme->info['regions']['content']))) { - $incompatible_core[] = $theme->name; - } - if (version_compare(phpversion(), $theme->info['php']) < 0) { - $incompatible_php[$theme->name] = $theme->info['php']; - } + + // Add notes to default and administration theme. + $theme->notes = array(); + $theme->classes = array(); + if ($theme->is_default) { + $theme->classes[] = 'theme-default'; + $theme->notes[] = t('default theme'); } - } - $form['status'] = array( - '#type' => 'checkboxes', - '#options' => array_fill_keys(array_keys($options), ''), - '#default_value' => $status, - '#incompatible_themes_core' => drupal_map_assoc($incompatible_core), - '#incompatible_themes_php' => $incompatible_php, - ); - $form['theme_default'] = array( - '#type' => 'radios', - '#options' => array_fill_keys(array_keys($options), ''), - '#default_value' => variable_get('theme_default', 'garland'), - ); + // Sort enabled and disabled themes into their own groups. + $theme_groups[$theme->status ? 'enabled' : 'disabled'][] = $theme; + } + + uasort($theme_groups['enabled'], 'system_sort_themes'); + return theme('system_themes_page', $theme_groups) . drupal_render(drupal_get_form('system_themes_admin_form', $admin_theme_options)); +} +/** + * Form to select the administration theme. + */ +function system_themes_admin_form($form_state, $theme_options) { // Administration theme settings. $form['admin_theme'] = array( '#type' => 'fieldset', @@ -278,7 +279,7 @@ function system_themes_form() { ); $form['admin_theme']['admin_theme'] = array( '#type' => 'select', - '#options' => array(0 => t('Default theme')) + $options, + '#options' => array(0 => t('Default theme')) + $theme_options, '#title' => t('Administration theme'), '#description' => t('Choose "Default theme" to always use the same theme as the rest of the site.'), '#default_value' => variable_get('admin_theme', 0), @@ -288,12 +289,10 @@ function system_themes_form() { '#title' => t('Use the administration theme when editing or creating content'), '#default_value' => variable_get('node_admin_theme', '0'), ); - - $form['buttons']['submit'] = array( + $form['admin_theme']['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration'), ); - return $form; } @@ -745,6 +744,19 @@ function system_sort_modules_by_info_nam } /** + * Array sorting callback; sorts modules or themes by their name. + */ +function system_sort_themes($a, $b) { + if ($a->is_default) { + return -1; + } + if ($b->is_default) { + return 1; + } + return strcasecmp($a->info['name'], $b->info['name']); +} + +/** * Build a table row for the system modules page. */ function _system_modules_build_row($info, $extra) { @@ -2239,58 +2251,54 @@ function theme_system_modules_uninstall( /** * Theme function for the system themes form. * - * @param $form - * An associative array containing the structure of the form. + * @param $theme_groups + * An associative array containing groups of themes. * @ingroup themeable */ -function theme_system_themes_form($form) { - foreach (element_children($form) as $key) { - // Only look for themes - if (!isset($form[$key]['info'])) { +function theme_system_themes_page($theme_groups) { + $output = '
'; + + // There are four possible theme groups. + $states = array( + 'enabled' => format_plural(count($theme_groups['enabled']), 'Enabled theme', 'Enabled themes'), + 'disabled' => format_plural(count($theme_groups['disabled']), 'Disabled theme', 'Disabled themes'), + ); + + foreach ($states as $state => $title) { + if (!count($theme_groups[$state])) { + // Skip this group of themes if no theme is there. continue; } - - // Fetch info - $info = $form[$key]['info']['#value']; - // Localize theme description. - $description = t($info['description']); - // Make sure it is compatible and render the checkbox if so. - if (isset($form['status']['#incompatible_themes_core'][$key])) { - unset($form['status'][$key]); - $status = theme('image', 'misc/watchdog-error.png', t('incompatible'), t('Incompatible with this version of Drupal core')); - $description .= '
' . t('This version is incompatible with the !core_version version of Drupal core.', array('!core_version' => VERSION)) . '
'; - } - elseif (isset($form['status']['#incompatible_themes_php'][$key])) { - unset($form['status'][$key]); - $status = theme('image', 'misc/watchdog-error.png', t('incompatible'), t('Incompatible with this version of PHP')); - $php_required = $form['status']['#incompatible_themes_php'][$key]; - if (substr_count($php_required, '.') < 2) { - $php_required .= '.*'; + // Start new theme group. + $output .= '

'. $title .'

'; + + foreach($theme_groups[$state] as $theme) { + + // Theme the screenshot. + $screenshot = $theme->screenshot ? theme('image', $theme->screenshot, t('Screenshot for %theme theme', array('%theme' => $theme->info['name'])), '', array('class' => 'screenshot'), FALSE) : t('no screenshot'); + + // Localize the theme description. + $description = t($theme->info['description']); + + // Make sure to provide feedback on compatibility. + if (!empty($theme->incompatible_core)) { + $description .= '
' . t('This version is incompatible with the !core_version version of Drupal core.', array('!core_version' => VERSION)) . '
'; + } + elseif (!empty($theme->inompatible_php)) { + if (substr_count($theme->info['php'], '.') < 2) { + $theme->info['php'] .= '.*'; + } + $description .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())) . '
'; } - $description .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion())) . '
'; - } - else { - $status = drupal_render($form['status'][$key]); - } - - // Style theme info - $theme = '

' . $info['name'] . '

' . $description . '
'; - // Build rows - $row = array(); - $row[] = drupal_render($form[$key]['screenshot']); - $row[] = $theme; - $row[] = isset($info['version']) ? $info['version'] : ''; - $row[] = array('data' => $status, 'align' => 'center'); - if ($form['theme_default']) { - $row[] = array('data' => drupal_render($form['theme_default'][$key]), 'align' => 'center'); - $row[] = array('data' => drupal_render($form[$key]['operations']), 'align' => 'center'); + // Style theme info + $notes = count($theme->notes) ? ' (' . join(', ', $theme->notes) . ')' : ''; + $theme->classes[] = 'theme-selector'; + $output .= '
' . $screenshot . '

' . $theme->info['name'] . ' ' . (isset($theme->info['version']) ? $theme->info['version'] : '') . $notes . '

' . $description . '
' . theme('item_list', $theme->operations) . '
'; } - $rows[] = $row; + $output .= '
'; } - - $header = array(t('Screenshot'), t('Name'), t('Version'), t('Enabled'), t('Default'), t('Operations')); - $output = theme('table', $header, $rows); - $output .= drupal_render_children($form); + $output .= '
'; + return $output; } Index: modules/system/system.css =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.css,v retrieving revision 1.61 diff -u -p -r1.61 system.css --- modules/system/system.css 24 Aug 2009 03:11:34 -0000 1.61 +++ modules/system/system.css 27 Aug 2009 08:16:26 -0000 @@ -510,8 +510,54 @@ html.js .js-hide { /* ** Styles for the system themes page (admin/appearance) */ -#system-themes-form div.incompatible { - font-weight: bold; +#block-system-main #system-themes-page h2 { + clear: both; + font-weight: normal; + text-transform: uppercase; +} +.theme-selector { + clear: both; + padding-top: 1em; +} +.theme-selector .screenshot { + float: left; + margin-right: 1em; + padding: 2px; +} +.theme-admin img, +.theme-default img { + border: 1px solid #aaa; +} +#block-system-main .theme-selector h3 { + padding-top: 2em; + font-weight: normal; +} +.system-themes-list-disabled .theme-selector { + width: 256px; + float: left; + clear: none; + padding: 1em 1em 1em 0; +} +.system-themes-list-disabled .theme-selector .screenshot { + padding-bottom: 0.5em; +} +.theme-selector .item-list li { + float: left; + padding: 0 0.7em 0 0.7em; + border-right: 1px solid #cdcdcd; +} +.theme-selector .item-list li.last { + padding: 0 0 0 0.7em; + border-right: none; +} +.theme-selector .item-list li.first { + padding: 0 0.7em 0 0; +} +.theme-selector-end { + border-bottom: 1px solid #cdcdcd; + clear: both; + padding-bottom: 1em; + margin-bottom: 1em; } /* Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.777 diff -u -p -r1.777 system.module --- modules/system/system.module 26 Aug 2009 10:53:45 -0000 1.777 +++ modules/system/system.module 27 Aug 2009 08:16:26 -0000 @@ -155,8 +155,8 @@ function system_help($path, $arg) { */ function system_theme() { return array_merge(drupal_common_theme(), array( - 'system_themes_form' => array( - 'arguments' => array('form' => NULL), + 'system_themes_page' => array( + 'arguments' => array('theme_groups' => NULL), 'file' => 'system.admin.inc', ), 'system_modules_fieldset' => array( @@ -585,8 +585,7 @@ function system_menu() { $items['admin/appearance'] = array( 'title' => 'Appearance', 'description' => 'Select and configure your site theme.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('system_themes_form'), + 'page callback' => 'system_themes_page', 'access arguments' => array('administer site configuration'), 'position' => 'left', 'weight' => -6, Index: themes/garland/screenshot.png =================================================================== RCS file: /cvs/drupal/drupal/themes/garland/screenshot.png,v retrieving revision 1.1 diff -u -p -r1.1 screenshot.png Binary files /tmp/cvsESeEJg and screenshot.png differ Index: themes/garland/minnelli/screenshot.png =================================================================== RCS file: /cvs/drupal/drupal/themes/garland/minnelli/screenshot.png,v retrieving revision 1.1 diff -u -p -r1.1 screenshot.png Binary files /tmp/cvs5ydkwi and screenshot.png differ Index: themes/seven/screenshot.png =================================================================== RCS file: /cvs/drupal/drupal/themes/seven/screenshot.png,v retrieving revision 1.1 diff -u -p -r1.1 screenshot.png Binary files /tmp/cvsWPfBjk and screenshot.png differ Index: themes/stark/screenshot.png =================================================================== RCS file: /cvs/drupal/drupal/themes/stark/screenshot.png,v retrieving revision 1.1 diff -u -p -r1.1 screenshot.png Binary files /tmp/cvsE23N7l and screenshot.png differ