theme.inc 12.2 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
2
/**
Dries's avatar
 
Dries committed
3
  Theme System - controls the output of Drupal.
4

Dries's avatar
 
Dries committed
5 6
  The theme system allows for nearly all output of the Drupal system to be
  customized by user themes.
Dries's avatar
 
Dries committed
7

Dries's avatar
 
Dries committed
8
  @package theme_system
Dries's avatar
 
Dries committed
9

Dries's avatar
 
Dries committed
10 11 12
  @defgroup theme_system
  @{
**/
Dries's avatar
 
Dries committed
13

Dries's avatar
 
Dries committed
14
/* $Id$ */
Dries's avatar
 
Dries committed
15

Dries's avatar
 
Dries committed
16 17
/**
  Returns the theme header.
Dries's avatar
 
Dries committed
18

Dries's avatar
 
Dries committed
19
  @param $title (optional) override the page title.
Dries's avatar
 
Dries committed
20

Kjartan's avatar
Kjartan committed
21
  @return a string containing the \a header output.
Dries's avatar
 
Dries committed
22
**/
Dries's avatar
 
Dries committed
23 24
function theme_header($title = "") {
  global $base_url;
Dries's avatar
 
Dries committed
25

Dries's avatar
 
Dries committed
26 27
  $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\">";
Dries's avatar
 
Dries committed
28 29
  $output .= "<head>";
  $output .= " <title>". $title ? $title : variable_get(site_name, "drupal") ."</title>";
Dries's avatar
 
Dries committed
30
  $output .= theme_head($main);
Dries's avatar
 
Dries committed
31 32 33 34 35 36
  $output .= " <style type=\"text/css\" media=\"all\">";
  $output .= "  @import url(misc/drupal.css);";
  $output .= " </style>";

  $output .= " </head>";
  $output .= " <body style=\"background-color: #fff; color: #000;\"". theme("onload_attribute"). "\">";
Dries's avatar
 
Dries committed
37 38
  $output .= "<table border=\"0\" cellspacing=\"4\" cellpadding=\"4\"><tr><td style=\"vertical-align: top; width: 170px;\">";

Dries's avatar
 
Dries committed
39 40 41 42 43
  $output .= theme("box", t("Navigation"), @implode("<br />", link_page()));
  $output .= render_blocks("all");
  $output .= "</td><td style=\"vertical-align: top;\">";

  return $output;
Dries's avatar
 
Dries committed
44
}
Dries's avatar
 
Dries committed
45

Dries's avatar
 
Dries committed
46 47 48 49
/**
  Returns themed set of links.

  @param $links an array of \a links to be themed.
Kjartan's avatar
Kjartan committed
50
  @param $delimiter (optional) \a delimiter used to separate the links.
Dries's avatar
 
Dries committed
51

Kjartan's avatar
Kjartan committed
52
  @return a string containing the \a links output.
Dries's avatar
 
Dries committed
53
**/
Dries's avatar
 
Dries committed
54 55 56
function theme_links($links, $delimiter = " | ") {
  return implode($delimiter, $links);
}
Dries's avatar
 
Dries committed
57

Dries's avatar
 
Dries committed
58 59 60 61 62
/**
  Returns themed image.

  @param $name the \a name of the image file.

Kjartan's avatar
Kjartan committed
63
  @return a string containing the \a image output.
Dries's avatar
 
Dries committed
64
**/
Dries's avatar
 
Dries committed
65 66 67
function theme_image($name) {
  return "misc/$name";
}
Dries's avatar
 
Dries committed
68

Dries's avatar
 
Dries committed
69 70 71 72 73
/**
  Returns a themed breadcrumb menu.

  @param $breadcrumb an array containing the breadcrumb links.

Kjartan's avatar
Kjartan committed
74
  @return a string containing the \a breadcrumb output.
Dries's avatar
 
Dries committed
75
**/
Dries's avatar
 
Dries committed
76
function theme_breadcrumb($breadcrumb) {
Dries's avatar
 
Dries committed
77
  return "<div class=\"breadcrumb\">". implode($breadcrumb, " &raquo; ") ."</div>";
Dries's avatar
 
Dries committed
78
}
Dries's avatar
 
Dries committed
79

Dries's avatar
 
Dries committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
/**
  Returns themed node.

  The passed $node object provides a all relevant information for displaying a node:
  \li \c $node->nid
  \li \c $node->type i.e. story, blog, forum.
  \li \c $node->title
  \li \c $node->created a unix timestamp.
  \li \c $node->teaser
  \li \c $node->body
  \li \c $node->changed a unix timestamp.
  \li \c $node->uid the id of the poster.
  \li \c $node->username the username of the poster.

  @param $node the \a node to be themed.
  @param $main

Kjartan's avatar
Kjartan committed
97
  @return a string containing the \a node output.
Dries's avatar
 
Dries committed
98
**/
Dries's avatar
 
Dries committed
99 100 101
function theme_node($node, $main) {
  if (module_exist("taxonomy")) {
    $terms = taxonomy_link("taxonomy terms", $node);
Dries's avatar
 
Dries committed
102 103
  }

Dries's avatar
 
Dries committed
104 105 106
  $output = "<h2>$node->title</h2> by ". format_name($node);

  if (count($terms)) {
Dries's avatar
 
Dries committed
107
    $output .= " <small>(". print theme("links", $terms) .")</small><br />";
Dries's avatar
 
Dries committed
108 109
  }

Dries's avatar
 
Dries committed
110 111 112 113 114
  if ($main && $node->teaser) {
    $output .= $node->teaser;
  }
  else {
    $output .= $node->body;
Dries's avatar
 
Dries committed
115 116
  }

Dries's avatar
 
Dries committed
117
  if ($links = link_node($node, $main)) {
Dries's avatar
 
Dries committed
118
    $output .= "<br />[ ". print theme("links", $links) ." ]";
Dries's avatar
 
Dries committed
119
  }
Dries's avatar
 
Dries committed
120 121
  $output .= "<hr />";

Dries's avatar
 
Dries committed
122
  return $output;
Dries's avatar
 
Dries committed
123 124
}

Dries's avatar
 
Dries committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
function _theme_table_cell($cell, $header = 0) {
  if (is_array($cell)) {
    $data = $cell["data"];
    foreach ($cell as $key => $value) {
      if ($key != "data")  {
        $attributes .= " $key=\"$value\"";
      }
    }
  }
  else {
    $data = $cell;
  }

  if ($header) {
    $output = "<th$attributes>$data</th>";
  }
  else {
    $output = "<td$attributes>$data</td>";
  }

  return $output;
}

Dries's avatar
 
Dries committed
148 149 150 151 152 153 154 155 156 157 158
/**
  Returns themed table.

  @param $title the form element's title
  @param $value the form element's data
  @param $description the form element's description or explanation

  @return a string contraining the \a node output.
**/

function theme_form_element($title, $value, $description = 0) {
159
  return "<div class=\"form-item\">". ($title ? "<label>$title:</label><br />" : "") . $value . ($description ? "<div class=\"description\">$description</div>" : "") ."</div>\n";
Dries's avatar
 
Dries committed
160
}
Dries's avatar
 
Dries committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

/**
  Returns themed table.

  @param $header
  @param $rows

  @return a string contraining the \a node output.
**/

function theme_table($header, $rows) {

  $output = "<table>\n";

  /*
  ** Emit the table header:
  */

  if (is_array($header)) {
    $output .= " <tr>";
    foreach ($header as $cell) {
      if (is_array($cell) && $cell["field"]) {
        $cell = tablesort($cell, $header);
      }
      $output .= _theme_table_cell($cell, 1);
    }
    $output .= " </tr>\n";
  }

  /*
  ** Emit the table rows:
  */

  if (is_array($rows)) {
    foreach ($rows as $number => $row) {
      if ($number % 2 == 1) {
        $output .= " <tr class=\"light\">";
      }
      else {
        $output .= " <tr class=\"dark\">";
      }

      foreach ($row as $cell) {
        $output .= _theme_table_cell($cell, 0);
      }
      $output .= " </tr>\n";
    }
  }

  $output .= "</table>\n";

  return $output;
}

Dries's avatar
 
Dries committed
215 216 217 218 219
/**
  Returns themed box.

  @param $subject the \a subject of the box.
  @param $content the \a content of the box.
Kjartan's avatar
Kjartan committed
220
  @param $region the \a region of the box.
Dries's avatar
 
Dries committed
221

Kjartan's avatar
Kjartan committed
222
  @return a string containing the \a box output.
Dries's avatar
 
Dries committed
223
**/
Dries's avatar
 
Dries committed
224 225
function theme_box($subject, $content, $region = "main") {
  $output = "<h2>$subject</h2><p>$content</p>";
Dries's avatar
 
Dries committed
226
  return $output;
Dries's avatar
 
Dries committed
227 228 229
}

/**
Dries's avatar
 
Dries committed
230 231 232 233 234 235 236 237 238 239
  Returns a themed 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, ...).

Kjartan's avatar
Kjartan committed
240
  @return a string containing the \a box output.
Dries's avatar
 
Dries committed
241
**/
Dries's avatar
 
Dries committed
242 243 244 245 246
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>";
Dries's avatar
 
Dries committed
247
  return $output;
Dries's avatar
 
Dries committed
248
}
Dries's avatar
 
Dries committed
249

Dries's avatar
 
Dries committed
250 251 252
/**
  Returns themed page footer.

Kjartan's avatar
Kjartan committed
253
  @return a string containing the \a footer output.
Dries's avatar
 
Dries committed
254
**/
Dries's avatar
 
Dries committed
255 256
function theme_footer() {
  $output = "</td></tr></table>";
Dries's avatar
 
Dries committed
257
  $output .= theme_closure();
Dries's avatar
 
Dries committed
258
  $output .= "</body></html>";
Dries's avatar
 
Dries committed
259
  return $output;
Dries's avatar
 
Dries committed
260
}
Kjartan's avatar
Changes  
Kjartan committed
261

Dries's avatar
 
Dries committed
262
/**
Dries's avatar
 
Dries committed
263 264
  Returns themed marker, useful for marking new comments or required form elements.

Kjartan's avatar
Kjartan committed
265
  @return a string containing the \a mark output.
Dries's avatar
 
Dries committed
266
**/
Dries's avatar
 
Dries committed
267
function theme_mark() {
Dries's avatar
 
Dries committed
268
  return "<span class=\"marker\">*</span>";
Dries's avatar
 
Dries committed
269 270
}

Dries's avatar
 
Dries committed
271
/**
Dries's avatar
 
Dries committed
272 273 274 275 276
  Returns themed list of items.

  @param $items (optional) an array of the items to be displayed in a list.
  @param $title (optional) the title of the list.

Kjartan's avatar
Kjartan committed
277
  @return a string containing the \a list output.
Dries's avatar
 
Dries committed
278
**/
Dries's avatar
 
Dries committed
279
function theme_item_list($items = array(), $title = NULL) {
Dries's avatar
 
Dries committed
280
  $output .= "<div class=\"item-list\">";
Dries's avatar
 
Dries committed
281
  if (isset($title)) {
Dries's avatar
 
Dries committed
282
    $output .= "<h3>$title</h3>";
Dries's avatar
 
Dries committed
283 284
  }

Dries's avatar
 
Dries committed
285
  if (isset($items)) {
Dries's avatar
 
Dries committed
286
    $output .= "<ul>";
Dries's avatar
 
Dries committed
287
    foreach ($items as $item) {
Dries's avatar
 
Dries committed
288
      $output .= "<li>$item</li>";
Dries's avatar
 
Dries committed
289
    }
Dries's avatar
 
Dries committed
290
    $output .= "</ul>";
Dries's avatar
 
Dries committed
291
  }
Dries's avatar
 
Dries committed
292
  $output .= "</div>";
Dries's avatar
 
Dries committed
293 294 295
  return $output;
}

Dries's avatar
 
Dries committed
296
/**
Dries's avatar
 
Dries committed
297 298 299 300
  Returns themed error message.

  @param $message the error message to be themed.

Kjartan's avatar
Kjartan committed
301
  @return a string containing the \a error output.
Dries's avatar
 
Dries committed
302
**/
Dries's avatar
 
Dries committed
303
function theme_error($message) {
Dries's avatar
 
Dries committed
304
  return "<div class=\"error\">$message</div>";
Dries's avatar
 
Dries committed
305 306
}

Dries's avatar
 
Dries committed
307 308
/**
  Execute hook _head which is run at the start of the page, and output should be in the head tags.
Dries's avatar
 
Dries committed
309

Dries's avatar
 
Dries committed
310
  @param $main (optional)
311

Kjartan's avatar
Kjartan committed
312
  @return a string containing the \a error output.
Dries's avatar
 
Dries committed
313
**/
Dries's avatar
 
Dries committed
314
function theme_head($main = 0) {
Dries's avatar
 
Dries committed
315
  global $base_url;
Dries's avatar
 
Dries committed
316
  $output .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
Dries's avatar
 
Dries committed
317 318 319 320
  $output .= "<base href=\"$base_url/\" />\n";
  $output .= "<style type=\"text/css\">\n";
  $output .= "@import url(misc/drupal.css);\n";
  $output .= "</style>\n";
Dries's avatar
 
Dries committed
321
  $head = module_invoke_all("head", $main);
Dries's avatar
 
Dries committed
322 323
  $output .= implode($head, "\n");
  return $output;
Dries's avatar
 
Dries committed
324 325
}

Dries's avatar
 
Dries committed
326
/**
Dries's avatar
 
Dries committed
327 328 329 330 331
  Execute hook _footer() which is run at the end of the page right
  before the </body> tag.

  @param $main (optional)

Kjartan's avatar
Kjartan committed
332
  @return a string containing the \a closure output.
Dries's avatar
 
Dries committed
333
**/
Dries's avatar
 
Dries committed
334
function theme_closure($main = 0) {
Dries's avatar
 
Dries committed
335 336 337 338
  $footer = module_invoke_all("footer", $main);
  return implode($footer, "\n");
}

Dries's avatar
 
Dries committed
339 340 341
/**
  Call _onload hook in all modules to enable modules to insert javascript
  that will get run once the page has been loaded by the browser.
342

Dries's avatar
 
Dries committed
343
  @param $theme_onloads (optional) addition onload directives.
Dries's avatar
 
Dries committed
344

Kjartan's avatar
Kjartan committed
345
  @return a string containing the \a onload output.
Dries's avatar
 
Dries committed
346 347 348 349
**/
function theme_onload_attribute($theme_onloads = array()) {
  if (!is_array($theme_onloads)) {
    $theme_onloads = array($theme_onloads);
Dries's avatar
 
Dries committed
350
  }
Dries's avatar
 
Dries committed
351 352 353 354 355
  // Merge theme onloads (javascript rollovers, image preloads, etc.)
  // with module onloads (htmlarea, etc.)
  $onloads = array_merge(module_invoke_all("onload"), $theme_onloads);
  if (count($onloads)) {
    return " onload=\"" . implode("; ", $onloads) . "\"";
Dries's avatar
 
Dries committed
356
  }
Dries's avatar
 
Dries committed
357
  return "";
Dries's avatar
 
Dries committed
358 359
}

Dries's avatar
 
Dries committed
360
/**
Dries's avatar
 
Dries committed
361 362 363 364
  Render blocks available for (global) $user and $region calling $theme->block($block).

  @param   $region   main|left|right

Kjartan's avatar
Kjartan committed
365
  @return a string containing the \a blocks output.
Dries's avatar
 
Dries committed
366 367
 **/
function render_blocks($region) {
Dries's avatar
 
Dries committed
368
  global $user;
Dries's avatar
 
Dries committed
369

Dries's avatar
 
Dries committed
370
  $result = db_query("SELECT * FROM {blocks} WHERE (status = '1' OR custom = '1') ". ($region != "all" ? "AND region = %d " : "") ."ORDER BY weight, module", $region == "left" ? 0 : 1);
Dries's avatar
 
Dries committed
371

Dries's avatar
 
Dries committed
372
  $output = "";
Dries's avatar
 
Dries committed
373 374 375 376
  while ($result && ($block = db_fetch_array($result))) {
    if ((($block['status'] && (!$user->uid || !$block['custom'])) || ($block['custom'] && $user->block[$block['module']][$block['delta']])) && (!$block['path'] || preg_match($block['path'], str_replace("?q=", "", request_uri())))) {
      $block = array_merge($block, module_invoke($block['module'], 'block', 'view', $block['delta']));
      if ($block['content']) {
Dries's avatar
 
Dries committed
377
        $output .= theme('block', (object)$block);
378
      }
Dries's avatar
 
Dries committed
379 380
    }
  }
Dries's avatar
 
Dries committed
381
  return $output;
Dries's avatar
 
Dries committed
382
}
383

Dries's avatar
 
Dries committed
384 385
/**
  Hook Help - returns theme specific help and information.
Dries's avatar
 
Dries committed
386

Dries's avatar
 
Dries committed
387
  @param section defines the \a section of the help to be returned.
Dries's avatar
 
Dries committed
388

Kjartan's avatar
Kjartan committed
389
  @return a string containing the help output.
Dries's avatar
 
Dries committed
390 391 392
**/
function theme_help($section) {
  $ouptout = "";
Dries's avatar
 
Dries committed
393

Dries's avatar
 
Dries committed
394 395 396 397
  switch ($section) {
    case 'admin/system/themes#description':
      $output = t("The base theme");
      break;
Dries's avatar
 
Dries committed
398
  }
Dries's avatar
 
Dries committed
399 400 401 402
  return $output;
}

/**
Kjartan's avatar
Kjartan committed
403
  Provides a list of currently available themes.
Dries's avatar
 
Dries committed
404 405 406

  @param $refresh

Kjartan's avatar
Kjartan committed
407
  @return an array of the currently available themes.
Dries's avatar
 
Dries committed
408 409 410 411 412 413
**/
function list_themes($refresh = 0) {
  static $list;

  if ($refresh) {
    unset($list);
Dries's avatar
 
Dries committed
414
  }
Dries's avatar
 
Dries committed
415 416 417 418 419 420 421 422 423

  if (!$list) {
    $list = array();
    $result = db_query("SELECT * FROM {system} where type = 'theme' AND status = '1' ORDER BY name");
    while ($theme = db_fetch_object($result)) {
      if (file_exists($theme->filename)) {
        $list[$theme->name] = $theme;
      }
    }
Dries's avatar
 
Dries committed
424
  }
Dries's avatar
 
Dries committed
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446

  return $list;
}

/**
  Initialized the theme system.

  @return the name of the currently selected theme.
**/
function init_theme() {
  global $user;

  $themes = list_themes();
  $name = $user->theme ? $user->theme : variable_get("theme_default", 0);

  $theme->path = "";
  $theme->name = "";

  if (is_object($themes[$name])) {
    include_once($themes[$name]->filename);
    $theme->path = dirname($themes[$name]->filename);
    $theme->name = $name;
Dries's avatar
 
Dries committed
447
  }
Dries's avatar
 
Dries committed
448 449

  return $theme;
Dries's avatar
 
Dries committed
450 451
}

Dries's avatar
 
Dries committed
452
/**
Dries's avatar
 
Dries committed
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
  Returns the path to the currently selected theme.

  @return the path to the the currently selected theme.
**/
function path_to_theme() {
  global $theme;
  return $theme->path;
}

/**
  External interface of the theme system to all other modules, and core files.

  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.
  Example: \verbatim $header_text = theme("header"); \endverbatim

  @return the path to the the currently selected theme.
**/
function theme() {
  global $theme;

  $args = func_get_args();
  $function = array_shift($args);

  if (($theme->name != "") && (function_exists($theme->name ."_". $function))) {
    return call_user_func_array($theme->name ."_". $function, $args);
Dries's avatar
 
Dries committed
481
  }
Dries's avatar
 
Dries committed
482 483
  elseif (function_exists("theme_". $function)){
    return call_user_func_array("theme_". $function, $args);
Dries's avatar
 
Dries committed
484 485 486
  }
}

Dries's avatar
 
Dries committed
487
/**  @} End of defgroup theme_system **/
Dries's avatar
 
Dries committed
488
?>