theme.inc 11.7 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 148 149 150 151 152 153 154 155 156 157 158 159 160 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
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;
}


/**
  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
202 203 204 205 206
/**
  Returns themed box.

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

Kjartan's avatar
Kjartan committed
209
  @return a string containing the \a box output.
Dries's avatar
 
Dries committed
210
**/
Dries's avatar
 
Dries committed
211 212
function theme_box($subject, $content, $region = "main") {
  $output = "<h2>$subject</h2><p>$content</p>";
Dries's avatar
 
Dries committed
213
  return $output;
Dries's avatar
 
Dries committed
214 215 216
}

/**
Dries's avatar
 
Dries committed
217 218 219 220 221 222 223 224 225 226
  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
227
  @return a string containing the \a box output.
Dries's avatar
 
Dries committed
228
**/
Dries's avatar
 
Dries committed
229 230 231 232 233
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
234
  return $output;
Dries's avatar
 
Dries committed
235
}
Dries's avatar
 
Dries committed
236

Dries's avatar
 
Dries committed
237 238 239
/**
  Returns themed page footer.

Kjartan's avatar
Kjartan committed
240
  @return a string containing the \a footer output.
Dries's avatar
 
Dries committed
241
**/
Dries's avatar
 
Dries committed
242 243
function theme_footer() {
  $output = "</td></tr></table>";
Dries's avatar
 
Dries committed
244
  $output .= theme_closure();
Dries's avatar
 
Dries committed
245
  $output .= "</body></html>";
Dries's avatar
 
Dries committed
246
  return $output;
Dries's avatar
 
Dries committed
247
}
Kjartan's avatar
Changes  
Kjartan committed
248

Dries's avatar
 
Dries committed
249
/**
Dries's avatar
 
Dries committed
250 251
  Returns themed marker, useful for marking new comments or required form elements.

Kjartan's avatar
Kjartan committed
252
  @return a string containing the \a mark output.
Dries's avatar
 
Dries committed
253
**/
Dries's avatar
 
Dries committed
254
function theme_mark() {
Dries's avatar
 
Dries committed
255
  return "<span class=\"marker\">*</span>";
Dries's avatar
 
Dries committed
256 257
}

Dries's avatar
 
Dries committed
258
/**
Dries's avatar
 
Dries committed
259 260 261 262 263
  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
264
  @return a string containing the \a list output.
Dries's avatar
 
Dries committed
265
**/
Dries's avatar
 
Dries committed
266
function theme_item_list($items = array(), $title = NULL) {
Dries's avatar
 
Dries committed
267
  $output .= "<div class=\"item-list\">";
Dries's avatar
 
Dries committed
268
  if (isset($title)) {
Dries's avatar
 
Dries committed
269
    $output .= "<h3>$title</h3>";
Dries's avatar
 
Dries committed
270 271
  }

Dries's avatar
 
Dries committed
272
  if (isset($items)) {
Dries's avatar
 
Dries committed
273
    $output .= "<ul>";
Dries's avatar
 
Dries committed
274
    foreach ($items as $item) {
Dries's avatar
 
Dries committed
275
      $output .= "<li>$item</li>";
Dries's avatar
 
Dries committed
276
    }
Dries's avatar
 
Dries committed
277
    $output .= "</ul>";
Dries's avatar
 
Dries committed
278
  }
Dries's avatar
 
Dries committed
279
  $output .= "</div>";
Dries's avatar
 
Dries committed
280 281 282
  return $output;
}

Dries's avatar
 
Dries committed
283
/**
Dries's avatar
 
Dries committed
284 285 286 287
  Returns themed error message.

  @param $message the error message to be themed.

Kjartan's avatar
Kjartan committed
288
  @return a string containing the \a error output.
Dries's avatar
 
Dries committed
289
**/
Dries's avatar
 
Dries committed
290
function theme_error($message) {
Dries's avatar
 
Dries committed
291
  return "<div class=\"error\">$message</div>";
Dries's avatar
 
Dries committed
292 293
}

Dries's avatar
 
Dries committed
294 295
/**
  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
296

Dries's avatar
 
Dries committed
297
  @param $main (optional)
298

Kjartan's avatar
Kjartan committed
299
  @return a string containing the \a error output.
Dries's avatar
 
Dries committed
300
**/
Dries's avatar
 
Dries committed
301
function theme_head($main = 0) {
Dries's avatar
 
Dries committed
302
  global $base_url;
Dries's avatar
 
Dries committed
303
  $output .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
Dries's avatar
 
Dries committed
304 305 306 307
  $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
308
  $head = module_invoke_all("head", $main);
Dries's avatar
 
Dries committed
309 310
  $output .= implode($head, "\n");
  return $output;
Dries's avatar
 
Dries committed
311 312
}

Dries's avatar
 
Dries committed
313
/**
Dries's avatar
 
Dries committed
314 315 316 317 318
  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
319
  @return a string containing the \a closure output.
Dries's avatar
 
Dries committed
320
**/
Dries's avatar
 
Dries committed
321
function theme_closure($main = 0) {
Dries's avatar
 
Dries committed
322 323 324 325
  $footer = module_invoke_all("footer", $main);
  return implode($footer, "\n");
}

Dries's avatar
 
Dries committed
326 327 328
/**
  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.
329

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

Kjartan's avatar
Kjartan committed
332
  @return a string containing the \a onload output.
Dries's avatar
 
Dries committed
333 334 335 336
**/
function theme_onload_attribute($theme_onloads = array()) {
  if (!is_array($theme_onloads)) {
    $theme_onloads = array($theme_onloads);
Dries's avatar
 
Dries committed
337
  }
Dries's avatar
 
Dries committed
338 339 340 341 342
  // 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
343
  }
Dries's avatar
 
Dries committed
344
  return "";
Dries's avatar
 
Dries committed
345 346
}

Dries's avatar
 
Dries committed
347
/**
Dries's avatar
 
Dries committed
348 349 350 351
  Render blocks available for (global) $user and $region calling $theme->block($block).

  @param   $region   main|left|right

Kjartan's avatar
Kjartan committed
352
  @return a string containing the \a blocks output.
Dries's avatar
 
Dries committed
353 354
 **/
function render_blocks($region) {
Dries's avatar
 
Dries committed
355
  global $user;
Dries's avatar
 
Dries committed
356

Dries's avatar
 
Dries committed
357
  $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
358

Dries's avatar
 
Dries committed
359
  $output = "";
Dries's avatar
 
Dries committed
360 361 362 363
  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
364
        $output .= theme('block', (object)$block);
365
      }
Dries's avatar
 
Dries committed
366 367
    }
  }
Dries's avatar
 
Dries committed
368
  return $output;
Dries's avatar
 
Dries committed
369
}
370

Dries's avatar
 
Dries committed
371 372
/**
  Hook Help - returns theme specific help and information.
Dries's avatar
 
Dries committed
373

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

Kjartan's avatar
Kjartan committed
376
  @return a string containing the help output.
Dries's avatar
 
Dries committed
377 378 379
**/
function theme_help($section) {
  $ouptout = "";
Dries's avatar
 
Dries committed
380

Dries's avatar
 
Dries committed
381 382 383 384
  switch ($section) {
    case 'admin/system/themes#description':
      $output = t("The base theme");
      break;
Dries's avatar
 
Dries committed
385
  }
Dries's avatar
 
Dries committed
386 387 388 389
  return $output;
}

/**
Kjartan's avatar
Kjartan committed
390
  Provides a list of currently available themes.
Dries's avatar
 
Dries committed
391 392 393

  @param $refresh

Kjartan's avatar
Kjartan committed
394
  @return an array of the currently available themes.
Dries's avatar
 
Dries committed
395 396 397 398 399 400
**/
function list_themes($refresh = 0) {
  static $list;

  if ($refresh) {
    unset($list);
Dries's avatar
 
Dries committed
401
  }
Dries's avatar
 
Dries committed
402 403 404 405 406 407 408 409 410

  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
411
  }
Dries's avatar
 
Dries committed
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433

  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
434
  }
Dries's avatar
 
Dries committed
435 436

  return $theme;
Dries's avatar
 
Dries committed
437 438
}

Dries's avatar
 
Dries committed
439
/**
Dries's avatar
 
Dries committed
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
  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
468
  }
Dries's avatar
 
Dries committed
469 470
  elseif (function_exists("theme_". $function)){
    return call_user_func_array("theme_". $function, $args);
Dries's avatar
 
Dries committed
471 472 473
  }
}

Dries's avatar
 
Dries committed
474
/**  @} End of defgroup theme_system **/
Dries's avatar
 
Dries committed
475
?>