? CHANGELOG.000
? CHANGELOG.001
Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.177
diff -u -r1.177 database.mysql
--- database/database.mysql	12 Apr 2005 18:52:47 -0000	1.177
+++ database/database.mysql	18 Apr 2005 14:50:20 -0000
@@ -122,7 +122,7 @@
   delta varchar(32) NOT NULL default '0',
   status tinyint(2) DEFAULT '0' NOT NULL,
   weight tinyint(1) DEFAULT '0' NOT NULL,
-  region tinyint(1) DEFAULT '0' NOT NULL,
+  region varchar(64) DEFAULT '' NOT NULL,
   custom tinyint(2) DEFAULT '0' NOT NULL,
   throttle tinyint(1) DEFAULT '0' NOT NULL,
   visibility tinyint(1) DEFAULT '0' NOT NULL,
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.108
diff -u -r1.108 updates.inc
--- database/updates.inc	16 Apr 2005 08:01:48 -0000	1.108
+++ database/updates.inc	18 Apr 2005 14:53:49 -0000
@@ -109,6 +109,7 @@
   "2005-04-10" => "update_130",
   "2005-04-11" => "update_131",
   "2005-04-14" => "update_132"
+  "2005-04-18" => "update_133"
 );
 
 function update_32() {
@@ -2405,6 +2406,16 @@
   return $ret;
 }
 
+function update_133() {
+  $ret = array();
+
+  $ret[] = update_sql("ALTER TABLE {blocks} CHANGE region region varchar(64) default '' NOT NULL");
+  $ret[] = update_sql("UPDATE {blocks} SET region = 'left' WHERE region = '0'");
+  $ret[] = update_sql("UPDATE {blocks} SET region = 'right' WHERE region = '1'");
+
+  return $ret;
+}
+
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
Index: modules/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block.module,v
retrieving revision 1.163
diff -u -r1.163 block.module
--- modules/block.module	12 Apr 2005 18:52:47 -0000	1.163
+++ modules/block.module	18 Apr 2005 15:10:34 -0000
@@ -14,7 +14,7 @@
     case 'admin/help#block':
       return t('
 <p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks.</p>
-<p>The sidebar each block appears in depends on both which theme you are using (some are left-only, some right, some both), and on the settings in block management.</p>
+<p>The region each block appears in depends on both which theme you are using (some are left-only, some right, some both, and some may offer other regions), and on the settings in block management.</p>
 <p>The block management screen lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a weight to each block. Lighter blocks (smaller weight) "float up" towards the top of the sidebar. Heavier ones "sink down" towards the bottom of it.</p>
 <p>A block\'s visibility depends on:</p>
 <ul>
@@ -31,7 +31,7 @@
       return t('Controls the boxes that are displayed around the main content.');
     case 'admin/block':
       return t("
-<p>Blocks are the boxes in the left and right side bars of the web site. They are made available by modules or created manually.</p>
+<p>Blocks are content rendered into regions, often boxes in the left and right side bars of the web site. They are made available by modules or created manually.</p>
 <p>Only enabled blocks are shown. You can position the blocks by deciding which side of the page they will show up on (sidebar) and in which order they appear (weight).</p>
 <p>If you want certain blocks to disable themselves temporarily during high server loads, check the 'Throttle' box. You can configure the auto-throttle on the <a href=\"%throttle\">throttle configuration page</a> after having enabled the throttle module.
 ", array('%throttle' => url('admin/settings/throttle')));
@@ -112,7 +112,7 @@
 function block_admin_save($edit) {
   foreach ($edit as $module => $blocks) {
     foreach ($blocks as $delta => $block) {
-      db_query("UPDATE {blocks} SET region = %d, status = %d, weight = %d, throttle = %d WHERE module = '%s' AND delta = '%s'",
+      db_query("UPDATE {blocks} SET region = '%s', status = %d, weight = %d, throttle = %d WHERE module = '%s' AND delta = '%s'",
                 $block['region'], $block['status'], $block['weight'], $block['throttle'], $module, $delta);
     }
   }
@@ -160,7 +160,7 @@
         }
 
         // reinsert blocks into table
-        db_query("INSERT INTO {blocks} (module, delta, status, weight, region, visibility, pages, custom, throttle, types) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d, %d, '%s')",
+        db_query("INSERT INTO {blocks} (module, delta, status, weight, region, visibility, pages, custom, throttle, types) VALUES ('%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s')",
           $block['module'], $block['delta'], $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['types']);
 
         $blocks[] = $block;
@@ -183,14 +183,13 @@
 function block_admin_display() {
   $blocks = _block_rehash();
 
-  $header = array(t('Block'), t('Enabled'), t('Weight'), t('Sidebar'));
+  $header = array(t('Block'), t('Enabled'), t('Weight'), t('Placement'));
   if (module_exist('throttle')) {
     $header[] = t('Throttle');
   }
   $header[] = array('data' => t('Operations'), 'colspan' => 2);
 
-  $left = array();
-  $right = array();
+  $regions = array();
   $disabled = array();
   foreach ($blocks as $block) {
     if ($block['module'] == 'block') {
@@ -203,8 +202,8 @@
     $row = array(array('data' => $block['info'], 'class' => 'block'),
       form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']),
       form_weight(NULL, $block['module'] .']['. $block['delta'] .'][weight', $block['weight']),
-      form_radios(NULL, $block['module'] .']['. $block['delta'] .'][region', $block['region'],
-      array(t('left'), t('right'))));
+      form_select(NULL, $block['module'] .']['. $block['delta'] .'][region', $block['region'],
+      block_region_list()));
 
     if (module_exist('throttle')) {
       $row[] = form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][throttle', 1, $block['throttle']);
@@ -212,11 +211,10 @@
     $row[] = l(t('configure'), 'admin/block/configure/'. $block['module'] .'/'. $block['delta']);
     $row[] = $delete;
     if ($block['status']) {
-      if ($block['region'] == 0) {
-        $left[] = $row;
-      }
-      if ($block['region'] == 1) {
-        $right[] = $row;
+      foreach (block_region_list() as $key => $value) {
+        if ($block['region'] == $key) {
+          $regions[ucfirst($value)][] = $row;
+        }
       }
     }
     else if ($block['region'] <= 1) {
@@ -225,13 +223,11 @@
   }
 
   $rows = array();
-  if (count($left)) {
-    $rows[] = array(array('data' => t('Left sidebar'), 'class' => 'region', 'colspan' => (module_exist('throttle') ? 7 : 6)));
-    $rows = array_merge($rows, $left);
-  }
-  if (count($right)) {
-    $rows[] = array(array('data' => t('Right sidebar'), 'class' => 'region', 'colspan' => (module_exist('throttle') ? 7 : 6)));
-    $rows = array_merge($rows, $right);
+  if (count($regions)) {
+    foreach ($regions as $region => $row) {
+      $rows[] = array(array('data' => t('%region region', array ('%region' => $region)), 'class' => 'region', 'colspan' => (module_exist('throttle') ? 7 : 6)));
+      $rows = array_merge($rows, $row);
+    }
   }
   if (count($disabled)) {
     $rows[] = array(array('data' => t('Disabled'), 'class' => 'region', 'colspan' => (module_exist('throttle') ? 7 : 6)));
@@ -426,39 +422,52 @@
   }
 }
 
- /**
-  * Return all blocks in the specied region for the current user. You may
-  * use this function to implement variable block regions.  The default
-  * regions are 'left', 'right' and 'all', where 'all' means both left and
-  * right.
-  *
-  * @param $region
-  *   This is a string which describes in a human readable form which region
-  *   you need.
-  *
-  * @param $regions
-  *   This is an optional array and contains map(s) from the string $region to
-  *   the numerical region value(s) in the blocks table. See default value for
-  *   examples.
-  *
-  * @return
-  *   An array of block objects, indexed with <i>module</i>_<i>delta</i>.
-  *   If you are displaying your blocks in one or two sidebars, you may check
-  *   whether this array is empty to see how many columns are going to be
-  *   displayed.
-  *
-  * @todo
-  *   Add a proper primary key (bid) to the blocks table so we don't have
-  *   to mess around with this <i>module</i>_<i>delta</i> construct.
-  *   Currently, the blocks table has no primary key defined!
-  */
-function block_list($region, $regions = array('left' => 0, 'right' => 1, 'all' => '0, 1')) {
+/**
+ * Get a list of all the defined block regions.
+ *
+ * @return
+ *   An array of all block regions.
+ */
+function block_region_list() {
+  $regions = array();
+  $themes = system_theme_data();
+  foreach ($themes as $info) {
+    $new_regions = function_exists($info->prefix . '_regions') ? call_user_func($info->prefix . '_regions') : array();
+    $regions = array_merge($new_regions, $regions);
+  }
+  return $regions;
+}
+
+/**
+ * Return all blocks in the specified region for the current user.
+ *
+ * @param $region
+ *   This is a string which describes in a human readable form which region
+ *   you need.
+ *
+ * @param $regions
+ *   This is an optional array and contains map(s) from the string $region to
+ *   the numerical region value(s) in the blocks table.
+ *
+ * @return
+ *   An array of block objects, indexed with <i>module</i>_<i>delta</i>.
+ *   If you are displaying your blocks in one or two sidebars, you may check
+ *   whether this array is empty to see how many columns are going to be
+ *   displayed.
+ *
+ * @todo
+ *   Add a proper primary key (bid) to the blocks table so we don't have
+ *   to mess around with this <i>module</i>_<i>delta</i> construct.
+ *   Currently, the blocks table has no primary key defined!
+ */
+function block_list($region) {
   global $user;
+
   static $blocks = array();
 
   if (!isset($blocks[$region])) {
     $blocks[$region] = array();
-    $result = db_query("SELECT * FROM {blocks} WHERE status = 1 AND region IN ('%s') ORDER BY weight, module", $regions[$region]);
+    $result = db_query("SELECT * FROM {blocks} WHERE status = 1 AND region = '%s' ORDER BY weight, module", $region);
     while ($block = db_fetch_array($result)) {
       // Use the user's block visibility setting, if necessary
       if ($block['custom'] != 0) {
Index: themes/bluemarine/xtemplate.xtmpl
===================================================================
RCS file: /cvs/drupal/drupal/themes/bluemarine/xtemplate.xtmpl,v
retrieving revision 1.6
diff -u -r1.6 xtemplate.xtmpl
--- themes/bluemarine/xtemplate.xtmpl	14 Nov 2004 19:34:09 -0000	1.6
+++ themes/bluemarine/xtemplate.xtmpl	18 Apr 2005 01:35:38 -0000
@@ -41,6 +41,11 @@
       <!-- END: search_box -->
     </td>
   </tr>
+  <tr>
+    <td>
+      <div id="banner_blocks">{banner_blocks}</div>
+    </td>
+  </tr>
 </table>
 
 <table border="0" cellpadding="0" cellspacing="0" id="content">
Index: themes/engines/xtemplate/xtemplate.engine
===================================================================
RCS file: /cvs/drupal/drupal/themes/engines/xtemplate/xtemplate.engine,v
retrieving revision 1.12
diff -u -r1.12 xtemplate.engine
--- themes/engines/xtemplate/xtemplate.engine	31 Mar 2005 09:25:33 -0000	1.12
+++ themes/engines/xtemplate/xtemplate.engine	18 Apr 2005 03:39:41 -0000
@@ -23,6 +23,17 @@
   return system_listing('^xtemplate\.xtmpl$', 'themes', 'filename');
 }
 
+function xtemplate_regions() {
+  return array(
+       'banner' => t('banner'),
+       'left' => t('left sidebar'),
+       'right' => t('right sidebar'),
+       'body_top' => t('body top'),
+       'body_bottom' => t('body bottom'),
+       'footer' => t('footer')
+  );
+}
+
 function xtemplate_features() {
   return array(
        'logo',
@@ -121,7 +132,8 @@
     "styles" => theme_get_styles(),
     "onload_attributes" => theme_onload_attribute(),
     "primary_links" => theme_get_setting('primary_links'),
-    "secondary_links" => theme_get_setting('secondary_links')
+    "secondary_links" => theme_get_setting('secondary_links'),
+    "banner_blocks" => theme("blocks", "banner")
    ));
 
   if ($logo = theme_get_setting('logo')) {
@@ -185,7 +197,21 @@
   $output = $xtemplate->template->text("header");
 
   $output .= "\n<!-- begin content -->\n";
+
+  if ($blocks = theme("blocks", "body_top")) {
+    $output .= $blocks;
+  }
+
   $output .= $content;
+
+  if ($blocks = theme("blocks", "body_bottom")) {
+    $output .= $blocks;
+  }
+
+  if ($blocks = theme("blocks", "left")) {
+    $xtemplate->template->assign("blocks", $blocks);
+    $xtemplate->template->parse("header.blocks");
+  }
   $output .= "\n<!-- end content -->\n";
 
   if ($blocks = theme("blocks", "right")) {
@@ -193,9 +219,9 @@
     $xtemplate->template->parse("footer.blocks");
   }
 
-  // only parse the footer block if site_footer is set
-  if ($footer_message = variable_get("site_footer", FALSE)) {
-    $xtemplate->template->assign("footer_message", $footer_message);
+  // Only parse the footer block if site_footer is set or there are footer blocks.
+  if ($footer_message = variable_get("site_footer", FALSE) || $blocks = theme("blocks", "footer")) {
+    $xtemplate->template->assign("footer_message", $footer_message . $blocks);
     $xtemplate->template->parse("footer.message");
   }
 
