Commit 6ea5c56d authored by Dries's avatar Dries

- Theme system changes.  Please consult http://drupal.org/node/view/9576 for details.
parent 6e145281
......@@ -3,7 +3,7 @@
#
# Protect files and directories from prying eyes:
<Files ~ "(\.(conf|inc|module|pl|sh|sql|theme)|Entries|Repositories|Root|scripts|updates)$">
<Files ~ "(\.(conf|inc|module|pl|sh|sql|theme|engine|xtmpl)|Entries|Repositories|Root|scripts|updates)$">
order deny,allow
deny from all
</Files>
......
......@@ -732,7 +732,8 @@ INSERT INTO system VALUES ('modules/node.module','node','module','',1,0,0);
INSERT INTO system VALUES ('modules/page.module','page','module','',1,0,0);
INSERT INTO system VALUES ('modules/story.module','story','module','',1,0,0);
INSERT INTO system VALUES ('modules/taxonomy.module','taxonomy','module','',1,0,0);
INSERT INTO system VALUES ('themes/xtemplate/xtemplate.theme','xtemplate','theme','Internet explorer, Netscape, Opera',1,0,0);
INSERT INTO system VALUES ('themes/bluemarine/xtemplate.xtmpl','bluemarine','theme','themes/engines/xtemplate/xtemplate.engine',1,0,0);
INSERT INTO system VALUES ('themes/engines/xtemplate/xtemplate.engine','xtemplate','theme_engine','',1,0,0);
INSERT INTO users (uid, name, mail) VALUES ('0', '', '');
INSERT INTO users_roles (uid, rid) VALUES (0, 1);
......@@ -743,7 +744,7 @@ INSERT INTO role (rid, name) VALUES (2, 'authenticated user');
INSERT INTO permission VALUES (2,'access comments, access content, post comments, post comments without approval',0);
REPLACE variable SET name='update_start', value='s:10:"2004-02-21;"';
REPLACE variable SET name='theme_default', value='s:9:"xtemplate";';
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';
......
......@@ -717,10 +717,11 @@ INSERT INTO system VALUES ('modules/node.module','node','module','',1,0,0);
INSERT INTO system VALUES ('modules/page.module','page','module','',1,0,0);
INSERT INTO system VALUES ('modules/story.module','story','module','',1,0,0);
INSERT INTO system VALUES ('modules/taxonomy.module','taxonomy','module','',1,0,0);
INSERT INTO system VALUES ('themes/xtemplate/xtemplate.theme','xtemplate','theme','Internet explorer, Netscape, Opera',1,0,0);
INSERT INTO system VALUES ('themes/bluemarine/xtemplate.xtmpl','bluemarine','theme','themes/engines/xtemplate/xtemplate.engine',1,0,0);
INSERT INTO system VALUES ('themes/engines/xtemplate/xtemplate.engine','xtemplate','theme_engine','',1,0,0);
INSERT INTO variable(name,value) VALUES('update_start', 's:10:"2004-02-21";');
INSERT INTO variable(name,value) VALUES('theme_default','s:9:"xtemplate";');
INSERT INTO variable(name,value) VALUES('theme_default','s:10:"bluemarine";');
INSERT INTO users(uid,name,mail) VALUES(0,'','');
INSERT INTO users_roles(uid,rid) VALUES(0, 1);
......
......@@ -74,7 +74,8 @@
"2004-08-10" => "update_100",
"2004-08-11" => "update_101",
"2004-08-12" => "update_102",
"2004-08-17" => "update_103"
"2004-08-17" => "update_103",
"2004-08-19" => "update_104"
);
function update_32() {
......@@ -1522,6 +1523,34 @@ function update_103() {
return $ret;
}
function update_104() {
$ret = array();
if (variable_get('theme_default', 'xtemplate') == 'chameleon') {
$ret[] = update_sql("DELETE FROM {system} WHERE name = 'chameleon'");
$ret[] = update_sql("INSERT INTO system VALUES ('themes/chameleon/chameleon.theme','chameleon','theme','',1,0,0)");
$ret[] = update_sql("INSERT INTO system VALUES ('themes/chameleon/marvin/style.css','marvin','theme','themes/chameleon/chameleon.theme',1,0,0)");
if (variable_get("chameleon_stylesheet", "themes/chameleon/pure/chameleon.css") == "themes/chameleon/marvin/chameleon.css") {
variable_set('theme_default', 'chameleon/marvin');
}
else {
variable_set('theme_default', 'chameleon');
}
}
elseif (variable_get('theme_default', 'xtemplate') == 'xtemplate') {
$ret[] = update_sql("DELETE FROM {system} WHERE name = 'xtemplate'");
$ret[] = update_sql("INSERT INTO system VALUES ('themes/bluemarine/bluemarine.theme','bluemarine','theme','themes/engines/xtemplate/xtemplate.engine',1,0,0)");
$ret[] = update_sql("INSERT INTO system VALUES ('themes/pushbutton/pushbutton.theme','pushbutton','theme','themes/engines/xtemplate/xtemplate.engine',1,0,0)");
$ret[] = update_sql("INSERT INTO system VALUES ('themes/engines/xtemplate/xtemplate.engine','xtemplate','theme_engine','',1,0,0)");
if (variable_get('xtemplate_template', 'default') == 'pushbutton') {
variable_set('theme_default', 'pushbutton');
}
else {
variable_set('theme_default', 'bluemarine');
}
}
return $ret;
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);
......
......@@ -87,9 +87,7 @@ function drupal_get_html_head() {
$output = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
$output .= "<base href=\"$base_url/\" />\n";
$output .= "<style type=\"text/css\" media=\"all\">\n";
$output .= "@import url(misc/drupal.css);\n";
$output .= "</style>\n";
$output .= theme('stylesheet_import', 'misc/drupal.css');
return $output . drupal_set_html_head();
}
......
......@@ -437,7 +437,7 @@ function file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $ca
}
elseif (ereg($mask, $file)) {
$name = basename($file);
$files["$dir/$file"]->path = "$dir/$file";
$files["$dir/$file"]->filename = "$dir/$file";
$files["$dir/$file"]->name = substr($name, 0, strrpos($name, '.'));
if ($callback) {
$callback("$dir/$file");
......
......@@ -33,16 +33,52 @@ function theme_help($section) {
* The name of the currently selected theme.
*/
function init_theme() {
global $user;
global $user, $custom_theme, $theme_engine, $theme_key;
$themes = list_themes();
// Only select the user selected theme if it is available in the
// list of enabled themes.
$theme = $user->theme && $themes[$user->theme] ? $user->theme : variable_get('theme_default', 0);
$theme = $user->theme && $themes[$user->theme] ? $user->theme : variable_get('theme_default', 'bluemarine');
include_once($themes[$theme]->filename);
// Allow modules to override the present theme... only select custom theme
// if it is available in the list of enabled themes.
$theme = $custom_theme && $themes[$custom_theme] ? $custom_theme : $theme;
// Store the identifier for retrieving theme settings with.
$theme_key = $theme;
// If we're using a style, load its appropriate theme,
// which is stored in the style's description field.
// Also load the stylesheet using drupal_set_html_head().
// Otherwise, load the theme.
if (strpos($themes[$theme]->filename, '.css')) {
// File is a style; put it in the html_head buffer
// Set theme to its template/theme
drupal_set_html_head(theme('stylesheet_import', $themes[$theme]->filename));
$theme = $themes[$theme]->description;
}
else {
// File is a template/theme
// Put the css with the same name in html_head, if it exists
if (file_exists($stylesheet = dirname($themes[$theme]->filename) .'/style.css')) {
drupal_set_html_head(theme('stylesheet_import', $stylesheet));
}
}
if (strpos($themes[$theme]->filename, '.theme')) {
// file is a theme; include it
include_once($themes[$theme]->filename);
}
elseif (strpos($themes[$theme]->description, '.engine')) {
// file is a template; include its engine
include_once($themes[$theme]->description);
$theme_engine = basename($themes[$theme]->description, '.engine');
if (function_exists($theme_engine .'_init')) {
call_user_func($theme_engine .'_init', $themes[$theme]);
}
}
return $theme;
}
......@@ -74,13 +110,42 @@ function list_themes($refresh = FALSE) {
return $list;
}
/**
* Provides a list of currently available theme engines
*
* @param $refresh
* Whether to reload the list of themes from the database.
* @return
* An array of the currently available theme engines.
*/
function list_theme_engines($refresh = FALSE) {
static $list;
if ($refresh) {
unset($list);
}
if (!$list) {
$list = array();
$result = db_query("SELECT * FROM {system} where type = 'theme_engine' AND status = '1' ORDER BY name");
while ($engine = db_fetch_object($result)) {
if (file_exists($engine->filename)) {
$list[$engine->name] = $engine;
}
}
}
return $list;
}
/**
* Generate the themed representation of a Drupal object.
*
* All requests for themed functions must go through this function. It examines
* the request and routes it to the appropriate theme function. If the current
* theme does not implement the requested function, then the base theme function
* is called.
* theme does not implement the requested function, then the current theme
* engine is checked. If neither the engine nor theme implement the requested
* function, then the base theme function is called.
*
* For example, to retrieve the HTML that is output by theme_page($output), a
* module should call theme('page', $output).
......@@ -94,14 +159,21 @@ function list_themes($refresh = FALSE) {
*/
function theme() {
global $theme;
global $theme_engine;
$args = func_get_args();
$function = array_shift($args);
if (($theme != '') && (function_exists($theme .'_'. $function))) {
if (($theme != '') && function_exists($theme .'_'. $function)) {
// call theme function
return call_user_func_array($theme .'_'. $function, $args);
}
elseif (($theme != '') && isset($theme_engine) && function_exists($theme_engine .'_'. $function)) {
// call engine function
return call_user_func_array($theme_engine .'_'. $function, $args);
}
elseif (function_exists('theme_'. $function)){
// call Drupal function
return call_user_func_array('theme_'. $function, $args);
}
}
......@@ -117,6 +189,113 @@ function path_to_theme() {
return dirname($themes[$theme]->filename);
}
/**
* Retrieve an associative array containing the settings for a theme.
*
* The final settings are arrived at by merging the default settings,
* the site-wide settings, and the settings defined for the specific theme.
* If no $key was specified, only the site-wide theme defaults are retrieved.
*
* The default values for each of settings are also defined in this function.
* To add new settings, add their default values here, and then add form elements
* to system_theme_settings() in system.module.
*
* @param $key
* The template/style value for a given theme.
*
* @return
* An associative array containing theme settings.
*/
function drupal_get_theme_settings($key = NULL) {
$defaults = array(
'primary_links' => '',
'secondary_links' => l('edit secondary links', 'admin/themes/settings'),
'mission' => '',
'default_logo' => 1,
'logo_path' => '',
'toggle_logo' => 1,
'toggle_name' => 1,
'toggle_search' => 1,
'toggle_slogan' => 0,
'toggle_mission' => 1,
'toggle_primary_links' => 1,
'toggle_secondary_links' => 1,
'toggle_node_user_picture' => 0,
'toggle_comment_user_picture' => 0,
);
foreach (node_list() as $type) {
$defaults['toggle_node_info_' . $type] = 1;
}
$settings = array_merge($defaults, variable_get('theme_settings', array()));
if ($key) {
$settings = array_merge($settings, variable_get(str_replace('/', '_', 'theme_'. $key .'_settings'), array()));
}
return $settings;
}
/**
* Retrieve a setting for the current theme.
* This function is designed for use from within themes & engines
* to determine theme settings made in the admin interface.
*
* Caches values for speed (use $refresh = TRUE to refresh cache)
*
* @param $setting_name
* The name of the setting to be retrieved.
*
* @param $refresh
* Whether to reload the cache of settings.
*
* @return
* The value of the requested setting, NULL if the setting does not exist.
*/
function drupal_get_theme_setting($setting_name, $refresh = FALSE) {
global $theme_key;
static $settings;
if (empty($settings) || $refresh) {
$settings = drupal_get_theme_settings($theme_key);
$themes = list_themes();
$theme_object = $themes[$theme_key];
if ($settings['mission'] == '') {
$settings['mission'] = variable_get('site_mission', '');
}
if (!$settings['toggle_mission']) {
$settings['mission'] = '';
}
if ($settings['toggle_logo']) {
if ($settings['default_logo']) {
$settings['logo'] = dirname($theme_object->filename) .'/logo.png';
}
elseif ($settings['logo_path']) {
$settings['logo'] = $settings['logo_path'];
}
}
if ($settings['toggle_primary_links']) {
if (!$settings['primary_links']) {
$settings['primary_links'] = theme('links', link_page());
}
}
else {
$settings['primary_links'] = '';
}
if (!$settings['toggle_secondary_links']) {
$settings['secondary_links'] = '';
}
}
return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
}
/**
* @defgroup themeable Themeable functions
* @{
......@@ -476,6 +655,22 @@ function theme_mark() {
return '<span class="marker">*</span>';
}
/**
* Import a stylesheet using @import.
*
* @param $stylesheet
* The filename to point the link at.
*
* @param $media
* The media type to specify for the stylesheet
*
* @return
* A string containing the HTML for the stylesheet import.
*/
function theme_stylesheet_import($stylesheet, $media = 'all') {
return '<style type="text/css" media="'. $media .'">@import "'. $stylesheet .'";</style>';
}
/**
* Return a themed list of items.
*
......
......@@ -379,6 +379,11 @@ tr.light .form-item, tr.dark .form-item {
.node-form .poll-form fieldset {
display: block;
}
img.screenshot {
border: 1px solid #808080;
display: block;
margin: 2px;
}
#tracker td.replies {
text-align: center;
}
......
This diff is collapsed.
This diff is collapsed.
<!-- BEGIN: header --><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>{head_title}</title>
{head}
<link type="text/css" rel="stylesheet" href="{directory}/xtemplate.css" />
</head>
<body{onload_attributes}>
<table border="0" cellpadding="0" cellspacing="0" id="header">
<tr>
<td id="logo">
<a href="./">{logo}</a>
</td>
<td id="menu">
<div id="secondary">{secondary_links}</div>
<div id="primary">{primary_links}</div>
<!-- BEGIN: search_box -->
<form action="{search_url}" method="post">
<div id="search">
<input class="form-text" type="text" size="15" value="" name="keys" alt="{search_description}" />
<input class="form-submit" type="submit" value="{search_button_text}" />
</div>
</form>
<!-- END: search_box -->
</td>
</tr>
</table>
<table border="0" cellpadding="0" cellspacing="0" id="content">
<tr>
<!-- BEGIN: blocks -->
<td id="sidebar-left">
{blocks}
</td>
<!-- END: blocks -->
<td valign="top">
<!-- BEGIN: mission -->
<div id="mission">{mission}</div>
<!-- END: mission -->
<div id="main">
<!-- BEGIN: title -->
{breadcrumb}
<h1 class="title">{title}</h1>
<!-- BEGIN: tabs -->
<div class="tabs">{tabs}</div>
<!-- END: tabs -->
<!-- END: title -->
<!-- BEGIN: help -->
<div id="help">{help}</div>
<!-- END: help -->
<!-- BEGIN: message -->
{message}
<!-- END: message -->
<!-- END: header -->
<!-- BEGIN: node -->
<div class="node {sticky}">
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<!-- BEGIN: title -->
<h2 class="title"><a href="{link}">{title}</a></h2>
<!-- END: title -->
<span class="submitted">{submitted}</span>
<!-- BEGIN: taxonomy -->
<span class="taxonomy">{taxonomy}</span>
<!-- END: taxonomy -->
<div class="content">{content}</div>
<!-- BEGIN: links -->
<div class="links">&raquo; {links}</div>
<!-- END: links -->
</div>
<!-- END: node -->
<!-- BEGIN: comment -->
<div class="comment">
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<h3 class="title">{title}</h3><!-- BEGIN: new --><span class="new">{new}</span><!-- END: new -->
<div class="submitted">{submitted}</div>
<div class="content">{content}</div>
<!-- BEGIN: links -->
<div class="links">&raquo; {links}</div>
<!-- END: links -->
</div>
<!-- END: comment -->
<!-- BEGIN: box -->
<div class="box">
<h2 class="title">{title}</h2>
<div class="content">{content}</div>
</div>
<!-- END: box -->
<!-- BEGIN: block -->
<div class="block block-{module}" id="block-{module}-{delta}">
<h2 class="title">{title}</h2>
<div class="content">{content}</div>
</div>
<!-- END: block -->
<!-- BEGIN: footer -->
</div><!-- main -->
</td>
<!-- BEGIN: blocks -->
<td id="sidebar-right">
{blocks}
</td>
<!-- END: blocks -->
</tr>
</table>
<!-- BEGIN: message -->
<div id="footer">
{footer_message}
</div>
<!-- END: message -->
{footer}
</body>
</html>
<!-- END: footer -->
<!-- BEGIN: header --><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>{head_title}</title>
{head}
</head>
<body{onload_attributes}>
<table border="0" cellpadding="0" cellspacing="0" id="header">
<tr>
<td id="logo">
<!-- BEGIN: logo -->
<a href="./" title="Home"><img src="{logo}" alt="Home" border="0" /></a>
<!-- END: logo -->
<!-- BEGIN: site_name -->
<h1 class='site-name'><a href="./" title="Home">{site_name}</a></h1>
<!-- END: site_name -->
<!-- BEGIN: site_slogan -->
<div class='site-slogan'>{site_slogan}</div>
<!-- END: site_slogan -->
</td>
<td id="menu">
<div id="secondary">{secondary_links}</div>
<div id="primary">{primary_links}</div>
<!-- BEGIN: search_box -->
<form action="{search_url}" method="post">
<div id="search">
<input class="form-text" type="text" size="15" value="" name="keys" alt="{search_description}" />
<input class="form-submit" type="submit" value="{search_button_text}" />
</div>
</form>
<!-- END: search_box -->
</td>
</tr>
</table>
<table border="0" cellpadding="0" cellspacing="0" id="content">
<tr>
<!-- BEGIN: blocks -->
<td id="sidebar-left">
{blocks}
</td>
<!-- END: blocks -->
<td valign="top">
<!-- BEGIN: mission -->
<div id="mission">{mission}</div>
<!-- END: mission -->
<div id="main">
<!-- BEGIN: title -->
{breadcrumb}
<h1 class="title">{title}</h1>
<!-- BEGIN: tabs -->
<div class="tabs">{tabs}</div>
<!-- END: tabs -->
<!-- END: title -->
<!-- BEGIN: help -->
<div id="help">{help}</div>
<!-- END: help -->
<!-- BEGIN: message -->
{message}
<!-- END: message -->
<!-- END: header -->
<!-- BEGIN: node -->
<div class="node {sticky}">
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<!-- BEGIN: title -->
<h2 class="title"><a href="{link}">{title}</a></h2>
<!-- END: title -->
<span class="submitted">{submitted}</span>
<!-- BEGIN: taxonomy -->
<span class="taxonomy">{taxonomy}</span>
<!-- END: taxonomy -->
<div class="content">{content}</div>
<!-- BEGIN: links -->
<div class="links">&raquo; {links}</div>
<!-- END: links -->
</div>
<!-- END: node -->
<!-- BEGIN: comment -->
<div class="comment">
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<h3 class="title">{title}</h3><!-- BEGIN: new --><span class="new">{new}</span><!-- END: new -->
<div class="submitted">{submitted}</div>
<div class="content">{content}</div>
<!-- BEGIN: links -->
<div class="links">&raquo; {links}</div>
<!-- END: links -->
</div>
<!-- END: comment -->
<!-- BEGIN: box -->
<div class="box">
<h2 class="title">{title}</h2>
<div class="content">{content}</div>
</div>
<!-- END: box -->
<!-- BEGIN: block -->
<div class="block block-{module}" id="block-{module}-{delta}">
<h2 class="title">{title}</h2>
<div class="content">{content}</div>
</div>
<!-- END: block -->