Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.90
diff -u -p -r1.90 block.admin.inc
--- modules/block/block.admin.inc	10 Oct 2010 20:11:21 -0000	1.90
+++ modules/block/block.admin.inc	23 Oct 2010 03:49:43 -0000
@@ -286,11 +286,12 @@ function block_admin_configure($form, &$
     '#type' => 'fieldset',
     '#title' => t('Region settings'),
     '#collapsible' => FALSE,
-    '#description' => t('Specify in which themes and regions this block is displayed.'),
+    '#description' => t('Specify where this block is displayed.'),
     '#tree' => TRUE,
   );
 
   $theme_default = variable_get('theme_default', 'bartik');
+  $admin_theme = variable_get('admin_theme');
   foreach (list_themes() as $key => $theme) {
     // Only display enabled themes
     if ($theme->status) {
@@ -300,9 +301,18 @@ function block_admin_configure($form, &$
         ':theme' => $key,
       ))->fetchField();
 
+      // Provide labels to help distinguish the administrative and
+      // default themes.
+      $theme_title = $theme->info['name'];
+      if ($key == $theme_default) {
+        $theme_title = t('!theme (default theme)', array('!theme' => $theme_title));
+      }
+      elseif ($admin_theme && $key == $admin_theme) {
+        $theme_title = t('!theme (administration theme)', array('!theme' => $theme_title));
+      }
       $form['regions'][$key] = array(
         '#type' => 'select',
-        '#title' => $theme->info['name'],
+        '#title' => $theme_title,
         '#default_value' => !empty($region) && $region != -1 ? $region : NULL,
         '#empty_value' => BLOCK_REGION_NONE,
         '#options' => system_region_list($key, REGIONS_VISIBLE),
Index: modules/block/block.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.api.php,v
retrieving revision 1.13
diff -u -p -r1.13 block.api.php
--- modules/block/block.api.php	13 Aug 2010 12:25:14 -0000	1.13
+++ modules/block/block.api.php	23 Oct 2010 03:49:43 -0000
@@ -57,6 +57,11 @@
  *     - DRUPAL_CACHE_GLOBAL: The block is the same for every user on every
  *       page where it is visible.
  *     - DRUPAL_NO_CACHE: The block should not get cached.
+ *   - 'properties': (optional) Array of additional metadata to add to the
+ *     block. Common properties include:
+ *     - 'administrative': Boolean which categorizes this block as usable in
+ *       an administrative context. This might include blocks which help an
+ *       admin approve/deny comments, or view recently created user accounts.
  *   - 'weight': (optional) Initial value for the ordering weight of this block.
  *     Most modules do not provide an initial value, and any value provided can
  *     be modified by a user on the block configuration screen.
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.906
diff -u -p -r1.906 comment.module
--- modules/comment/comment.module	20 Oct 2010 01:31:06 -0000	1.906
+++ modules/comment/comment.module	23 Oct 2010 03:49:44 -0000
@@ -402,6 +402,7 @@ function comment_permission() {
  */
 function comment_block_info() {
   $blocks['recent']['info'] = t('Recent comments');
+  $blocks['recent']['properties']['administrative'] = TRUE;
 
   return $blocks;
 }
Index: modules/dashboard/dashboard.admin.js
===================================================================
RCS file: modules/dashboard/dashboard.admin.js
diff -N modules/dashboard/dashboard.admin.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/dashboard/dashboard.admin.js	23 Oct 2010 03:49:44 -0000
@@ -0,0 +1,129 @@
+// $Id$
+
+Drupal.behaviors.dashboardAdmin = {};
+
+Drupal.behaviors.dashboardAdmin.attach = function (context, settings) {
+  var $ = jQuery;
+  var theme = settings.dashboardTheme;
+  var regions = settings.dashboardRegions;
+  var $checkbox = $('#edit-dashboard-availability').once('dashboard-admin');
+  var $select = $('#edit-regions-' + theme);
+  if ($checkbox.length && $select.length) {
+    // When the user changes the administrative theme regions dropdown, update
+    // the dashboard checkbox, and vice versa.
+    var handler = new Drupal.dashboardAdminHandler($checkbox, $select, regions);
+    handler.initialize();
+  }
+};
+
+/**
+ * Constructor for the Drupal.dashboardAdminHandler class.
+ *
+ * Keeps the administrative theme regions dropdown and the dashboard checkbox
+ * in sync.
+ *
+ * @param {jQuery} $checkbox
+ *   A jQuery object representing the dashboard checkbox.
+ * @param {jQuery} $select
+ *   A jQuery object representing the select dropdown for the administrative
+ *   theme's regions.
+ * @param {array} regions
+ *   An array of dashboard region names.
+ */
+Drupal.dashboardAdminHandler = function ($checkbox, $select, regions) {
+  this.$checkbox = $checkbox;
+  this.$select = $select;
+  this.initializeDashboardRegions(regions);
+  this.dashboardMain = 'dashboard_main';
+
+  this.initialCheckboxValue = $checkbox.is(':checked');
+  this.initialSelectValue = $select.val();
+  this.blockRegionNone = $select.find('option:first').val();
+};
+
+/**
+ * Initializes the dashboardAdminHandler object.
+ *
+ * Determines the initial values for the dashboard region and the content
+ * region, and binds a change handler to the checkbox and the select dropdown.
+ */
+Drupal.dashboardAdminHandler.prototype.initialize = function () {
+  var $ = jQuery;
+
+  // Keep track of the original value of the region dropdown, so we can restore
+  // it when the checkbox value changes.
+  if (this.isDashboardRegion(this.initialSelectValue)) {
+    this.dashboardRegion = this.initialSelectValue;
+    this.contentRegion = this.blockRegionNone;
+  }
+  else {
+    this.dashboardRegion = this.dashboardMain;
+    this.contentRegion = this.initialSelectValue;
+  }
+
+  // Bind event handlers to the checkbox and the select dropdown so we can
+  // keep each up to date when the other changes.
+  this.$checkbox.bind('change', $.proxy(this, 'checkboxHandler'));
+  this.$select.bind('change', $.proxy(this, 'selectHandler'));
+};
+
+/**
+ * Updates the select dropdown when the user clicks the checkbox.
+ */
+Drupal.dashboardAdminHandler.prototype.checkboxHandler = function () {
+  var checked = this.$checkbox.is(':checked');
+  if (checked) {
+    this.$select.val(this.dashboardRegion);
+  }
+  else {
+    this.$select.val(this.contentRegion);
+  }
+};
+
+/**
+ * Updates the checkbox when the user changes the selected region.
+ */
+Drupal.dashboardAdminHandler.prototype.selectHandler = function () {
+  var region = this.$select.val();
+  // If the user chose "None" as the region, record that as their new region
+  // preference.
+  if (region == this.blockRegionNone) {
+    var checked = this.$checkbox.attr('checked');
+    if (checked) {
+      this.dashboardRegion = this.blockRegionNone;
+    }
+    else {
+      this.contentRegion = this.blockRegionNone;
+    }
+  }
+  else if (this.isDashboardRegion(region)) {
+    this.dashboardRegion = region;
+    this.$checkbox.attr('checked', 'checked');
+  }
+  else {
+    this.contentRegion = region;
+    this.$checkbox.attr('checked', '');
+  }
+};
+
+/**
+ * Determines whether a given region is on the dashboard.
+ */
+Drupal.dashboardAdminHandler.prototype.isDashboardRegion = function (regionName) {
+  return this.dashboardRegions[regionName] || false;
+};
+
+/**
+ * Initializes the object with the list of dashboard region names.
+ *
+ * @param {Array} regions
+ *   An array of dashboard region names.
+ */
+Drupal.dashboardAdminHandler.prototype.initializeDashboardRegions = function (regions) {
+  var regionNames = {};
+  var i;
+  for (i = 0; i < regions.length; i++) {
+    regionNames[regions[i]] = regions[i];
+  }
+  this.dashboardRegions = regionNames;
+};
Index: modules/dashboard/dashboard.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/dashboard/dashboard.module,v
retrieving revision 1.40
diff -u -p -r1.40 dashboard.module
--- modules/dashboard/dashboard.module	21 Oct 2010 11:55:08 -0000	1.40
+++ modules/dashboard/dashboard.module	23 Oct 2010 03:49:44 -0000
@@ -186,6 +186,33 @@ function dashboard_system_info_alter(&$i
 }
 
 /**
+ * Implements hook_block_info_alter().
+ *
+ * Saves a list of blocks to be available to the dashboard by default, which
+ * are defined with $block['properties']['administrative'] = TRUE.
+ */
+function dashboard_block_info_alter(&$blocks, $theme, $code_blocks) {
+  if (!$theme = variable_get('admin_theme')) {
+    global $theme_key;
+    $theme = $theme_key;
+  }
+  $available_blocks = variable_get('dashboard_available_blocks', array());
+
+  foreach ($blocks as $module => &$module_blocks) {
+    foreach ($module_blocks as $delta => &$block) {
+      if ($block['theme'] != $theme) {
+        // Only process for the admin theme, which displays the dashboard.
+        continue;
+      }
+      if (!empty($code_blocks[$module][$delta]['properties']['administrative']) && !isset($available_blocks[$module][$delta])) {
+        $available_blocks[$module][$delta] = TRUE;
+      }
+    }
+  }
+  variable_set('dashboard_available_blocks', $available_blocks);
+}
+
+/**
  * Implements hook_theme().
  */
 function dashboard_theme() {
@@ -281,14 +308,16 @@ function dashboard_admin_blocks() {
   module_load_include('inc', 'block', 'block.admin');
 
   // Prepare the blocks for the current theme, and remove those that are
-  // currently displayed in non-dashboard regions.
+  // currently displayed in non-dashboard regions, or are not marked as
+  // available through hook_block_info() or the block configure form.
   // @todo This assumes the current page is being displayed using the same
   //   theme that the dashboard is displayed in.
   $blocks = block_admin_display_prepare_blocks($theme_key);
   $dashboard_regions = dashboard_region_descriptions();
   $regions_to_remove = array_diff_key(system_region_list($theme_key, REGIONS_VISIBLE), $dashboard_regions);
+  $available_blocks = variable_get('dashboard_available_blocks', array());
   foreach ($blocks as $id => $block) {
-    if (isset($regions_to_remove[$block['region']])) {
+    if (isset($regions_to_remove[$block['region']]) || (empty($available_blocks[$block['module']][$block['delta']]) && !in_array($block['region'], dashboard_regions()))) {
       unset($blocks[$id]);
     }
   }
@@ -356,6 +385,68 @@ function dashboard_form_block_admin_conf
       $region['#options'] = array_diff_key($region['#options'], $dashboard_regions);
     }
   }
+
+  // Provide a block setting to control dashboard availability.
+  $available_blocks = variable_get('dashboard_available_blocks', array());
+  $form['settings']['dashboard_availability'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Available on dashboard'),
+    '#default_value' => !empty($available_blocks[$form['module']['#value']][$form['delta']['#value']]),
+  );
+
+  $form['#attached']['js'][] = drupal_get_path('module', 'dashboard') . '/dashboard.admin.js';
+  $form['#attached']['js'][] = array(
+    'data' => array(
+      'dashboardTheme' => $theme_key,
+      'dashboardRegions' => dashboard_regions(),
+    ),
+    'type' => 'setting',
+  );
+  $form['#validate'][] = 'dashboard_form_block_admin_configure_validate';
+  $form['#submit'] = array_merge(array('dashboard_form_block_admin_configure_submit'), $form['#submit']);
+}
+
+/**
+ * Form validation handler for block configuration form.
+ */
+function dashboard_form_block_admin_configure_validate($form, &$form_state) {
+  global $theme_key;
+  drupal_theme_initialize();
+
+  // Ensure that the dashboard availability flag is only settable if the block
+  // hasn't been assigned to a non-dashboard region.
+  $selected_region = $form_state['values']['regions'][$theme_key];
+  $changed = ($form['settings']['dashboard_availability']['#default_value'] != $form_state['values']['dashboard_availability']);
+  if ($form_state['values']['dashboard_availability'] && $changed && $selected_region != BLOCK_REGION_NONE && !in_array($selected_region, dashboard_regions())) {
+    form_set_error('regions][' . $theme_key, t('The block must be removed from a region in !theme to enable it on the dashboard.', array('!theme' => $form['regions'][$theme_key]['#title'])));
+  }
+}
+
+/**
+ * Form submission handler for block configuration form.
+ */
+function dashboard_form_block_admin_configure_submit($form, &$form_state) {
+  global $theme_key;
+  drupal_theme_initialize();
+
+  // Cause the block to be added/removed from the dashboard based on the
+  // dashboard availability setting, if the state has changed.
+  if ($form['settings']['dashboard_availability']['#default_value'] != $form_state['values']['dashboard_availability']) {
+    $region = &$form_state['values']['regions'][$theme_key];
+    $available_blocks = variable_get('dashboard_available_blocks', array());
+    $available_blocks[$form_state['values']['module']][$form_state['values']['delta']] = $form_state['values']['dashboard_availability'];
+    variable_set('dashboard_available_blocks', $available_blocks);
+    if ($form_state['values']['dashboard_availability']) {
+      // Add the block to the dashboard if not already assigned to a region.
+      if ($region == BLOCK_REGION_NONE) {
+        $region = 'dashboard_main';
+        drupal_set_message(t('Block added to the dashboard.'));
+      }
+    }
+    elseif (in_array($region, dashboard_regions())) {
+      $region = BLOCK_REGION_NONE;
+    }
+  }
 }
 
 /**
@@ -445,9 +536,11 @@ function dashboard_show_disabled() {
   // Blocks are not necessarily initialized at this point.
   $blocks = _block_rehash();
 
-  // Limit the list to disabled blocks for the current theme.
+  // Limit the list to disabled blocks for the current theme which are marked
+  // as available through hook_block_info() or the block configure form.
+  $available_blocks = variable_get('dashboard_available_blocks', array());
   foreach ($blocks as $key => $block) {
-    if ($block['theme'] != $theme_key || (!empty($block['status']) && !empty($block['region']))) {
+    if ($block['theme'] != $theme_key || (!empty($block['status']) && !empty($block['region'])) || empty($available_blocks[$block['module']][$block['delta']])) {
       unset($blocks[$key]);
     }
   }
Index: modules/dashboard/dashboard.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/dashboard/dashboard.test,v
retrieving revision 1.6
diff -u -p -r1.6 dashboard.test
--- modules/dashboard/dashboard.test	21 Oct 2010 11:55:09 -0000	1.6
+++ modules/dashboard/dashboard.test	23 Oct 2010 03:49:44 -0000
@@ -42,7 +42,7 @@ class DashboardBlocksTestCase extends Dr
     $custom_block['info'] = $this->randomName(8);
     $custom_block['title'] = $this->randomName(8);
     $custom_block['body[value]'] = $this->randomName(32);
-    $custom_block['regions[stark]'] = 'dashboard_main';
+    $custom_block['dashboard_availability'] = TRUE;
     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
 
     // Ensure admin access.
@@ -79,4 +79,116 @@ class DashboardBlocksTestCase extends Dr
       $this->assertTrue(empty($elements), t('%region is not an available choice on the block configuration page.', array('%region' => $region)));
     }
   }
+
+  /**
+   * Test that defining a block with ['properties']['administrative'] = TRUE
+   * adds it as an available block for the dashboard.
+   */
+  function testBlockAvailability() {
+    global $theme_key;
+    $this->drupalGet('admin/dashboard/configure');
+    // "Recent comments" should be available in the dashboard block admin UI.
+    $this->assertText(t('Recent comments'), t('Block defined as "administrative" found in the dashboard block admin UI.'));
+    // "Syndicate" should not show up in the UI since it is not defined
+    // as "administrative".
+    $this->assertNoText(t('Syndicate'), t('Blocks not defined as "administrative" are excluded from dashboard UI by default.'));
+
+    // Now test admin/dashboard/drawer in the same way.
+    $this->drupalGet('admin/dashboard/drawer');
+    $this->assertText(t('Recent comments'), t('Drawer of disabled blocks includes the one defined as "administrative".'));
+    $this->assertNoText(t('Syndicate'), t('Drawer of disabled blocks excludes blocks not defined as "administrative".'));
+
+    // Manipulate availability checkbox and reverse it: make "Recent comments"
+    // unavailable to the dashboard and make "Syndicate" available.
+    $values = array();
+    $values['dashboard_availability'] = FALSE;
+    $this->drupalPost('admin/structure/block/manage/comment/recent/configure', $values, t('Save block'));
+    $this->drupalGet('admin/structure/block/manage/comment/recent/configure');
+    $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-dashboard-availability'));
+    $this->assertTrue(!empty($elements[0]) && empty($elements[0]['checked']), t('Dashboard availability disabled for "Recent comments".'));
+    $values['dashboard_availability'] = TRUE;
+    $this->drupalPost('admin/structure/block/manage/node/syndicate/configure', $values, t('Save block'));
+    $this->drupalGet('admin/structure/block/manage/node/syndicate/configure');
+    $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-dashboard-availability'));
+    $this->assertTrue(!empty($elements[0]) && !empty($elements[0]['checked']), t('Dashboard availability enabled for "Syndicate".'));
+
+    $this->drupalGet('admin/dashboard/configure');
+    $this->assertNoText(t('Recent comments'), t('Block dashboard availability can be overridden.'));
+    $this->assertText(t('Syndicate'), t('Block dashboard availability overridden for a block not defined as "administrative".'));
+
+    // Now test admin/dashboard/drawer in the same way.
+    $this->drupalGet('admin/dashboard/drawer');
+    $this->assertNoText(t('Recent comments'), t('Drawer of disabled blocks excludes blocks defined as "administrative" but overridden through the block UI.'));
+    $values = array();
+    $values['blocks[node_syndicate][region]'] = BLOCK_REGION_NONE;
+    $this->drupalPost('admin/dashboard/configure', $values, t('Save blocks'));
+    $this->assertText(t('Syndicate'), t('Drawer of disabled blocks includes blocks not defined as "administrative" but overridden through the UI.'));
+  }
+
+  /**
+   * Test that a block can be added and removed from the dashboard via the
+   * "Available on dashboard" checkbox. Also test the validation error if the
+   * block is already assigned to a region.
+   */
+  function testDashboardEnableCheckbox() {
+    // Attempt to put "System help" block on the dashboard. This should fail
+    // since the block is already assigned to a non-dashboard region of the
+    // admin theme.
+    $this->drupalGet('admin/structure/block/manage/system/help/configure');
+    $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-dashboard-availability'));
+    $this->assertTrue(!empty($elements[0]) && empty($elements[0]['checked']), t('Dashboard availability checkbox is present and unchecked.'));
+    $values = array();
+    $values['dashboard_availability'] = TRUE;
+    $this->drupalPost('admin/structure/block/manage/system/help/configure', $values, t('Save block'));
+    $stark_label = t('!theme (default theme)', array('!theme' => 'Stark'));
+    $this->assertText(t('The block must be removed from a region in !theme to enable it on the dashboard.', array('!theme' => $stark_label)), t('Dashboard availability setting not selectable when the block is already in a non-dashboard region for the admin theme.'));
+
+    // Unassign the region, and now we should see a success message.
+    $values['regions[stark]'] = BLOCK_REGION_NONE;
+    $this->drupalPost('admin/structure/block/manage/system/help/configure', $values, t('Save block'));
+    $this->assertText(t('Block added to the dashboard.'), t('Validation error is fixed by unassigning the region.'));
+
+    // Ensure that the block shows up on the dashboard.
+    $this->drupalGet('admin/dashboard');
+    $this->assertText(t('System help'), t('Block is now on the dashboard.'));
+    $this->drupalGet('admin/dashboard/configure');
+    $this->assertText(t('System help'), t('Block displays in dashboard block UI.'));
+
+    // Now remove the block from the dashboard via the checkbox.
+    $values = array();
+    $values['dashboard_availability'] = FALSE;
+    $this->drupalPost('admin/structure/block/manage/system/help/configure', $values, t('Save block'));
+    $this->drupalGet('admin/dashboard');
+    $this->assertNoText(t('System help'), t('Block was removed from the dashboard via the dashboard availability setting.'));
+
+    // Test a block defined as "administrative" but not initially on
+    // the dashboard.
+    $this->drupalGet('admin/dashboard');
+    $this->assertNoText(t('Recent comments'), t('Block is not on the dashboard.'));
+    $this->drupalGet('admin/dashboard/drawer');
+    $this->assertText(t('Recent comments'), t('Block is in drawer of disabled blocks.'));
+
+    $this->drupalGet('admin/structure/block/manage/comment/recent/configure');
+    $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-dashboard-availability'));
+    $this->assertTrue(!empty($elements[0]) && !empty($elements[0]['checked']), t('Dashboard availability enabled for "Recent comments".'));
+
+    // Save the "Who's online" block, which should be available to the
+    // dashboard by default, but not enabled. Change the title, but leave the
+    // dashboard availability checkbox unchanged. The block should not be
+    // automatically added to the dashboard unless the user consciously
+    // changes the checkbox.
+    $this->drupalGet('admin/structure/block/manage/user/online/configure');
+    $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-dashboard-availability'));
+    $this->assertTrue(!empty($elements[0]) && !empty($elements[0]['checked']), t('Dashboard availability checkbox is checked.'));
+    $this->drupalGet('admin/dashboard');
+    $this->assertNoText(t('Who\'s online'), t('Block is not on the dashboard.'));
+    $values = array();
+    $values['title'] = t('My block');
+    $this->drupalPost('admin/structure/block/manage/user/online/configure', $values, t('Save block'));
+    $this->assertNoText(t('Block added to the dashboard.'), t('Block was not automatically added to dashboard.'));
+    $this->drupalGet('admin/dashboard');
+    $this->assertNoText(t('My block'), t('Block is not on the dashboard.'));
+    $this->drupalGet('admin/dashboard/drawer');
+    $this->assertText(t('My block'), t('Block is in drawer of disabled blocks.'));
+  }
 }
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1309
diff -u -p -r1.1309 node.module
--- modules/node/node.module	20 Oct 2010 08:15:33 -0000	1.1309
+++ modules/node/node.module	23 Oct 2010 03:49:44 -0000
@@ -2076,6 +2076,7 @@ function node_block_info() {
   $blocks['syndicate']['cache'] = DRUPAL_NO_CACHE;
 
   $blocks['recent']['info'] = t('Recent content');
+  $blocks['recent']['properties']['administrative'] = TRUE;
 
   return $blocks;
 }
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.365
diff -u -p -r1.365 search.module
--- modules/search/search.module	20 Oct 2010 01:31:07 -0000	1.365
+++ modules/search/search.module	23 Oct 2010 03:49:44 -0000
@@ -143,6 +143,8 @@ function search_block_info() {
   $blocks['form']['info'] = t('Search form');
   // Not worth caching.
   $blocks['form']['cache'] = DRUPAL_NO_CACHE;
+  $blocks['form']['properties']['administrative'] = TRUE;
+
   return $blocks;
 }
 
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1211
diff -u -p -r1.1211 user.module
--- modules/user/user.module	20 Oct 2010 05:32:31 -0000	1.1211
+++ modules/user/user.module	23 Oct 2010 03:49:45 -0000
@@ -1273,10 +1273,13 @@ function user_block_info() {
   $blocks['login']['cache'] = DRUPAL_NO_CACHE;
 
   $blocks['new']['info'] = t('Who\'s new');
+  $blocks['new']['properties']['administrative'] = TRUE;
 
   // Too dynamic to cache.
   $blocks['online']['info'] = t('Who\'s online');
   $blocks['online']['cache'] = DRUPAL_NO_CACHE;
+  $blocks['online']['properties']['administrative'] = TRUE;
+
   return $blocks;
 }
 
