theme.inc 13 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
Dries's avatar
 
Dries committed
2 3
/* $Id$ */

4
/**
Dries's avatar
 
Dries committed
5 6 7 8 9 10 11 12 13 14
 * @file
 *
 * Theme System - controls the output of Drupal.
 *
 * The theme system allows for nearly all output of the Drupal system to be
 * customized by user themes.
 *
 * @see <a href="http://drupal.org/node/view/253">Theme system</a>
 * @see themeable
 */
Dries's avatar
 
Dries committed
15

Dries's avatar
 
Dries committed
16
/**
Dries's avatar
 
Dries committed
17 18 19 20 21 22
 * Hook Help - returns theme specific help and information.
 *
 * @param section defines the @a section of the help to be returned.
 *
 * @return a string containing the help output.
 */
Dries's avatar
 
Dries committed
23
function theme_help($section) {
Dries's avatar
 
Dries committed
24
  $output = "";
Dries's avatar
 
Dries committed
25 26 27 28 29 30 31 32 33 34

  switch ($section) {
    case 'admin/system/themes#description':
      $output = t("The base theme");
      break;
  }
  return $output;
}

/**
Dries's avatar
 
Dries committed
35 36 37 38
 * Initialized the theme system.
 *
 * @return the name of the currently selected theme.
 */
Dries's avatar
 
Dries committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
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;
  }

  return $theme;
}

/**
Dries's avatar
 
Dries committed
58 59 60 61 62 63
 * Provides a list of currently available themes.
 *
 * @param $refresh
 *
 * @return an array of the currently available themes.
 */
Dries's avatar
 
Dries committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
function list_themes($refresh = 0) {
  static $list;

  if ($refresh) {
    unset($list);
  }

  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;
      }
    }
  }

  return $list;
}

/**
Dries's avatar
 
Dries committed
85 86 87 88 89 90 91 92 93
 * 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 themed output.
 */
Dries's avatar
 
Dries committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
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);
  }
  elseif (function_exists("theme_". $function)){
    return call_user_func_array("theme_". $function, $args);
  }
}

/**
Dries's avatar
 
Dries committed
109 110 111 112
 * Returns the path to the currently selected theme.
 *
 * @return the path to the the currently selected theme.
 */
Dries's avatar
 
Dries committed
113 114 115 116 117 118
function path_to_theme() {
  global $theme;
  return $theme->path;
}

/**
Dries's avatar
 
Dries committed
119 120 121 122 123 124 125 126
 * @defgroup themeable Themeable functions
 * @{
 *
 * Themeable functions - functions that can be styled differently in themes.
 *
 * @see theme
 * @see theme.inc
 */
Dries's avatar
 
Dries committed
127

Dries's avatar
 
Dries committed
128
/**
Dries's avatar
 
Dries committed
129 130 131 132
 * Returns the theme header.
 *
 * @return a string containing the @a header output.
 */
Dries's avatar
 
Dries committed
133
function theme_header() {
Dries's avatar
 
Dries committed
134 135
  $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
136
  $output .= "<head>";
Dries's avatar
 
Dries committed
137
  $output .= " <title>". drupal_get_title() ? drupal_get_title() : variable_get(site_name, "drupal") ."</title>";
Dries's avatar
 
Dries committed
138
  $output .= theme_head();
Dries's avatar
 
Dries committed
139 140 141 142 143 144
  $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
145 146
  $output .= "<table border=\"0\" cellspacing=\"4\" cellpadding=\"4\"><tr><td style=\"vertical-align: top; width: 170px;\">";

Dries's avatar
 
Dries committed
147
  $output .= theme("box", t("Navigation"), @implode("<br />", link_page()));
148
  $output .= theme("blocks", "all");
Dries's avatar
 
Dries committed
149 150
  $output .= "</td><td style=\"vertical-align: top;\">";

Dries's avatar
 
Dries committed
151 152 153 154 155 156
  $output .= theme("breadcrumb", drupal_get_breadcrumb());
  $output .= "<h1>" . drupal_get_title() . "</h1>";
  if ($help = menu_get_active_help()) {
    $output .= "<small>$help</small><hr />";
  }

Dries's avatar
 
Dries committed
157
  return $output;
Dries's avatar
 
Dries committed
158
}
Dries's avatar
 
Dries committed
159

Dries's avatar
 
Dries committed
160
/**
Dries's avatar
 
Dries committed
161 162
 * Returns an entire Drupal page displaying the supplied content.
 *
Dries's avatar
 
Dries committed
163 164
 * @param $content a string containing the content to display
 * @param $title (optional) page title (\<head>\<title>)
Dries's avatar
 
Dries committed
165 166
 * @param $breadcrumb (optional) page breadcrumb
 *
Dries's avatar
 
Dries committed
167
 * @see drupal_breadcrumb
Dries's avatar
 
Dries committed
168
 *
Dries's avatar
 
Dries committed
169 170
 * @return a string containing the @a page output.
 */
Dries's avatar
 
Dries committed
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
function theme_page($content, $title = NULL, $breadcrumb = NULL) {
  if (isset($title)) {
    drupal_set_title($title);
  }
  if (isset($breadcrumb)) {
    drupal_set_breadcrumb($breadcrumb);
  }

  $output = theme("header");
  $output .= $content;
  $output .= theme("footer");

  return $output;
}

Dries's avatar
 
Dries committed
186
/**
Dries's avatar
 
Dries committed
187 188 189 190 191 192 193
 * Returns themed set of links.
 *
 * @param $links an array of @a links to be themed.
 * @param $delimiter (optional) @a delimiter used to separate the links.
 *
 * @return a string containing the @a links output.
 */
Dries's avatar
 
Dries committed
194 195 196
function theme_links($links, $delimiter = " | ") {
  return implode($delimiter, $links);
}
Dries's avatar
 
Dries committed
197

Dries's avatar
 
Dries committed
198
/**
Dries's avatar
 
Dries committed
199 200 201 202 203 204
 * Returns themed image.
 *
 * @param $name the @a name of the image file.
 *
 * @return a string containing the @a image output.
 */
Dries's avatar
 
Dries committed
205 206 207
function theme_image($name) {
  return "misc/$name";
}
Dries's avatar
 
Dries committed
208

Dries's avatar
 
Dries committed
209
/**
Dries's avatar
 
Dries committed
210 211 212 213 214 215
 * Returns a themed breadcrumb menu.
 *
 * @param $breadcrumb an array containing the breadcrumb links.
 *
 * @return a string containing the @a breadcrumb output.
 */
Dries's avatar
 
Dries committed
216
function theme_breadcrumb($breadcrumb) {
Dries's avatar
 
Dries committed
217
  return "<div class=\"breadcrumb\">". implode($breadcrumb, " &raquo; ") ."</div>";
Dries's avatar
 
Dries committed
218
}
Dries's avatar
 
Dries committed
219

Dries's avatar
 
Dries committed
220
/**
Dries's avatar
 
Dries committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
 * 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 Display teaser only, as on main page?
 * @param $page Display node as standalone page (no title)?
 *
 * @return a string containing the @a node output.
 */
Dries's avatar
 
Dries committed
241
function theme_node($node, $main = 0, $page = 0) {
Dries's avatar
 
Dries committed
242 243
  if (module_exist("taxonomy")) {
    $terms = taxonomy_link("taxonomy terms", $node);
Dries's avatar
 
Dries committed
244 245
  }

Dries's avatar
 
Dries committed
246
  if ($page == 0) {
Dries's avatar
 
Dries committed
247
    $output = "<h2 class=\"title\">$node->title</h2> by ". format_name($node);
Dries's avatar
 
Dries committed
248 249 250 251
  }
  else {
    $output = "by ". format_name($node);
  }
Dries's avatar
 
Dries committed
252 253

  if (count($terms)) {
Dries's avatar
 
Dries committed
254
    $output .= " <small>(". theme("links", $terms) .")</small><br />";
Dries's avatar
 
Dries committed
255 256
  }

Dries's avatar
 
Dries committed
257 258 259 260 261
  if ($main && $node->teaser) {
    $output .= $node->teaser;
  }
  else {
    $output .= $node->body;
Dries's avatar
 
Dries committed
262 263
  }

Dries's avatar
 
Dries committed
264
  if ($links = link_node($node, $main)) {
Dries's avatar
 
Dries committed
265
    $output .= "<div class=\"links\">". theme("links", $links) ."</div>";
Dries's avatar
 
Dries committed
266
  }
Dries's avatar
 
Dries committed
267

Dries's avatar
 
Dries committed
268
  return $output;
Dries's avatar
 
Dries committed
269 270
}

Dries's avatar
 
Dries committed
271
/**
Dries's avatar
 
Dries committed
272 273 274 275 276 277 278 279
 * Returns themed form element.
 *
 * @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 containing the @a node output.
 */
Dries's avatar
 
Dries committed
280 281

function theme_form_element($title, $value, $description = 0) {
282
  return "<div class=\"form-item\">". ($title ? "<label>$title:</label><br />" : "") . $value . ($description ? "<div class=\"description\">$description</div>" : "") ."</div>\n";
Dries's avatar
 
Dries committed
283
}
Dries's avatar
 
Dries committed
284 285

/**
Dries's avatar
 
Dries committed
286 287 288 289 290 291 292
 * Returns themed table.
 *
 * @param $header
 * @param $rows
 *
 * @return a string containing the @a node output.
 */
Dries's avatar
 
Dries committed
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337

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
338
/**
Dries's avatar
 
Dries committed
339 340
 * Returns themed box.
 *
Kjartan's avatar
Kjartan committed
341
 * @param $title the @a subject of the box.
Dries's avatar
 
Dries committed
342 343 344 345 346
 * @param $content the @a content of the box.
 * @param $region the @a region of the box.
 *
 * @return a string containing the @a box output.
 */
Dries's avatar
 
Dries committed
347 348
function theme_box($title, $content, $region = "main") {
  $output = "<h2 class=\"title\">$title</h2><p>$content</p>";
Dries's avatar
 
Dries committed
349
  return $output;
Dries's avatar
 
Dries committed
350 351 352
}

/**
Dries's avatar
 
Dries committed
353 354 355 356 357 358 359 360 361 362 363 364 365
 * 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, ...).
 *
 * @return a string containing the @a box output.
 */
Dries's avatar
 
Dries committed
366
function theme_block($block) {
Dries's avatar
 
Dries committed
367 368 369 370
  $output  = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">\n";
  $output .= " <h2 class=\"title\">$block->subject</h2>\n";
  $output .= " <div class=\"content\">$block->content</div>\n";
  $output .= "</div>\n";
Dries's avatar
 
Dries committed
371
  return $output;
Dries's avatar
 
Dries committed
372
}
Dries's avatar
 
Dries committed
373

Dries's avatar
 
Dries committed
374
/**
Dries's avatar
 
Dries committed
375 376 377 378
 * Returns themed page footer.
 *
 * @return a string containing the @a footer output.
 */
Dries's avatar
 
Dries committed
379 380
function theme_footer() {
  $output = "</td></tr></table>";
Dries's avatar
 
Dries committed
381
  $output .= theme_closure();
Dries's avatar
 
Dries committed
382
  $output .= "</body></html>";
Dries's avatar
 
Dries committed
383
  return $output;
Dries's avatar
 
Dries committed
384
}
Kjartan's avatar
Changes  
Kjartan committed
385

Dries's avatar
 
Dries committed
386
/**
Dries's avatar
 
Dries committed
387 388 389 390 391
 * Returns themed marker, useful for marking new comments or required form
 * elements.
 *
 * @return a string containing the @a mark output.
 */
Dries's avatar
 
Dries committed
392
function theme_mark() {
Dries's avatar
 
Dries committed
393
  return "<span class=\"marker\">*</span>";
Dries's avatar
 
Dries committed
394 395
}

Dries's avatar
 
Dries committed
396
/**
Dries's avatar
 
Dries committed
397 398 399 400 401 402 403
 * 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.
 *
 * @return a string containing the @a list output.
 */
Dries's avatar
 
Dries committed
404
function theme_item_list($items = array(), $title = NULL) {
Dries's avatar
 
Dries committed
405
  $output = "<div class=\"item-list\">";
Dries's avatar
 
Dries committed
406
  if (isset($title)) {
Dries's avatar
 
Dries committed
407
    $output .= "<h3>$title</h3>";
Dries's avatar
 
Dries committed
408 409
  }

Dries's avatar
 
Dries committed
410
  if (isset($items)) {
Dries's avatar
 
Dries committed
411
    $output .= "<ul>";
Dries's avatar
 
Dries committed
412
    foreach ($items as $item) {
Dries's avatar
 
Dries committed
413
      $output .= "<li>$item</li>";
Dries's avatar
 
Dries committed
414
    }
Dries's avatar
 
Dries committed
415
    $output .= "</ul>";
Dries's avatar
 
Dries committed
416
  }
Dries's avatar
 
Dries committed
417
  $output .= "</div>";
Dries's avatar
 
Dries committed
418 419 420
  return $output;
}

Dries's avatar
 
Dries committed
421
/**
Dries's avatar
 
Dries committed
422 423 424 425 426 427
 * Returns themed error message.
 *
 * @param $message the error message to be themed.
 *
 * @return a string containing the @a error output.
 */
Dries's avatar
 
Dries committed
428
function theme_error($message) {
Dries's avatar
 
Dries committed
429
  return "<div class=\"error\">$message</div>";
Dries's avatar
 
Dries committed
430 431
}

Dries's avatar
 
Dries committed
432
/**
Dries's avatar
 
Dries committed
433 434 435 436 437 438 439
 * Execute hook _head which is run at the start of the page, and output should
 * be in the head tags.
 *
 * @param $main (optional)
 *
 * @return a string containing the @a error output.
 */
Dries's avatar
 
Dries committed
440
function theme_head($main = 0) {
Dries's avatar
 
Dries committed
441
  global $base_url;
Dries's avatar
 
Dries committed
442
  $output .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
Dries's avatar
 
Dries committed
443 444 445 446
  $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
447
  $head = module_invoke_all("head", $main);
Dries's avatar
 
Dries committed
448 449
  $output .= implode($head, "\n");
  return $output;
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
 * Execute hook _footer() which is run at the end of the page right before the
 * \</body> tag.
 *
 * @param $main (optional)
 *
 * @return a string containing the @a closure output.
 */
Dries's avatar
 
Dries committed
460
function theme_closure($main = 0) {
Dries's avatar
 
Dries committed
461 462 463 464
  $footer = module_invoke_all("footer", $main);
  return implode($footer, "\n");
}

Dries's avatar
 
Dries committed
465
/**
Dries's avatar
 
Dries committed
466 467 468 469 470 471 472
 * 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.
 *
 * @param $theme_onloads (optional) addition onload directives.
 *
 * @return a string containing the @a onload output.
 */
Dries's avatar
 
Dries committed
473 474 475
function theme_onload_attribute($theme_onloads = array()) {
  if (!is_array($theme_onloads)) {
    $theme_onloads = array($theme_onloads);
Dries's avatar
 
Dries committed
476
  }
Dries's avatar
 
Dries committed
477 478 479 480 481
  // 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
482
  }
Dries's avatar
 
Dries committed
483
  return "";
Dries's avatar
 
Dries committed
484 485
}

Dries's avatar
 
Dries committed
486
/**
487 488
 * Returns themed blocks available for current $user at $region.
 *
Dries's avatar
 
Dries committed
489
 * @param $region main|left|right
490
 *
Dries's avatar
 
Dries committed
491
 * @return a string containing the @a blocks output.
492 493
 */
function theme_blocks($region) {
Dries's avatar
 
Dries committed
494
  $output = "";
495 496 497 498 499

  if ($list = module_invoke('block', 'list', $region)) {
    foreach ($list as $key => $block) {
      // $key == <i>module</i>_<i>delta</i>
      $output .= theme('block', $block);
Dries's avatar
 
Dries committed
500 501
    }
  }
Dries's avatar
 
Dries committed
502
  return $output;
Dries's avatar
 
Dries committed
503
}
Dries's avatar
 
Dries committed
504
/* @} End of defgroup themeable */
505

Dries's avatar
 
Dries committed
506 507 508 509 510 511
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\"";
Dries's avatar
 
Dries committed
512 513
      }
    }
Dries's avatar
 
Dries committed
514
  }
Dries's avatar
 
Dries committed
515 516
  else {
    $data = $cell;
Dries's avatar
 
Dries committed
517
  }
Dries's avatar
 
Dries committed
518

Dries's avatar
 
Dries committed
519 520
  if ($header) {
    $output = "<th$attributes>$data</th>";
Dries's avatar
 
Dries committed
521
  }
Dries's avatar
 
Dries committed
522 523
  else {
    $output = "<td$attributes>$data</td>";
Dries's avatar
 
Dries committed
524
  }
Dries's avatar
 
Dries committed
525

Dries's avatar
 
Dries committed
526 527
  return $output;
}
Dries's avatar
 
Dries committed
528
?>