Commit 1f273dac authored by Dries's avatar Dries
Browse files

- Committed stage 1 of the theme system improvements.

  Some TODO's:
   * The sidebars of theme Marvin and theme UnConeD look unstyled.
   * CSS-ify theme UnConeD so we can remove the class around the functions.
   * Rewrite theme_init() not to use a class and simplify theme()
     accordingly.
parent 92995414
Drupal x.x.x, xxxx-xx-xx
------------------------
- usability improvements:
* grouped form elements using <fieldset> and <legend> tags.
* replaced short drop-down menus by radio buttons.
Drupal 4.3.0, 2003-11-01
------------------------
......
......@@ -6,106 +6,111 @@
*
* @package theme system
*/
class BaseTheme {
var $background = "#ffffff";
var $foreground = "#000000";
function system($field) {
$system["name"] = "Basic theme";
$system["author"] = "Drupal";
$system["description"] = "Basic theme. Lynx friendly";
return $system[$field];
}
function header($title = "") {
global $base_url;
$output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
$output .= "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
$output .= "<head><title>". $title ? $title : variable_get(site_name, "drupal") ."</title>";
$output .= theme_head($main);
$output .= "</head><body style=\"background-color: $this->background; color: $this->foreground;\"". theme_onload_attribute(). "\">";
$output .= "<table border=\"0\" cellspacing=\"4\" cellpadding=\"4\"><tr><td style=\"vertical-align: top; width: 170px;\">";
function theme_help($section) {
print $output;
$this->box(t("Navigation"), @implode("<br />", link_page())); theme_blocks("all", $this);
print "</td><td style=\"vertical-align: top;\">";
$ouptout = "";
switch ($section) {
case 'admin/system/themes#description':
$output = t("The base theme");
break;
}
function links($links, $delimiter = " | ") {
return implode($delimiter, $links);
}
return $output;
}
function image($name) {
return "misc/$name";
}
class BaseTheme {
}
function breadcrumb($breadcrumb) {
print "<div class=\"breadcrumb\">". implode($breadcrumb, " &raquo; ") ."</div>";
}
function theme_header($title = "") {
global $base_url;
function node($node, $main) {
if (module_exist("taxonomy")) {
$terms = taxonomy_link("taxonomy terms", $node);
}
$output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
$output .= "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
$output .= "<head><title>". $title ? $title : variable_get(site_name, "drupal") ."</title>";
$output .= theme_head($main);
$output .= "</head><body style=\"background-color: #fff; color: #000;\"". theme_onload_attribute(). "\">";
$output .= "<table border=\"0\" cellspacing=\"4\" cellpadding=\"4\"><tr><td style=\"vertical-align: top; width: 170px;\">";
print $output;
theme("box", t("Navigation"), @implode("<br />", link_page()));
theme_blocks("all", $this);
print "</td><td style=\"vertical-align: top;\">";
}
$output = "<h2>$node->title</h2> by ". format_name($node);
function theme_links($links, $delimiter = " | ") {
return implode($delimiter, $links);
}
if (count($terms)) {
$output .= "<small>(". $this->links($terms) .")</small><br />";
}
function theme_image($name) {
return "misc/$name";
}
if ($main && $node->teaser) {
$output .= $node->teaser;
}
else {
$output .= $node->body;
}
if ($links = link_node($node, $main)) {
$output .= "<br />[ ". $this->links($links) ." ]";
}
$output .= "<hr />";
function theme_breadcrumb($breadcrumb) {
print "<div class=\"breadcrumb\">". implode($breadcrumb, " &raquo; ") ."</div>";
}
print $output;
function theme_node($node, $main) {
if (module_exist("taxonomy")) {
$terms = taxonomy_link("taxonomy terms", $node);
}
function box($subject, $content, $region = "main") {
$output = "<h2>$subject</h2><p>$content</p>";
print $output;
$output = "<h2>$node->title</h2> by ". format_name($node);
if (count($terms)) {
$output .= " <small>(". theme("links", $terms) .")</small><br />";
}
/**
* Render a block.
*
* You can style your blocks by defining .block (all blocks),
* .block-<i>module</i> (all blocks of module <i>module</i>),
* and \#block-<i>module</i>-<i>delta</i> (specific block of
* module <i>module</i> with delta <i>delta</i>) in your
* theme's CSS.
*
* @param $block object "indexed with" fields from database
* table 'blocks' ($block->module, $block->delta, $block->region,
* ...) and fields returned by <i>module</i>_block("view")
* ($block->subject, $block->content, ...).
*/
function block($block) {
$output = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">";
$output .= " <h3>$block->subject</h3>";
$output .= " <div class=\"content\">$block->content</div>";
$output .= "</div>";
print $output;
if ($main && $node->teaser) {
$output .= $node->teaser;
}
else {
$output .= $node->body;
}
function footer() {
$output = "</td></tr></table>";
$output .= theme_footer();
$output .= "</body></html>";
print $output;
if ($links = link_node($node, $main)) {
$output .= "<br />[ ". theme("links", $links) ." ]";
}
$output .= "<hr />";
print $output;
}
function theme_box($subject, $content, $region = "main") {
$output = "<h2>$subject</h2><p>$content</p>";
print $output;
}
/**
* Render a block.
*
* You can style your blocks by defining .block (all blocks),
* .block-<i>module</i> (all blocks of module <i>module</i>),
* and \#block-<i>module</i>-<i>delta</i> (specific block of
* module <i>module</i> with delta <i>delta</i>) in your
* theme's CSS.
*
* @param $block object "indexed with" fields from database
* table 'blocks' ($block->module, $block->delta, $block->region,
* ...) and fields returned by <i>module</i>_block("view")
* ($block->subject, $block->content, ...).
*/
function theme_block($block) {
$output = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">";
$output .= " <h3>$block->subject</h3>";
$output .= " <div class=\"content\">$block->content</div>";
$output .= "</div>";
print $output;
}
} // End of BaseTheme class //
function theme_footer() {
$output = "</td></tr></table>";
$output .= theme_footer();
$output .= "</body></html>";
print $output;
}
/**
* Return a marker. Used to indicate new comments or required form
......@@ -178,7 +183,7 @@ function theme_head($main = 0) {
* Execute hook _footer() which is run at the end of the page right
* before the </body> tag
*/
function theme_footer($main = 0) {
function theme_closure($main = 0) {
$footer = module_invoke_all("footer", $main);
return implode($footer, "\n");
}
......@@ -199,6 +204,8 @@ function theme_init() {
$instance =& new BaseTheme;
}
$instance->theme = $name;
return $instance;
}
......@@ -224,15 +231,26 @@ function theme_blocks($region) {
function theme() {
global $theme;
$args = func_get_args();
$function = array_shift($args);
if (method_exists($theme, $function)) {
$name = $theme->theme;
if (function_exists($name ."_". $function)) {
return call_user_func_array($name ."_". $function, $args);
}
else if (method_exists($theme, $function)) {
return call_user_method_array($function, $theme, $args);
// temporary fall-back; can be removed as soon the $theme-object is no more
}
else if (function_exists("theme_". $function)) {
return call_user_func_array("theme_". $function, $args);
}
else {
return call_user_func_array($function, $args);
// temporary fall-back; can be removed as soon the $theme-object is no more
}
}
......
<?php
// $Id$
class Theme_marvin extends BaseTheme {
function system($field) {
$system["name"] = "Marvin";
$system["author"] = "Dries";
$system["description"] = "Internet explorer, Netscape, Opera";
function marvin_help($section) {
return $system[$field];
}
$ouptout = "";
switch ($section) {
case 'admin/system/themes#description':
$output = t("A PHP theme");
break;
}
return $output;
}
class Theme_marvin extends BaseTheme {
function header($title = "") {
?>
......@@ -166,7 +172,7 @@ function footer() {
</td>
</tr>
</table>
<?php print theme_footer(); ?>
<?php print theme_closure(); ?>
</body>
</html>
<?php
......
<?php
// $Id$
function unconed_help($section) {
$ouptout = "";
switch ($section) {
case 'admin/system/themes#description':
$output = t("A PHP theme");
break;
}
return $output;
}
class Theme_unconed extends BaseTheme {
var $foreground = "#000000";
var $background = "#ffffff";
......@@ -57,7 +70,7 @@ function header($title = "") {
</tr>
<tr>
<td colspan="2" style="text-align: center;">
<table border="0" cellspacing="0" cellpadding="0" style="background-color: <?php echo $this->brcolor1; ?>; width: 100%;"><tr><td style="text-align: center;"><table border="0" cellspacing="1" cellpadding="4" style="width: 100%;"><tr><td style="background-color: <?php echo $this->bgcolor2; ?>; text-align: center;"><?php print $this->links(link_page()); ?></td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" style="background-color: <?php echo $this->brcolor1; ?>; width: 100%;"><tr><td style="text-align: center;"><table border="0" cellspacing="1" cellpadding="4" style="width: 100%;"><tr><td style="background-color: <?php echo $this->bgcolor2; ?>; text-align: center;"><?php print theme_links(link_page()); ?></td></tr></table></td></tr></table>
</td>
</tr>
<tr><td colspan="2"><?php
......@@ -86,7 +99,7 @@ function node($node, $main = 0) {
if (module_exist("taxonomy")) {
$terms = taxonomy_link("taxonomy terms", $node);
}
$taxo = $this->links($terms);
$taxo = theme_links($terms);
print "<td style=\"background-color: $this->bgcolor2; width: 70%;\"><small>" . t("Submitted by %a on %b", array("%a" => format_name($node), "%b" => format_date($node->created, "large"))) . "</small></td><td style=\"background-color: $this->bgcolor2; width: 30%; text-align: center;\"><b>". $taxo ."</b>";
?>
</td>
......@@ -105,7 +118,7 @@ function node($node, $main = 0) {
</tr>
<?php
if ($links = link_node($node, $main)) {
echo "<tr style=\"background-color: ". $this->bgcolor3 .";\"><td style=\"background-color: ". $this->bgcolor3 ."; text-align: right;\" colspan=\"2\">[ ". $this->links($links) ." ]</td></tr>";
echo "<tr style=\"background-color: ". $this->bgcolor3 .";\"><td style=\"background-color: ". $this->bgcolor3 ."; text-align: right;\" colspan=\"2\">[ ". theme_links($links) ." ]</td></tr>";
}
?>
</table></td></tr></table><br />
......@@ -192,13 +205,13 @@ function footer() {
?></td></tr>
<tr>
<td colspan="2">
<table border="0" cellspacing="0" cellpadding="0" style="background-color: <?php echo $this->brcolor1; ?>; width: 100%;"><tr><td style="text-align: center;"><table border="0" cellspacing="1" cellpadding="4" style="width: 100%;"><tr><td style="background-color: <?php echo $this->bgcolor2; ?>; text-align: center;"><?php print $this->links(link_page()); ?></td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" style="background-color: <?php echo $this->brcolor1; ?>; width: 100%;"><tr><td style="text-align: center;"><table border="0" cellspacing="1" cellpadding="4" style="width: 100%;"><tr><td style="background-color: <?php echo $this->bgcolor2; ?>; text-align: center;"><?php print theme_links(link_page()); ?></td></tr></table></td></tr></table>
</td>
</tr>
</table>
</td><td style="background-color: <?php print $this->clc0; ?>;"><img src="<?php print $this->path; ?>/images/null.gif" width="4" alt="" title="" /></td><td style="background-color: <?php print $this->cl00; ?>;"><img src="<?php print $this->path; ?>/images/null.gif" width="10" alt="" title="" /></td></tr>
</table>
<?php print theme_footer(); ?>
<?php print theme_closure(); ?>
</body>
</html>
<?php
......
<?php
// $Id$
class Theme_xtemplate extends BaseTheme {
}
if (!class_exists("XTemplate")) {
include_once("themes/xtemplate/xtemplate.inc");
}
$GLOBALS["xtemplate"]->sidebar = variable_get("xtemplate_sidebar", "right");
$GLOBALS["xtemplate"]->template = new XTemplate("themes/xtemplate/xtemplate.xtmpl");
$GLOBALS["xtemplate"]->template->SetNullBlock(" "); // "" doesnt work!
function xtemplate_settings() {
$output = form_select(t("Sidebar placement"), "xtemplate_sidebar", variable_get("xtemplate_sidebar", "left"), array("none" => t("No sidebars"), "left" => t("Sidebar on the left"), "right" => t("Sidebar on the right"), "both" => t("Sidebar on the left and the right")));
$output = form_radios(t("Sidebar placement"), "xtemplate_sidebar", variable_get("xtemplate_sidebar", "left"), array("none" => t("No sidebars"), "left" => t("Sidebar on the left"), "right" => t("Sidebar on the right"), "both" => t("Sidebar on the left and the right")));
$output .= form_textarea(t("Message on front page"), "xtemplate_message", variable_get("xtemplate_message", "edit message"), 70, 6, t("This text will be displayed on the front page. It can be used to display a mission statement, announcement or site description.."));
$output .= form_textfield(t("Stylesheet URL"), "xtemplate_stylesheet", variable_get("xtemplate_stylesheet", "themes/xtemplate/xtemplate.css"), 100, 300, t("The URL for your theme's cascading stylesheet."));
$output .= form_textarea(t("Logo"), "xtemplate_logo", variable_get("xtemplate_logo", "<img src=\"themes/xtemplate/images/druplicon.gif\" alt=\"Druplicon\" />"), 70, 4, t("The HTML code for displaying the logo."));
$output .= form_textarea(t("Primary links"), "xtemplate_primary_links", variable_get("xtemplate_primary_links", l("edit primary links", "admin/system/themes/xtemplate")), 70, 8, t("The HTML code for the primary links."));
$output .= form_textarea(t("Secondary links"), "xtemplate_secondary_links", variable_get("xtemplate_secondary_links", l("edit secondary links", "admin/system/themes/xtemplate")), 70, 8, t("The HTML code for the secondary links."));
$output .= form_select(t("Search box"), "xtemplate_search_box", variable_get("xtemplate_search_box", 0), array(t("Disabled"), t("Enabled")), t("Show a search box in the upper right corner."));
$output .= form_radios(t("Search box"), "xtemplate_search_box", variable_get("xtemplate_search_box", 0), array(t("Disabled"), t("Enabled")), t("Show a search box in the upper right corner."));
return $output;
}
class Theme_xtemplate extends BaseTheme {
function xtemplate_help($section) {
function system($field) {
$system["name"] = "xtemplate";
$system["description"] = "a template driven theme";
$ouptout = "";
return $system[$field];
switch ($section) {
case 'admin/system/themes#description':
$output = t("A template driven theme");
break;
}
function Theme_xtemplate() {
if (!class_exists("XTemplate")) {
include_once("themes/xtemplate/xtemplate.inc");
}
return $output;
}
$this->sidebar = variable_get("xtemplate_sidebar", "right");
function xtemplate_node($node, $main = 0) {
$this->template = new XTemplate("themes/xtemplate/xtemplate.xtmpl");
$this->template->SetNullBlock(" "); // "" doesnt work!
}
$xtemplate = $GLOBALS["xtemplate"];
function node($node, $main = 0) {
$xtemplate->template->assign(array(
"link" => url("node/view/$node->nid"),
"title" => ucfirst($node->title),
"author" => format_name($node),
"date" => format_date($node->created),
"content" => ($main && $node->teaser) ? $node->teaser : $node->body));
$this->template->assign(array(
"link" => url("node/view/$node->nid"),
"title" => ucfirst($node->title),
"author" => format_name($node),
"date" => format_date($node->created),
"content" => ($main && $node->teaser) ? $node->teaser : $node->body));
if (module_exist("taxonomy") && ($taxonomy = taxonomy_link("taxonomy terms", $node))) {
$xtemplate->template->assign("taxonomy", theme_links($taxonomy));
}
else {
$xtemplate->template->assign("taxonomy", "");
}
if ($links = link_node($node, $main)) {
$xtemplate->template->assign("links", theme_links($links));
}
else {
$xtemplate->template->assign("links", "");
}
if (module_exist("taxonomy") && ($taxonomy = taxonomy_link("taxonomy terms", $node))) {
$this->template->assign("taxonomy", $this->links($taxonomy));
}
else {
$this->template->assign("taxonomy", "");
}
$xtemplate->template->parse("node");
print $xtemplate->template->text("node");
$xtemplate->template->reset("node");
}
if ($links = link_node($node, $main)) {
$this->template->assign("links", $this->links($links));
}
else {
$this->template->assign("links", "");
}
function xtemplate_comment($comment, $link = 0) {
$this->template->parse("node");
print $this->template->text("node");
$this->template->reset("node");
}
$xtemplate = $GLOBALS["xtemplate"];
function comment($comment, $link = 0) {
$this->template->assign(array (
$xtemplate->template->assign(array (
"title" => ucfirst($comment->subject),
"author" => format_name($comment),
"date" => format_date($comment->timestamp),
"content" => $comment->comment,
"links" => $link));
if ($comment->new) {
$this->template->parse("comment_new");
print $this->template->text("comment_new");
$this->template->reset("comment_new");
}
else {
$this->template->parse("comment_old");
print $this->template->text("comment_old");
$this->template->reset("comment_old");
}
}
function header($title = "") {
$this->template->assign(array(
"title" => ($title ? $title." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")),
"head" => theme_head(),
"stylesheet" => variable_get("xtemplate_stylesheet", "themes/xtemplate/xtemplate.css"),
"onload_attributes" => theme_onload_attribute(),
"logo" => variable_get("xtemplate_logo", "<img src=\"themes/xtemplate/images/druplicon.gif\" />"),
"primary_links" => variable_get("xtemplate_primary_links", l("edit primary links", "admin/system/themes/xtemplate")),
"secondary_links" => variable_get("xtemplate_secondary_links", l("edit secondary links", "admin/system/themes/xtemplate"))
));
if (variable_get("xtemplate_search_box", 1)) {
$this->template->assign(array(
//"search" => search_form(),
"search_url" => url("search"),
"search_button_text" => t("Search")
));
$this->template->parse("header.search_box");
}
// only parse the message block if we are on the frontpage ...
if ($_GET["q"] == variable_get("site_frontpage", "node") && ($message = variable_get("xtemplate_message", "edit message"))) {
$this->template->assign("header_message", $message);
$this->template->parse("header.message");
}
ob_start();
if ($this->sidebar == "left") {
theme_blocks("all");
}
else if ($this->sidebar == "both") {
theme_blocks("left");
}
if ($blocks = ob_get_contents()) {
$this->template->assign("blocks", $blocks);
$this->template->parse("header.blocks");
}
ob_end_clean();
$this->template->parse("header");
print $this->template->text("header");
}
function block(&$block) {
// create template variables for all block variables (module, delta, region, subject, content, ...)
foreach ($block as $key => $value) {
$this->template->assign($key, $value);
}
$this->template->parse("block");
print $this->template->text("block");
$this->template->reset("block");
}
function box($title, $content, $region = "main") {
$this->template->assign(array(
"subject" => $title,
"content" => $content));
$this->template->parse("box");
print $this->template->text("box");
$this->template->reset("box");
}
function footer() {
ob_start();
if ($this->sidebar == "right") {
theme_blocks("all");
}
else if ($this->sidebar == "both") {
theme_blocks("right");
}
if ($blocks = ob_get_contents()) {
$this->template->assign("blocks", $blocks);
$this->template->parse("footer.blocks");
}
ob_end_clean();
// only parse the footer block if site_footer is set
if ($footer_message = variable_get("site_footer", FALSE)) {
$this->template->assign("footer_message", $footer_message);
$this->template->parse("footer.message");
}
$this->template->assign("footer", theme_footer());
$this->template->parse("footer");
print $this->template->text("footer");
if ($comment->new) {
$xtemplate->template->parse("comment_new");
print $xtemplate->template->text("comment_new");
$xtemplate->template->reset("comment_new");
}
else {
$xtemplate->template->parse("comment_old");
print $xtemplate->template->text("comment_old");
$xtemplate->template->reset("comment_old");
}
}
function xtemplate_header($title = "") {
$xtemplate = $GLOBALS["xtemplate"];
$xtemplate->template->assign(array(
"title" => ($title ? $title." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")),
"head" => theme_head(),
"stylesheet" => variable_get("xtemplate_stylesheet", "themes/xtemplate/xtemplate.css"),
"onload_attributes" => theme_onload_attribute(),
"logo" => variable_get("xtemplate_logo", "<img src=\"themes/xtemplate/images/druplicon.gif\" />"),
"primary_links" => variable_get("xtemplate_primary_links", l("edit primary links", "admin/system/themes/xtemplate")),
"secondary_links" => variable_get("xtemplate_secondary_links", l("edit secondary links", "admin/system/themes/xtemplate"))
));
if (variable_get("xtemplate_search_box", 1)) {
$xtemplate->template->assign(array(
//"search" => search_form(),
"search_url" => url("search"),
"search_button_text" => t("Search")
));
$xtemplate->template->parse("header.search_box");
}
// only parse the message block if we are on the frontpage ...
if ($_GET["q"] == variable_get("site_frontpage", "node") && ($message = variable_get("xtemplate_message", "edit message"))) {
$xtemplate->template->assign("header_message", $message);
$xtemplate->template->parse("header.message");