theme.inc

  1. Views
    1. 6 theme/theme.inc
    2. 7 theme/theme.inc
  2. drupal
    1. 4.6 includes/theme.inc
    2. 4.7 includes/theme.inc
    3. 5 includes/theme.inc
    4. 6 includes/theme.inc
    5. 7 includes/theme.inc
    6. 8 core/includes/theme.inc

The theme system, which controls the output of Drupal.

The theme system allows for nearly all output of the Drupal system to be customized by user themes.

See also

<a href="http://drupal.org/node/253">Theme system</a>

themeable

Functions & methods

NameDescription
init_themeInitialize the theme system by loading the theme.
list_themesProvides a list of currently available themes.
list_theme_enginesProvides a list of currently available theme engines
path_to_themeReturn the path to the currently selected theme.
themeGenerate the themed representation of a Drupal object.
theme_add_styleAdd a theme stylesheet to be included later. This is handled separately from drupal_set_html_head() to enforce the correct CSS cascading order.
theme_blockReturn a themed block.
theme_blocksReturn a set of blocks available for the current user.
theme_boxReturn a themed box.
theme_breadcrumbReturn a themed breadcrumb trail.
theme_closureExecute hook_footer() which is run at the end of the page right before the close of the body tag.
theme_feed_iconReturn code that emits an feed icon.
theme_form_elementReturn a themed form element.
theme_get_functionDetermine if a theme function exists, and if so return which one was found.
theme_get_settingRetrieve a setting for the current theme. This function is designed for use from within themes & engines to determine theme settings made in the admin interface.
theme_get_settingsRetrieve an associative array containing the settings for a theme.
theme_get_stylesReturn the HTML for a theme's stylesheets.
theme_helpReturn a themed help message.
theme_imageReturn a themed image.
theme_item_listReturn a themed list of items.
theme_linksReturn a themed set of links.
theme_maintenance_page
theme_markReturn a themed marker, useful for marking new or updated content.
theme_more_help_linkReturns code that emits the 'more help'-link.
theme_nodeReturn a themed node.
theme_pageReturn an entire Drupal page displaying the supplied content.
theme_placeholderFormat a dynamic text string for emphasized display in a placeholder.
theme_progress_bar
theme_status_messagesReturns themed set of status and/or error messages. The messages are grouped by type.
theme_stylesheet_importImport a stylesheet using @import.
theme_submenuReturn a themed submenu, typically displayed under the tabs.
theme_tableReturn a themed table.
theme_tablesort_indicatorReturn a themed sort icon.
theme_usernameFormat a username.
theme_xml_iconReturn code that emits an XML icon.
_theme_table_cell

Constants

NameDescription
MARK_NEW
MARK_READ@name Content markers
MARK_UPDATED

File

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