[ Index ] |
|
Code source de Drupal 5.3 |
1 <?php 2 // $Id: theme.inc,v 1.337.2.2 2007/05/31 05:52:42 drumm Exp $ 3 4 /** 5 * @file 6 * The theme system, which controls the output of Drupal. 7 * 8 * The theme system allows for nearly all output of the Drupal system to be 9 * customized by user themes. 10 * 11 * @see <a href="http://drupal.org/node/253">Theme system</a> 12 * @see themeable 13 */ 14 15 /** 16 * @name Content markers 17 * @{ 18 * Markers used by theme_mark() and node_mark() to designate content. 19 * @see theme_mark(), node_mark() 20 */ 21 define('MARK_READ', 0); 22 define('MARK_NEW', 1); 23 define('MARK_UPDATED', 2); 24 /** 25 * @} End of "Content markers". 26 */ 27 28 /** 29 * Initialize the theme system by loading the theme. 30 * 31 */ 32 function init_theme() { 33 global $theme, $user, $custom_theme, $theme_engine, $theme_key; 34 35 // If $theme is already set, assume the others are set, too, and do nothing 36 if (isset($theme)) { 37 return; 38 } 39 40 drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE); 41 $themes = list_themes(); 42 43 // Only select the user selected theme if it is available in the 44 // list of enabled themes. 45 $theme = $user->theme && $themes[$user->theme]->status ? $user->theme : variable_get('theme_default', 'garland'); 46 47 // Allow modules to override the present theme... only select custom theme 48 // if it is available in the list of installed themes. 49 $theme = $custom_theme && $themes[$custom_theme] ? $custom_theme : $theme; 50 51 // Store the identifier for retrieving theme settings with. 52 $theme_key = $theme; 53 54 // If we're using a style, load its appropriate theme, 55 // which is stored in the style's description field. 56 // Also add the stylesheet using drupal_add_css(). 57 // Otherwise, load the theme. 58 if (strpos($themes[$theme]->filename, '.css')) { 59 // File is a style; loads its CSS. 60 // Set theme to its template/theme 61 drupal_add_css($themes[$theme]->filename, 'theme'); 62 $theme = basename(dirname($themes[$theme]->description)); 63 } 64 else { 65 // File is a template/theme 66 // Load its CSS, if it exists 67 if (file_exists($stylesheet = dirname($themes[$theme]->filename) .'/style.css')) { 68 drupal_add_css($stylesheet, 'theme'); 69 } 70 } 71 72 if (strpos($themes[$theme]->filename, '.theme')) { 73 // file is a theme; include it 74 include_once './' . $themes[$theme]->filename; 75 } 76 elseif (strpos($themes[$theme]->description, '.engine')) { 77 // file is a template; include its engine 78 include_once './' . $themes[$theme]->description; 79 $theme_engine = basename($themes[$theme]->description, '.engine'); 80 if (function_exists($theme_engine .'_init')) { 81 call_user_func($theme_engine .'_init', $themes[$theme]); 82 } 83 } 84 } 85 86 /** 87 * Provides a list of currently available themes. 88 * 89 * @param $refresh 90 * Whether to reload the list of themes from the database. 91 * @return 92 * An array of the currently available themes. 93 */ 94 function list_themes($refresh = FALSE) { 95 static $list; 96 97 if ($refresh) { 98 unset($list); 99 } 100 101 if (!$list) { 102 $list = array(); 103 $result = db_query("SELECT * FROM {system} WHERE type = 'theme'"); 104 while ($theme = db_fetch_object($result)) { 105 if (file_exists($theme->filename)) { 106 $list[$theme->name] = $theme; 107 } 108 } 109 } 110 111 return $list; 112 } 113 114 /** 115 * Provides a list of currently available theme engines 116 * 117 * @param $refresh 118 * Whether to reload the list of themes from the database. 119 * @return 120 * An array of the currently available theme engines. 121 */ 122 function list_theme_engines($refresh = FALSE) { 123 static $list; 124 125 if ($refresh) { 126 unset($list); 127 } 128 129 if (!$list) { 130 $list = array(); 131 $result = db_query("SELECT * FROM {system} WHERE type = 'theme_engine' AND status = '1' ORDER BY name"); 132 while ($engine = db_fetch_object($result)) { 133 if (file_exists($engine->filename)) { 134 $list[$engine->name] = $engine; 135 } 136 } 137 } 138 139 return $list; 140 } 141 142 /** 143 * Generate the themed representation of a Drupal object. 144 * 145 * All requests for themed functions must go through this function. It examines 146 * the request and routes it to the appropriate theme function. If the current 147 * theme does not implement the requested function, then the current theme 148 * engine is checked. If neither the engine nor theme implement the requested 149 * function, then the base theme function is called. 150 * 151 * For example, to retrieve the HTML that is output by theme_page($output), a 152 * module should call theme('page', $output). 153 * 154 * @param $function 155 * The name of the theme function to call. 156 * @param ... 157 * Additional arguments to pass along to the theme function. 158 * @return 159 * An HTML string that generates the themed output. 160 */ 161 function theme() { 162 static $functions; 163 $args = func_get_args(); 164 $function = array_shift($args); 165 166 if (!isset($functions[$function])) { 167 $functions[$function] = theme_get_function($function); 168 } 169 if ($functions[$function]) { 170 return call_user_func_array($functions[$function], $args); 171 } 172 } 173 174 /** 175 * Determine if a theme function exists, and if so return which one was found. 176 * 177 * @param $function 178 * The name of the theme function to test. 179 * @return 180 * The name of the theme function that should be used, or FALSE if no function exists. 181 */ 182 function theme_get_function($function) { 183 global $theme, $theme_engine; 184 185 // Because theme() is called a lot, calling init_theme() only to have it 186 // smartly return is a noticeable performance hit. Don't do it. 187 if (!isset($theme)) { 188 init_theme(); 189 } 190 191 if (($theme != '') && function_exists($theme .'_'. $function)) { 192 // call theme function 193 return $theme .'_'. $function; 194 } 195 elseif (($theme != '') && isset($theme_engine) && function_exists($theme_engine .'_'. $function)) { 196 // call engine function 197 return $theme_engine .'_'. $function; 198 } 199 elseif (function_exists('theme_'. $function)){ 200 // call Drupal function 201 return 'theme_'. $function; 202 } 203 return FALSE; 204 } 205 206 /** 207 * Return the path to the currently selected theme. 208 */ 209 function path_to_theme() { 210 global $theme; 211 212 if (!isset($theme)) { 213 init_theme(); 214 } 215 216 $themes = list_themes(); 217 218 return dirname($themes[$theme]->filename); 219 } 220 221 /** 222 * Return the path to the currently selected engine. 223 */ 224 function path_to_engine() { 225 global $theme, $theme_engine; 226 227 if (!isset($theme)) { 228 init_theme(); 229 } 230 231 $engines = list_theme_engines(); 232 233 return dirname($engines[$theme_engine]->filename); 234 } 235 236 /** 237 * Retrieve an associative array containing the settings for a theme. 238 * 239 * The final settings are arrived at by merging the default settings, 240 * the site-wide settings, and the settings defined for the specific theme. 241 * If no $key was specified, only the site-wide theme defaults are retrieved. 242 * 243 * The default values for each of settings are also defined in this function. 244 * To add new settings, add their default values here, and then add form elements 245 * to system_theme_settings() in system.module. 246 * 247 * @param $key 248 * The template/style value for a given theme. 249 * 250 * @return 251 * An associative array containing theme settings. 252 */ 253 function theme_get_settings($key = NULL) { 254 $defaults = array( 255 'mission' => '', 256 'default_logo' => 1, 257 'logo_path' => '', 258 'default_favicon' => 1, 259 'favicon_path' => '', 260 'toggle_logo' => 1, 261 'toggle_favicon' => 1, 262 'toggle_name' => 1, 263 'toggle_search' => 1, 264 'toggle_slogan' => 0, 265 'toggle_mission' => 1, 266 'toggle_node_user_picture' => 0, 267 'toggle_comment_user_picture' => 0, 268 ); 269 270 if (module_exists('node')) { 271 foreach (node_get_types() as $type => $name) { 272 $defaults['toggle_node_info_' . $type] = 1; 273 } 274 } 275 $settings = array_merge($defaults, variable_get('theme_settings', array())); 276 277 if ($key) { 278 $settings = array_merge($settings, variable_get(str_replace('/', '_', 'theme_'. $key .'_settings'), array())); 279 } 280 281 // Only offer search box if search.module is enabled. 282 if (!module_exists('search') || !user_access('search content')) { 283 $settings['toggle_search'] = 0; 284 } 285 286 return $settings; 287 } 288 289 /** 290 * Retrieve a setting for the current theme. 291 * This function is designed for use from within themes & engines 292 * to determine theme settings made in the admin interface. 293 * 294 * Caches values for speed (use $refresh = TRUE to refresh cache) 295 * 296 * @param $setting_name 297 * The name of the setting to be retrieved. 298 * 299 * @param $refresh 300 * Whether to reload the cache of settings. 301 * 302 * @return 303 * The value of the requested setting, NULL if the setting does not exist. 304 */ 305 function theme_get_setting($setting_name, $refresh = FALSE) { 306 global $theme_key; 307 static $settings; 308 309 if (empty($settings) || $refresh) { 310 $settings = theme_get_settings($theme_key); 311 312 $themes = list_themes(); 313 $theme_object = $themes[$theme_key]; 314 315 if ($settings['mission'] == '') { 316 $settings['mission'] = variable_get('site_mission', ''); 317 } 318 319 if (!$settings['toggle_mission']) { 320 $settings['mission'] = ''; 321 } 322 323 if ($settings['toggle_logo']) { 324 if ($settings['default_logo']) { 325 $settings['logo'] = base_path() . dirname($theme_object->filename) .'/logo.png'; 326 } 327 elseif ($settings['logo_path']) { 328 $settings['logo'] = base_path() . $settings['logo_path']; 329 } 330 } 331 332 if ($settings['toggle_favicon']) { 333 if ($settings['default_favicon']) { 334 if (file_exists($favicon = dirname($theme_object->filename) .'/favicon.ico')) { 335 $settings['favicon'] = base_path() . $favicon; 336 } 337 else { 338 $settings['favicon'] = base_path() . 'misc/favicon.ico'; 339 } 340 } 341 elseif ($settings['favicon_path']) { 342 $settings['favicon'] = base_path() . $settings['favicon_path']; 343 } 344 else { 345 $settings['toggle_favicon'] = FALSE; 346 } 347 } 348 } 349 350 return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL; 351 } 352 353 /** 354 * @defgroup themeable Themeable functions 355 * @{ 356 * Functions that display HTML, and which can be customized by themes. 357 * 358 * All functions that produce HTML for display should be themeable. This means 359 * that they should be named with the theme_ prefix, and invoked using theme() 360 * rather than being called directly. This allows themes to override the display 361 * of any Drupal object. 362 * 363 * The theme system is described and defined in theme.inc. 364 */ 365 366 /** 367 * Formats text for emphasized display in a placeholder inside a sentence. 368 * Used automatically by t(). 369 * 370 * @param $text 371 * The text to format (plain-text). 372 * @return 373 * The formatted text (html). 374 */ 375 function theme_placeholder($text) { 376 return '<em>'. check_plain($text) .'</em>'; 377 } 378 379 /** 380 * Return an entire Drupal page displaying the supplied content. 381 * 382 * @param $content 383 * A string to display in the main content area of the page. 384 * @return 385 * A string containing the entire HTML page. 386 */ 387 function theme_page($content) { 388 // Get blocks before so that they can alter the header (JavaScript, Stylesheets etc.) 389 $blocks = theme('blocks', 'all'); 390 391 $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 392 $output .= '<html xmlns="http://www.w3.org/1999/xhtml">'; 393 $output .= '<head>'; 394 $output .= ' <title>'. (drupal_get_title() ? strip_tags(drupal_get_title()) : variable_get('site_name', 'Drupal')) .'</title>'; 395 $output .= drupal_get_html_head(); 396 $output .= drupal_get_css(); 397 $output .= drupal_get_js(); 398 399 $output .= ' </head>'; 400 $output .= ' <body style="background-color: #fff; color: #000;">'; 401 $output .= '<table border="0" cellspacing="4" cellpadding="4"><tr><td style="vertical-align: top; width: 170px;">'; 402 403 $output .= $blocks; 404 $output .= '</td><td style="vertical-align: top;">'; 405 406 $output .= theme('breadcrumb', drupal_get_breadcrumb()); 407 $output .= '<h1>' . drupal_get_title() . '</h1>'; 408 409 if ($tabs = theme('menu_local_tasks')) { 410 $output .= $tabs; 411 } 412 413 $output .= theme('help'); 414 415 $output .= theme('status_messages'); 416 417 $output .= "\n<!-- begin content -->\n"; 418 $output .= $content; 419 $output .= drupal_get_feeds(); 420 $output .= "\n<!-- end content -->\n"; 421 422 $output .= '</td></tr></table>'; 423 $output .= theme('closure'); 424 $output .= '</body></html>'; 425 426 return $output; 427 } 428 429 function theme_maintenance_page($content, $messages = TRUE, $partial = FALSE) { 430 drupal_set_header('Content-Type: text/html; charset=utf-8'); 431 drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() .'misc/maintenance.css";</style>'); 432 drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() . drupal_get_path('module', 'system') .'/defaults.css";</style>'); 433 drupal_set_html_head('<style type="text/css" media="all">@import "'. base_path() . drupal_get_path('module', 'system') .'/system.css";</style>'); 434 drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />'); 435 436 $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 437 $output .= '<html xmlns="http://www.w3.org/1999/xhtml">'; 438 $output .= '<head>'; 439 $output .= ' <title>'. strip_tags(drupal_get_title()) .'</title>'; 440 $output .= drupal_get_html_head(); 441 $output .= drupal_get_js(); 442 $output .= '</head>'; 443 $output .= '<body>'; 444 $output .= '<h1>' . drupal_get_title() . '</h1>'; 445 446 if ($messages) { 447 $output .= theme('status_messages'); 448 } 449 450 $output .= "\n<!-- begin content -->\n"; 451 $output .= $content; 452 $output .= "\n<!-- end content -->\n"; 453 454 if (!$partial) { 455 $output .= '</body></html>'; 456 } 457 458 return $output; 459 } 460 461 function theme_install_page($content) { 462 drupal_set_header('Content-Type: text/html; charset=utf-8'); 463 drupal_add_css('misc/maintenance.css', 'module', 'all', FALSE); 464 drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />'); 465 $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 466 $output .= '<html xmlns="http://www.w3.org/1999/xhtml">'; 467 $output .= '<head>'; 468 $output .= ' <title>'. strip_tags(drupal_get_title()) .'</title>'; 469 $output .= drupal_get_html_head(); 470 $output .= drupal_get_css(); 471 $output .= drupal_get_js(); 472 $output .= '</head>'; 473 $output .= '<body>'; 474 $output .= '<h1>' . drupal_get_title() . '</h1>'; 475 476 $messages = drupal_set_message(); 477 if (isset($messages['error'])) { 478 $title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process'); 479 $output .= '<h3>' .$title. ':</h3>'; 480 $output .= theme('status_messages', 'error'); 481 } 482 483 if (isset($messages['status'])) { 484 $warnings = count($messages['status']) > 1 ? st('The following installation warnings should be carefully reviewed, but in most cases may be safely ignored') : st('The following installation warning should be carefully reviewed, but in most cases may be safely ignored'); 485 $output .= '<h4>' .$title. ':</h4>'; 486 $output .= theme('status_messages', 'status'); 487 } 488 489 $output .= "\n<!-- begin content -->\n"; 490 $output .= $content; 491 $output .= "\n<!-- end content -->\n"; 492 493 $output .= '</body></html>'; 494 495 return $output; 496 } 497 498 /** 499 * Return a themed set of status and/or error messages. The messages are grouped 500 * by type. 501 * 502 * @param $display 503 * (optional) Set to 'status' or 'error' to display only messages of that type. 504 * 505 * @return 506 * A string containing the messages. 507 */ 508 function theme_status_messages($display = NULL) { 509 $output = ''; 510 foreach (drupal_get_messages($display) as $type => $messages) { 511 $output .= "<div class=\"messages $type\">\n"; 512 if (count($messages) > 1) { 513 $output .= " <ul>\n"; 514 foreach ($messages as $message) { 515 $output .= ' <li>'. $message ."</li>\n"; 516 } 517 $output .= " </ul>\n"; 518 } 519 else { 520 $output .= $messages[0]; 521 } 522 $output .= "</div>\n"; 523 } 524 return $output; 525 } 526 527 /** 528 * Return a themed set of links. 529 * 530 * @param $links 531 * A keyed array of links to be themed. 532 * @param $attributes 533 * A keyed array of attributes 534 * @return 535 * A string containing an unordered list of links. 536 */ 537 function theme_links($links, $attributes = array('class' => 'links')) { 538 $output = ''; 539 540 if (count($links) > 0) { 541 $output = '<ul'. drupal_attributes($attributes) .'>'; 542 543 $num_links = count($links); 544 $i = 1; 545 546 foreach ($links as $key => $link) { 547 $class = ''; 548 549 // Automatically add a class to each link and also to each LI 550 if (isset($link['attributes']) && isset($link['attributes']['class'])) { 551 $link['attributes']['class'] .= ' ' . $key; 552 $class = $key; 553 } 554 else { 555 $link['attributes']['class'] = $key; 556 $class = $key; 557 } 558 559 // Add first and last classes to the list of links to help out themers. 560 $extra_class = ''; 561 if ($i == 1) { 562 $extra_class .= 'first '; 563 } 564 if ($i == $num_links) { 565 $extra_class .= 'last '; 566 } 567 $output .= '<li class="'. $extra_class . $class .'">'; 568 569 // Is the title HTML? 570 $html = isset($link['html']) && $link['html']; 571 572 // Initialize fragment and query variables. 573 $link['query'] = isset($link['query']) ? $link['query'] : NULL; 574 $link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL; 575 576 if (isset($link['href'])) { 577 $output .= l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html); 578 } 579 else if ($link['title']) { 580 //Some links are actually not links, but we wrap these in <span> for adding title and class attributes 581 if (!$html) { 582 $link['title'] = check_plain($link['title']); 583 } 584 $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>'; 585 } 586 587 $i++; 588 $output .= "</li>\n"; 589 } 590 591 $output .= '</ul>'; 592 } 593 594 return $output; 595 } 596 597 /** 598 * Return a themed image. 599 * 600 * @param $path 601 * Either the path of the image file (relative to base_path()) or a full URL. 602 * @param $alt 603 * The alternative text for text-based browsers. 604 * @param $title 605 * The title text is displayed when the image is hovered in some popular browsers. 606 * @param $attributes 607 * Associative array of attributes to be placed in the img tag. 608 * @param $getsize 609 * If set to TRUE, the image's dimension are fetched and added as width/height attributes. 610 * @return 611 * A string containing the image tag. 612 */ 613 function theme_image($path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) { 614 if (!$getsize || (is_file($path) && (list($width, $height, $type, $image_attributes) = @getimagesize($path)))) { 615 $attributes = drupal_attributes($attributes); 616 $url = (url($path) == $path) ? $path : (base_path() . $path); 617 return '<img src="'. check_url($url) .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. $image_attributes . $attributes .' />'; 618 } 619 } 620 621 /** 622 * Return a themed breadcrumb trail. 623 * 624 * @param $breadcrumb 625 * An array containing the breadcrumb links. 626 * @return a string containing the breadcrumb output. 627 */ 628 function theme_breadcrumb($breadcrumb) { 629 if (!empty($breadcrumb)) { 630 return '<div class="breadcrumb">'. implode(' » ', $breadcrumb) .'</div>'; 631 } 632 } 633 634 /** 635 * Return a themed help message. 636 * 637 * @return a string containing the helptext for the current page. 638 */ 639 function theme_help() { 640 if ($help = menu_get_active_help()) { 641 return '<div class="help">'. $help .'</div>'; 642 } 643 } 644 645 /** 646 * Return a themed node. 647 * 648 * @param $node 649 * An object providing all relevant information for displaying a node: 650 * - $node->nid: The ID of the node. 651 * - $node->type: The content type (story, blog, forum...). 652 * - $node->title: The title of the node. 653 * - $node->created: The creation date, as a UNIX timestamp. 654 * - $node->teaser: A shortened version of the node body. 655 * - $node->body: The entire node contents. 656 * - $node->changed: The last modification date, as a UNIX timestamp. 657 * - $node->uid: The ID of the author. 658 * - $node->username: The username of the author. 659 * @param $teaser 660 * Whether to display the teaser only, as on the main page. 661 * @param $page 662 * Whether to display the node as a standalone page. If TRUE, do not display 663 * the title because it will be provided by the menu system. 664 * @return 665 * A string containing the node output. 666 */ 667 function theme_node($node, $teaser = FALSE, $page = FALSE) { 668 if (!$node->status) { 669 $output = '<div class="node-unpublished">'; 670 } 671 672 if (module_exists('taxonomy')) { 673 $terms = taxonomy_link('taxonomy terms', $node); 674 } 675 676 if ($page == 0) { 677 $output .= t('!title by !name', array('!title' => '<h2 class="title">'. check_plain($node->title) .'</h2>', '!name' => theme('username', $node))); 678 } 679 else { 680 $output .= t('by !name', array('!name' => theme('username', $node))); 681 } 682 683 if (count($terms)) { 684 $output .= ' <small>('. theme('links', $terms) .')</small><br />'; 685 } 686 687 if ($teaser && $node->teaser) { 688 $output .= $node->teaser; 689 } 690 else { 691 $output .= $node->body; 692 } 693 694 if ($node->links) { 695 $output .= '<div class="links">'. theme('links', $node->links) .'</div>'; 696 } 697 698 if (!$node->status) { 699 $output .= '</div>'; 700 } 701 702 return $output; 703 } 704 705 /** 706 * Return a themed submenu, typically displayed under the tabs. 707 * 708 * @param $links 709 * An array of links. 710 */ 711 function theme_submenu($links) { 712 return '<div class="submenu">'. implode(' | ', $links) .'</div>'; 713 } 714 715 /** 716 * Return a themed table. 717 * 718 * @param $header 719 * An array containing the table headers. Each element of the array can be 720 * either a localized string or an associative array with the following keys: 721 * - "data": The localized title of the table column. 722 * - "field": The database field represented in the table column (required if 723 * user is to be able to sort on this column). 724 * - "sort": A default sort order for this column ("asc" or "desc"). 725 * - Any HTML attributes, such as "colspan", to apply to the column header cell. 726 * @param $rows 727 * An array of table rows. Every row is an array of cells, or an associative 728 * array with the following keys: 729 * - "data": an array of cells 730 * - Any HTML attributes, such as "class", to apply to the table row. 731 * 732 * Each cell can be either a string or an associative array with the following keys: 733 * - "data": The string to display in the table cell. 734 * - "header": Indicates this cell is a header. 735 * - Any HTML attributes, such as "colspan", to apply to the table cell. 736 * 737 * Here's an example for $rows: 738 * @verbatim 739 * $rows = array( 740 * // Simple row 741 * array( 742 * 'Cell 1', 'Cell 2', 'Cell 3' 743 * ), 744 * // Row with attributes on the row and some of its cells. 745 * array( 746 * 'data' => array('Cell 1', array('data' => 'Cell 2', 'colspan' => 2)), 'class' => 'funky' 747 * ) 748 * ); 749 * @endverbatim 750 * 751 * @param $attributes 752 * An array of HTML attributes to apply to the table tag. 753 * @param $caption 754 * A localized string to use for the <caption> tag. 755 * @return 756 * An HTML string representing the table. 757 */ 758 function theme_table($header, $rows, $attributes = array(), $caption = NULL) { 759 $output = '<table'. drupal_attributes($attributes) .">\n"; 760 761 if (isset($caption)) { 762 $output .= '<caption>'. $caption ."</caption>\n"; 763 } 764 765 // Format the table header: 766 if (count($header)) { 767 $ts = tablesort_init($header); 768 $output .= ' <thead><tr>'; 769 foreach ($header as $cell) { 770 $cell = tablesort_header($cell, $header, $ts); 771 $output .= _theme_table_cell($cell, TRUE); 772 } 773 $output .= " </tr></thead>\n"; 774 } 775 776 // Format the table rows: 777 $output .= "<tbody>\n"; 778 if (count($rows)) { 779 $flip = array('even' => 'odd', 'odd' => 'even'); 780 $class = 'even'; 781 foreach ($rows as $number => $row) { 782 $attributes = array(); 783 784 // Check if we're dealing with a simple or complex row 785 if (isset($row['data'])) { 786 foreach ($row as $key => $value) { 787 if ($key == 'data') { 788 $cells = $value; 789 } 790 else { 791 $attributes[$key] = $value; 792 } 793 } 794 } 795 else { 796 $cells = $row; 797 } 798 799 // Add odd/even class 800 $class = $flip[$class]; 801 if (isset($attributes['class'])) { 802 $attributes['class'] .= ' '. $class; 803 } 804 else { 805 $attributes['class'] = $class; 806 } 807 808 // Build row 809 $output .= ' <tr'. drupal_attributes($attributes) .'>'; 810 $i = 0; 811 foreach ($cells as $cell) { 812 $cell = tablesort_cell($cell, $header, $ts, $i++); 813 $output .= _theme_table_cell($cell); 814 } 815 $output .= " </tr>\n"; 816 } 817 } 818 819 $output .= "</tbody></table>\n"; 820 return $output; 821 } 822 823 /** 824 * Returns a header cell for tables that have a select all functionality. 825 */ 826 function theme_table_select_header_cell() { 827 drupal_add_js(array('tableSelect' => array('selectAll' => t('Select all rows in this table'), 'selectNone' => t('Deselect all rows in this table'))), 'setting'); 828 drupal_add_js('misc/tableselect.js'); 829 830 return array('class' => 'select-all'); 831 } 832 833 /** 834 * Return a themed sort icon. 835 * 836 * @param $style 837 * Set to either asc or desc. This sets which icon to show. 838 * @return 839 * A themed sort icon. 840 */ 841 function theme_tablesort_indicator($style) { 842 if ($style == "asc"){ 843 return theme('image', 'misc/arrow-asc.png', t('sort icon'), t('sort ascending')); 844 } 845 else { 846 return theme('image', 'misc/arrow-desc.png', t('sort icon'), t('sort descending')); 847 } 848 } 849 850 /** 851 * Return a themed box. 852 * 853 * @param $title 854 * The subject of the box. 855 * @param $content 856 * The content of the box. 857 * @param $region 858 * The region in which the box is displayed. 859 * @return 860 * A string containing the box output. 861 */ 862 function theme_box($title, $content, $region = 'main') { 863 $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>'; 864 return $output; 865 } 866 867 /** 868 * Return a themed block. 869 * 870 * You can style your blocks by defining .block (all blocks), 871 * .block-<i>module</i> (all blocks of module <i>module</i>), and 872 * \#block-<i>module</i>-<i>delta</i> (specific block of module <i>module</i> 873 * with delta <i>delta</i>) in your theme's CSS. 874 * 875 * @param $block 876 * An object populated with fields from the "blocks" database table 877 * ($block->module, $block->delta ...) and fields returned by 878 * <i>module</i>_block('view') ($block->subject, $block->content, ...). 879 * @return 880 * A string containing the block output. 881 */ 882 function theme_block($block) { 883 $output = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">\n"; 884 $output .= " <h2 class=\"title\">$block->subject</h2>\n"; 885 $output .= " <div class=\"content\">$block->content</div>\n"; 886 $output .= "</div>\n"; 887 return $output; 888 } 889 890 /** 891 * Return a themed marker, useful for marking new or updated 892 * content. 893 * 894 * @param $type 895 * Number representing the marker type to display 896 * @see MARK_NEW, MARK_UPDATED, MARK_READ 897 * @return 898 * A string containing the marker. 899 */ 900 function theme_mark($type = MARK_NEW) { 901 global $user; 902 if ($user->uid) { 903 if ($type == MARK_NEW) { 904 return ' <span class="marker">'. t('new') .'</span>'; 905 } 906 else if ($type == MARK_UPDATED) { 907 return ' <span class="marker">'. t('updated') .'</span>'; 908 } 909 } 910 } 911 912 /** 913 * Return a themed list of items. 914 * 915 * @param $items 916 * An array of items to be displayed in the list. If an item is a string, 917 * then it is used as is. If an item is an array, then the "data" element of 918 * the array is used as the contents of the list item. If an item is an array 919 * with a "children" element, those children are displayed in a nested list. 920 * All other elements are treated as attributes of the list item element. 921 * @param $title 922 * The title of the list. 923 * @param $attributes 924 * The attributes applied to the list element. 925 * @param $type 926 * The type of list to return (e.g. "ul", "ol") 927 * @return 928 * A string containing the list output. 929 */ 930 function theme_item_list($items = array(), $title = NULL, $type = 'ul', $attributes = NULL) { 931 $output = '<div class="item-list">'; 932 if (isset($title)) { 933 $output .= '<h3>'. $title .'</h3>'; 934 } 935 936 if (!empty($items)) { 937 $output .= "<$type" . drupal_attributes($attributes) . '>'; 938 foreach ($items as $item) { 939 $attributes = array(); 940 $children = array(); 941 if (is_array($item)) { 942 foreach ($item as $key => $value) { 943 if ($key == 'data') { 944 $data = $value; 945 } 946 elseif ($key == 'children') { 947 $children = $value; 948 } 949 else { 950 $attributes[$key] = $value; 951 } 952 } 953 } 954 else { 955 $data = $item; 956 } 957 if (count($children) > 0) { 958 $data .= theme_item_list($children, NULL, $type, $attributes); // Render nested list 959 } 960 $output .= '<li' . drupal_attributes($attributes) . '>'. $data .'</li>'; 961 } 962 $output .= "</$type>"; 963 } 964 $output .= '</div>'; 965 return $output; 966 } 967 968 /** 969 * Returns code that emits the 'more help'-link. 970 */ 971 function theme_more_help_link($url) { 972 return '<div class="more-help-link">' . t('[<a href="@link">more help...</a>]', array('@link' => check_url($url))) . '</div>'; 973 } 974 975 /** 976 * Return code that emits an XML icon. 977 */ 978 function theme_xml_icon($url) { 979 if ($image = theme('image', 'misc/xml.png', t('XML feed'), t('XML feed'))) { 980 return '<a href="'. check_url($url) .'" class="xml-icon">'. $image. '</a>'; 981 } 982 } 983 984 /** 985 * Return code that emits an feed icon. 986 */ 987 function theme_feed_icon($url) { 988 if ($image = theme('image', 'misc/feed.png', t('Syndicate content'), t('Syndicate content'))) { 989 return '<a href="'. check_url($url) .'" class="feed-icon">'. $image. '</a>'; 990 } 991 } 992 993 /** 994 * Execute hook_footer() which is run at the end of the page right before the 995 * close of the body tag. 996 * 997 * @param $main (optional) 998 * Whether the current page is the front page of the site. 999 * @return 1000 * A string containing the results of the hook_footer() calls. 1001 */ 1002 function theme_closure($main = 0) { 1003 $footer = module_invoke_all('footer', $main); 1004 return implode("\n", $footer) . drupal_get_js('footer'); 1005 } 1006 1007 /** 1008 * Return a set of blocks available for the current user. 1009 * 1010 * @param $region 1011 * Which set of blocks to retrieve. 1012 * @return 1013 * A string containing the themed blocks for this region. 1014 */ 1015 function theme_blocks($region) { 1016 $output = ''; 1017 1018 if ($list = block_list($region)) { 1019 foreach ($list as $key => $block) { 1020 // $key == <i>module</i>_<i>delta</i> 1021 $output .= theme('block', $block); 1022 } 1023 } 1024 1025 // Add any content assigned to this region through drupal_set_content() calls. 1026 $output .= drupal_get_content($region); 1027 1028 return $output; 1029 } 1030 1031 /** 1032 * Format a username. 1033 * 1034 * @param $object 1035 * The user object to format, usually returned from user_load(). 1036 * @return 1037 * A string containing an HTML link to the user's page if the passed object 1038 * suggests that this is a site user. Otherwise, only the username is returned. 1039 */ 1040 function theme_username($object) { 1041 1042 if ($object->uid && $object->name) { 1043 // Shorten the name when it is too long or it will break many tables. 1044 if (drupal_strlen($object->name) > 20) { 1045 $name = drupal_substr($object->name, 0, 15) .'...'; 1046 } 1047 else { 1048 $name = $object->name; 1049 } 1050 1051 if (user_access('access user profiles')) { 1052 $output = l($name, 'user/'. $object->uid, array('title' => t('View user profile.'))); 1053 } 1054 else { 1055 $output = check_plain($name); 1056 } 1057 } 1058 else if ($object->name) { 1059 // Sometimes modules display content composed by people who are 1060 // not registered members of the site (e.g. mailing list or news 1061 // aggregator modules). This clause enables modules to display 1062 // the true author of the content. 1063 if ($object->homepage) { 1064 $output = l($object->name, $object->homepage); 1065 } 1066 else { 1067 $output = check_plain($object->name); 1068 } 1069 1070 $output .= ' ('. t('not verified') .')'; 1071 } 1072 else { 1073 $output = variable_get('anonymous', t('Anonymous')); 1074 } 1075 1076 return $output; 1077 } 1078 1079 function theme_progress_bar($percent, $message) { 1080 $output = '<div id="progress" class="progress">'; 1081 $output .= '<div class="percentage">'. $percent .'%</div>'; 1082 $output .= '<div class="status">'. $message .'</div>'; 1083 $output .= '<div class="bar"><div class="filled" style="width: '. $percent .'%"></div></div>'; 1084 $output .= '</div>'; 1085 1086 return $output; 1087 } 1088 1089 /** 1090 * @} End of "defgroup themeable". 1091 */ 1092 1093 function _theme_table_cell($cell, $header = FALSE) { 1094 $attributes = ''; 1095 1096 if (is_array($cell)) { 1097 $data = $cell['data']; 1098 $header |= isset($cell['header']); 1099 unset($cell['data']); 1100 unset($cell['header']); 1101 $attributes = drupal_attributes($cell); 1102 } 1103 else { 1104 $data = $cell; 1105 } 1106 1107 if ($header) { 1108 $output = "<th$attributes>$data</th>"; 1109 } 1110 else { 1111 $output = "<td$attributes>$data</td>"; 1112 } 1113 1114 return $output; 1115 } 1116
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Nov 30 16:20:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |