Commit 26fa7c73 authored by Dries's avatar Dries

- Patch #16216 by nedjo: multiple block regions!

parent 6ef678e4
......@@ -121,9 +121,10 @@ CREATE TABLE authmap (
CREATE TABLE blocks (
module varchar(64) DEFAULT '' NOT NULL,
delta varchar(32) NOT NULL default '0',
theme varchar(255) NOT NULL default '',
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 'left' NOT NULL,
custom tinyint(2) DEFAULT '0' NOT NULL,
throttle tinyint(1) DEFAULT '0' NOT NULL,
visibility tinyint(1) DEFAULT '0' NOT NULL,
......@@ -805,8 +806,8 @@ REPLACE variable SET name='update_start', value='s:10:"2005-03-21";';
REPLACE variable SET name='theme_default', value='s:10:"bluemarine";';
REPLACE blocks SET module = 'user', delta = '0', status = '1';
REPLACE blocks SET module = 'user', delta = '1', status = '1';
REPLACE blocks SET module = 'user', delta = '0', theme = 'bluemarine', status = '1';
REPLACE blocks SET module = 'user', delta = '1', theme = 'bluemarine', status = '1';
INSERT INTO sequences (name, id) VALUES ('menu_mid', 1);
......
......@@ -116,9 +116,10 @@ CREATE TABLE authmap (
CREATE TABLE blocks (
module varchar(64) NOT NULL default '',
delta varchar(32) NOT NULL default '0',
theme varchar(255) NOT NULL default '',
status smallint NOT NULL default '0',
weight smallint NOT NULL default '0',
region smallint NOT NULL default '0',
region varchar(64) DEFAULT 'left' NOT NULL,
custom smallint NOT NULL default '0',
throttle smallint NOT NULL default '0',
visibility smallint NOT NULL default '0',
......@@ -798,8 +799,8 @@ INSERT INTO permission VALUES (1,'access content',0);
INSERT INTO role (name) VALUES ('authenticated user');
INSERT INTO permission VALUES (2,'access comments, access content, post comments, post comments without approval',0);
INSERT INTO blocks(module,delta,status) VALUES('user', 0, 1);
INSERT INTO blocks(module,delta,status) VALUES('user', 1, 1);
INSERT INTO blocks(module,delta,theme,status) VALUES('user', 0, 'bluemarine', 1);
INSERT INTO blocks(module,delta,theme,status) VALUES('user', 1, 'bluemarine', 1);
INSERT INTO node_access VALUES (0, 0, 'all', 1, 0, 0);
......
......@@ -120,7 +120,8 @@
"2005-05-22" => "update_141",
"2005-07-29" => "update_142",
"2005-07-30" => "update_143",
"2005-08-08" => "update_144"
"2005-08-08" => "update_144",
"2005-08-15" => "update_145"
);
function update_32() {
......@@ -2550,6 +2551,28 @@ function update_144() {
return $ret;
}
function update_145() {
$default_theme = variable_get('theme_default', 'bluemarine');
$ret = array();
$ret[] = update_sql("ALTER TABLE {blocks} CHANGE region region varchar(64) default 'left' NOT NULL");
$ret[] = update_sql("ALTER TABLE {blocks} ADD theme varchar(255) NOT NULL default ''");
// Intialize block data for default theme
$ret[] = update_sql("UPDATE {blocks} SET region = 'left' WHERE region = '0'");
$ret[] = update_sql("UPDATE {blocks} SET region = 'right' WHERE region = '1'");
db_query("UPDATE {blocks} SET theme = '%s'", $default_theme);
// Initialze block data for other enabled themes.
$themes = list_themes();
foreach (array_keys($themes) as $theme) {
if (($theme != $default_theme) && $themes[$theme]->status == 1) {
system_initialize_theme_blocks($theme);
}
}
return $ret;
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);
......
......@@ -24,6 +24,50 @@
*/
define('SAVED_DELETED', 3);
/**
* Set content for a specified region.
*
* @param $region
* Page region the content is assigned to.
*
* @param $data
* Content to be set.
*/
function drupal_set_content($region = null, $data = null) {
static $content = array();
if (!is_null($region) && !is_null($data)) {
$content[$region][] = $data;
}
return $content;
}
/**
* Get assigned content.
*
* @param $region
* A specified region to fetch content for. If null, all regions will be returned.
*
* @param $delimiter
* Content to be inserted between exploded array elements.
*/
function drupal_get_content($region = null, $delimiter = ' ') {
$content = drupal_set_content();
if (isset($region)) {
if (is_array($content[$region])) {
return implode ($delimiter, $content[$region]);
}
}
else {
foreach (array_keys($content) as $region) {
if (is_array($content[$region])) {
$content[$region] = implode ($delimiter, $content[$region]);
}
}
return $content;
}
}
/**
* Set the breadcrumb trail for the current page.
*
......
......@@ -798,7 +798,7 @@ function theme_box($title, $content, $region = 'main') {
*
* @param $block
* An object populated with fields from the "blocks" database table
* ($block->module, $block->delta, $block->region, ...) and fields returned by
* ($block->module, $block->delta ...) and fields returned by
* <i>module</i>_block('view') ($block->subject, $block->content, ...).
* @return
* A string containing the block output.
......@@ -945,6 +945,10 @@ function theme_blocks($region) {
$output .= theme('block', $block);
}
}
// Add any content assigned to this region through drupal_set_content() calls.
$output .= drupal_get_content($region);
return $output;
}
......
......@@ -87,6 +87,12 @@ td.menu-disabled {
.breadcrumb {
padding-bottom: .5em
}
.block-region {
background-color: #ffff66;
margin-top: 4px;
margin-bottom: 4px;
padding: 3px;
}
.block ul {
margin: 0;
padding: 0 0 0.25em 1em;
......@@ -343,7 +349,6 @@ tr.odd .form-item, tr.even .form-item {
font-style: normal;
text-decoration: line-through;
}
#node-admin-filter ul {
list-style-type: none;
padding: 0px;
......@@ -618,3 +623,4 @@ html.js fieldset.collapsible legend a {
html.js fieldset.collapsed legend a {
background-image: url('menu-collapsed.png');
}
This diff is collapsed.
This diff is collapsed.
......@@ -18,7 +18,7 @@ function system_help($section) {
case 'admin/settings':
return t('<p>General configuration options for your site. Set up the name of the site, e-mail address used in mail-outs, clean URL options, caching, etc.</p>');
case 'admin/themes':
return t('<p>Select which themes are available to your users and specify the default theme. To configure site-wide display settings, click the "configure" task above. Alternately, to override these settings in a specific theme, click the "configure" link for the corresponding theme.</p>');
return t('<p>Select which themes are available to your users and specify the default theme. To configure site-wide display settings, click the "configure" task above. Alternately, to override these settings in a specific theme, click the "configure" link for the corresponding theme. Note that different themes may have different regions available for rendering content like blocks. If you want consistency in what your users see, you may wish to enable only one theme.</p>');
case 'admin/themes/settings':
return t('<p>These options control the default display settings for your entire site, across all themes. Unless they have been overridden by a specific theme, these settings will be used.</p>');
case 'admin/themes/settings/'. arg(3):
......@@ -328,15 +328,21 @@ function system_theme_data() {
// Add templates to the site listing
foreach (call_user_func($engine->name . '_templates') as $template) {
$template->template = TRUE;
$template->name = basename(dirname($template->filename));
$template->owner = $engine->filename;
$template->prefix = $engine->name;
// do not double-insert templates with theme files in their directory
// Do not double-insert templates with theme files in their directory,
// but do register their engine data.
if (array_key_exists($template->name, $themes)) {
continue;
$themes[$template->name]->template = TRUE;
$themes[$template->name]->owner = $engine->filename;
$themes[$template->name]->prefix = $engine->name;
}
else {
$template->template = TRUE;
$template->name = basename(dirname($template->filename));
$template->owner = $engine->filename;
$template->prefix = $engine->name;
$themes[$template->name] = $template;
}
$themes[$template->name] = $template;
}
}
......@@ -368,6 +374,57 @@ function system_theme_data() {
return $themes;
}
/**
* Get a list of available regions from a specified theme.
*
* @param $theme
* The name of a theme.
* @return
* An array of regions in the form $region['name'] = 'description'.
*/
function system_region_list($theme) {
static $list = array();
if(!array_key_exists($theme, $list)) {
$themes = list_themes();
if (strpos($themes[$theme]->filename, '.css')) {
// File is a style, which can't have its own regions; use its theme instead.
$theme = basename(dirname($themes[$theme]->description));
}
if (file_exists($file = dirname($themes[$theme]->filename) .'/' . $themes[$theme]->name . '.theme')) {
include_once($file);
}
$regions = function_exists($theme . '_regions') ? call_user_func($theme . '_regions') : array();
if (strpos($themes[$theme]->description, '.engine')) {
// File is a template; include its engine's regions.
include_once($themes[$theme]->description);
$theme_engine = basename($themes[$theme]->description, '.engine');
$engine_regions = function_exists($theme_engine . '_regions') ? call_user_func($theme_engine . '_regions') : array();
$regions = array_merge($engine_regions, $regions);
}
$list[$theme] = $regions;
}
return $list[$theme];
}
/**
* Get the name of the default region for a given theme.
*
* @param $theme
* The name of a theme.
* @return
* A string that is the region name.
*/
function system_default_region($theme) {
$regions = array_keys(system_region_list($theme));
return $regions[0];
}
/**
* Returns an array of files objects of the given type from both the
* site-wide directory (i.e. modules/) and site-specific directory
......@@ -506,6 +563,10 @@ function system_listing_save($edit = array()) {
if (($edit['type'] == 'theme') && ($edit['theme_default'] == $name)) {
$status = 1;
}
// If status is being set to 1 from 0, initialize block data for this theme if necessary.
if (($status == 1) && db_num_rows(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s' AND status = 0", $edit['type'], $name))) {
system_initialize_theme_blocks($name);
}
db_query("UPDATE {system} SET status = %d, throttle = %d WHERE type = '%s' AND name = '%s'", $status, $edit['throttle'][$name], $edit['type'], $name);
}
......@@ -520,6 +581,31 @@ function system_listing_save($edit = array()) {
drupal_goto($_GET['q']);
}
}
/**
* Assign an initial, default set of blocks for a theme. This function is called the first
* time a new theme is enabled. The new theme gets a copy of the default theme's blocks,
* with the difference that if a particular region isn't available in the new theme, the block
* is assigned instead to the new theme's default region.
*
* @param $theme
* The name of a theme.
*/
function system_initialize_theme_blocks($theme) {
$default_theme = variable_get('theme_default', 'bluemarine');
$regions = system_region_list($theme);
// Initialize theme's blocks if none already registered.
if (!(db_num_rows(db_query("SELECT module FROM {blocks} WHERE theme = '%s'", $theme)))) {
$result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $default_theme);
while($block = db_fetch_array($result)) {
// If the region isn't supported by the theme, assign the block to the theme's default region.
if (!array_key_exists($block['region'], $regions)) {
$block['region'] = system_default_region($theme);
}
db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d)",
$block['module'], $block['delta'], $theme, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle']);
}
}
}
function system_settings_form($form) {
$form .= form_submit(t('Save configuration'));
......
......@@ -18,7 +18,7 @@ function system_help($section) {
case 'admin/settings':
return t('<p>General configuration options for your site. Set up the name of the site, e-mail address used in mail-outs, clean URL options, caching, etc.</p>');
case 'admin/themes':
return t('<p>Select which themes are available to your users and specify the default theme. To configure site-wide display settings, click the "configure" task above. Alternately, to override these settings in a specific theme, click the "configure" link for the corresponding theme.</p>');
return t('<p>Select which themes are available to your users and specify the default theme. To configure site-wide display settings, click the "configure" task above. Alternately, to override these settings in a specific theme, click the "configure" link for the corresponding theme. Note that different themes may have different regions available for rendering content like blocks. If you want consistency in what your users see, you may wish to enable only one theme.</p>');
case 'admin/themes/settings':
return t('<p>These options control the default display settings for your entire site, across all themes. Unless they have been overridden by a specific theme, these settings will be used.</p>');
case 'admin/themes/settings/'. arg(3):
......@@ -328,15 +328,21 @@ function system_theme_data() {
// Add templates to the site listing
foreach (call_user_func($engine->name . '_templates') as $template) {
$template->template = TRUE;
$template->name = basename(dirname($template->filename));
$template->owner = $engine->filename;
$template->prefix = $engine->name;
// do not double-insert templates with theme files in their directory
// Do not double-insert templates with theme files in their directory,
// but do register their engine data.
if (array_key_exists($template->name, $themes)) {
continue;
$themes[$template->name]->template = TRUE;
$themes[$template->name]->owner = $engine->filename;
$themes[$template->name]->prefix = $engine->name;
}
else {
$template->template = TRUE;
$template->name = basename(dirname($template->filename));
$template->owner = $engine->filename;
$template->prefix = $engine->name;
$themes[$template->name] = $template;
}
$themes[$template->name] = $template;
}
}
......@@ -368,6 +374,57 @@ function system_theme_data() {
return $themes;
}
/**
* Get a list of available regions from a specified theme.
*
* @param $theme
* The name of a theme.
* @return
* An array of regions in the form $region['name'] = 'description'.
*/
function system_region_list($theme) {
static $list = array();
if(!array_key_exists($theme, $list)) {
$themes = list_themes();
if (strpos($themes[$theme]->filename, '.css')) {
// File is a style, which can't have its own regions; use its theme instead.
$theme = basename(dirname($themes[$theme]->description));
}
if (file_exists($file = dirname($themes[$theme]->filename) .'/' . $themes[$theme]->name . '.theme')) {
include_once($file);
}
$regions = function_exists($theme . '_regions') ? call_user_func($theme . '_regions') : array();
if (strpos($themes[$theme]->description, '.engine')) {
// File is a template; include its engine's regions.
include_once($themes[$theme]->description);
$theme_engine = basename($themes[$theme]->description, '.engine');
$engine_regions = function_exists($theme_engine . '_regions') ? call_user_func($theme_engine . '_regions') : array();
$regions = array_merge($engine_regions, $regions);
}
$list[$theme] = $regions;
}
return $list[$theme];
}
/**
* Get the name of the default region for a given theme.
*
* @param $theme
* The name of a theme.
* @return
* A string that is the region name.
*/
function system_default_region($theme) {
$regions = array_keys(system_region_list($theme));
return $regions[0];
}
/**
* Returns an array of files objects of the given type from both the
* site-wide directory (i.e. modules/) and site-specific directory
......@@ -506,6 +563,10 @@ function system_listing_save($edit = array()) {
if (($edit['type'] == 'theme') && ($edit['theme_default'] == $name)) {
$status = 1;
}
// If status is being set to 1 from 0, initialize block data for this theme if necessary.
if (($status == 1) && db_num_rows(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s' AND status = 0", $edit['type'], $name))) {
system_initialize_theme_blocks($name);
}
db_query("UPDATE {system} SET status = %d, throttle = %d WHERE type = '%s' AND name = '%s'", $status, $edit['throttle'][$name], $edit['type'], $name);
}
......@@ -520,6 +581,31 @@ function system_listing_save($edit = array()) {
drupal_goto($_GET['q']);
}
}
/**
* Assign an initial, default set of blocks for a theme. This function is called the first
* time a new theme is enabled. The new theme gets a copy of the default theme's blocks,
* with the difference that if a particular region isn't available in the new theme, the block
* is assigned instead to the new theme's default region.
*
* @param $theme
* The name of a theme.
*/
function system_initialize_theme_blocks($theme) {
$default_theme = variable_get('theme_default', 'bluemarine');
$regions = system_region_list($theme);
// Initialize theme's blocks if none already registered.
if (!(db_num_rows(db_query("SELECT module FROM {blocks} WHERE theme = '%s'", $theme)))) {
$result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $default_theme);
while($block = db_fetch_array($result)) {
// If the region isn't supported by the theme, assign the block to the theme's default region.
if (!array_key_exists($block['region'], $regions)) {
$block['region'] = system_default_region($theme);
}
db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d)",
$block['module'], $block['delta'], $theme, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle']);
}
}
}
function system_settings_form($form) {
$form .= form_submit(t('Save configuration'));
......
......@@ -30,6 +30,9 @@
</form><?php } ?>
</td>
</tr>
<tr>
<td colspan="2"><div><?php print $header ?></div></td>
</tr>
</table>
<table border="0" cellpadding="0" cellspacing="0" id="content">
......
......@@ -16,6 +16,13 @@ function chameleon_features() {
'toggle_secondary_links');
}
function chameleon_regions() {
return array(
'left' => t('left sidebar'),
'right' => t('right sidebar')
);
}
function chameleon_page($content) {
$language = $GLOBALS['locale'];
......
......@@ -17,6 +17,22 @@ function phptemplate_templates($directory = 'themes') {
return system_listing('^page\.tpl\.php$', $directory, 'filename');
}
/**
* Declare the available regions implemented by this engine.
*
* @return
* An array of regions. The first array element will be used as the default region for themes.
*/
function phptemplate_regions() {
return array(
'left' => t('left sidebar'),
'right' => t('right sidebar'),
'content' => t('content'),
'header' => t('header'),
'footer' => t('footer')
);
}
/**
* Execute a template engine call.
*
......@@ -68,6 +84,7 @@ function _phptemplate_callback($hook, $variables = array(), $file = null) {
* A sequential array of variables passed to the theme function.
*/
function _phptemplate_default_variables($hook, $variables) {
global $theme;
static $count = array();
$count[$hook] = is_int($count[$hook]) ? $count[$hook] : 1;
$variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
......@@ -79,7 +96,18 @@ function _phptemplate_default_variables($hook, $variables) {
$variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
$variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
}
elseif ($hook == 'page') {
$regions = system_region_list($theme);
// Load all region content assigned via blocks.
foreach (array_keys($regions) as $region) {
// Skip blocks in this region that have already been loaded.
// This pre-loading is necessary because phptemplate uses variable names different from
// the region names, e.g., 'sidebar_left' instead of 'left'.
if (!in_array($region, array('left', 'right', 'footer'))) {
$variables[$region] .= theme('blocks', $region);
}
}
}
// Tell all templates where they are located.
$variables['directory'] = path_to_theme();
......@@ -128,7 +156,7 @@ function phptemplate_page($content) {
$layout = 'none';
global $sidebar_indicator;
/**
* Sidebar_indicator tells the block counting code to count sidebars seperately.
* Sidebar_indicator tells the block counting code to count sidebars separately.
*/
$sidebar_indicator = 'left';
$sidebar_left = theme('blocks', 'left');
......@@ -158,7 +186,7 @@ function phptemplate_page($content) {
'breadcrumb' => theme('breadcrumb', drupal_get_breadcrumb()),
'closure' => theme('closure'),
'content' => '<!-- begin content -->' . $content . '<!-- end content -->',
'footer_message' => variable_get('site_footer', FALSE),
'footer_message' => variable_get('site_footer', FALSE) . "\n" . theme('blocks', 'footer'),
'head' => drupal_get_html_head(),
'head_title' => implode(' | ', $head_title),
'help' => theme('help'),
......
......@@ -54,7 +54,10 @@
</form>
<?php endif; ?>
</td>
</tr>
</tr>
<tr>
<td colspan="2"><div><?php print $header ?></div></td>
</tr>
</table>
<table id="content" border="0" cellpadding="15" cellspacing="0" width="100%">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment