PageRenderTime 102ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/profiles/openatrium/themes/tao/template.php

https://gitlab.com/endomorphosis/aegir
PHP | 573 lines | 360 code | 68 blank | 145 comment | 55 complexity | ef22d7a4343c26901938845b42846080 MD5 | raw file
  1. <?php
  2. /**
  3. * Implementation of hook_theme().
  4. */
  5. function tao_theme() {
  6. $items = array();
  7. // Consolidate a variety of theme functions under a single template type.
  8. $items['block'] = array(
  9. 'arguments' => array('block' => NULL),
  10. 'template' => 'object',
  11. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  12. );
  13. $items['box'] = array(
  14. 'arguments' => array('title' => NULL, 'content' => NULL, 'region' => 'main'),
  15. 'template' => 'object',
  16. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  17. );
  18. $items['comment'] = array(
  19. 'arguments' => array('comment' => NULL, 'node' => NULL, 'links' => array()),
  20. 'template' => 'object',
  21. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  22. );
  23. $items['node'] = array(
  24. 'arguments' => array('node' => NULL, 'teaser' => FALSE, 'page' => FALSE),
  25. 'template' => 'node',
  26. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  27. );
  28. $items['fieldset'] = array(
  29. 'arguments' => array('element' => array()),
  30. 'template' => 'fieldset',
  31. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  32. );
  33. // Use a template for form elements
  34. $items['form_element'] = array(
  35. 'arguments' => array('element' => array(), 'value' => NULL),
  36. 'template' => 'form-item',
  37. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  38. );
  39. // Print friendly page headers.
  40. $items['print_header'] = array(
  41. 'arguments' => array(),
  42. 'template' => 'print-header',
  43. 'path' => drupal_get_path('theme', 'tao') .'/templates',
  44. );
  45. // Split out pager list into separate theme function.
  46. $items['pager_list'] = array('arguments' => array(
  47. 'tags' => array(),
  48. 'limit' => 10,
  49. 'element' => 0,
  50. 'parameters' => array(),
  51. 'quantity' => 9,
  52. ));
  53. return $items;
  54. }
  55. /**
  56. * Backport of Drupal 7's drupal_html_class().
  57. */
  58. function tao_drupal_html_class($class) {
  59. return tao_drupal_clean_css_identifier(drupal_strtolower($class));
  60. }
  61. /**
  62. * Backport of Drupal 7's drupal_clean_css_identifier().
  63. */
  64. function tao_drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '')) {
  65. // By default, we filter using Drupal's coding standards.
  66. $identifier = strtr($identifier, $filter);
  67. // Valid characters in a CSS identifier are:
  68. // - the hyphen (U+002D)
  69. // - a-z (U+0030 - U+0039)
  70. // - A-Z (U+0041 - U+005A)
  71. // - the underscore (U+005F)
  72. // - 0-9 (U+0061 - U+007A)
  73. // - ISO 10646 characters U+00A1 and higher
  74. // We strip out any character not in the above list.
  75. $identifier = preg_replace('/[^\x{002D}\x{0030}-\x{0039}\x{0041}-\x{005A}\x{005F}\x{0061}-\x{007A}\x{00A1}-\x{FFFF}]/u', '', $identifier);
  76. return $identifier;
  77. }
  78. /**
  79. * DEPRECATED. CSS exclusion is better handled with positive (yet omitted)
  80. * entries in your .info file.
  81. *
  82. * Strips CSS files from a Drupal CSS array whose filenames start with
  83. * prefixes provided in the $match argument.
  84. */
  85. function tao_css_stripped($match = array('modules/*'), $exceptions = NULL) {
  86. // Set default exceptions
  87. if (!is_array($exceptions)) {
  88. $exceptions = array(
  89. 'modules/color/color.css',
  90. 'modules/locale/locale.css',
  91. 'modules/system/system.css',
  92. 'modules/update/update.css',
  93. 'modules/openid/openid.css',
  94. 'modules/acquia/*',
  95. );
  96. }
  97. $css = drupal_add_css();
  98. $match = implode("\n", $match);
  99. $exceptions = implode("\n", $exceptions);
  100. foreach (array_keys($css['all']['module']) as $filename) {
  101. if (drupal_match_path($filename, $match) && !drupal_match_path($filename, $exceptions)) {
  102. unset($css['all']['module'][$filename]);
  103. }
  104. }
  105. // This servers to move the "all" CSS key to the front of the stack.
  106. // Mainly useful because modules register their CSS as 'all', while
  107. // Tao has a more media handling.
  108. ksort($css);
  109. return $css;
  110. }
  111. /**
  112. * Print all child pages of a book.
  113. */
  114. function tao_print_book_children($node) {
  115. // We use a semaphore here since this function calls and is called by the
  116. // node_view() stack so that it may be called multiple times for a single book tree.
  117. static $semaphore;
  118. if (module_exists('book') && book_type_is_allowed($node->type)) {
  119. if (isset($_GET['print']) && isset($_GET['book_recurse']) && !isset($semaphore)) {
  120. $semaphore = TRUE;
  121. $child_pages = '';
  122. $zomglimit = 0;
  123. $tree = array_shift(book_menu_subtree_data($node->book));
  124. if (!empty($tree['below'])) {
  125. foreach ($tree['below'] as $link) {
  126. _tao_print_book_children($link, $child_pages, $zomglimit);
  127. }
  128. }
  129. unset($semaphore);
  130. return $child_pages;
  131. }
  132. }
  133. return '';
  134. }
  135. /**
  136. * Book printing recursion.
  137. */
  138. function _tao_print_book_children($link, &$content, &$zomglimit, $limit = 500) {
  139. if ($zomglimit < $limit) {
  140. $zomglimit++;
  141. if (!empty($link['link']['nid'])) {
  142. $node = node_load($link['link']['nid']);
  143. if ($node) {
  144. $content .= node_view($node);
  145. }
  146. if (!empty($link['below'])) {
  147. foreach ($link['below'] as $child) {
  148. _tao_print_book_children($child, $content);
  149. }
  150. }
  151. }
  152. }
  153. }
  154. /**
  155. * Preprocess functions ===============================================
  156. */
  157. /**
  158. * Implementation of preprocess_page().
  159. */
  160. function tao_preprocess_page(&$vars) {
  161. $attr = array();
  162. $attr['class'] = $vars['body_classes'];
  163. $attr['class'] .= ' tao'; // Add the tao class so that we can avoid using the 'body' selector
  164. // Replace screen/all stylesheets with print
  165. // We want a minimal print representation here for full control.
  166. if (isset($_GET['print'])) {
  167. $css = drupal_add_css();
  168. unset($css['all']);
  169. unset($css['screen']);
  170. $css['all'] = $css['print'];
  171. $vars['styles'] = drupal_get_css($css);
  172. // Add print header
  173. $vars['print_header'] = theme('print_header');
  174. // Replace all body classes
  175. $attr['class'] = 'print';
  176. // Use print template
  177. $vars['template_file'] = 'print-page';
  178. // Suppress devel output
  179. $GLOBALS['devel_shutdown'] = FALSE;
  180. }
  181. // Split primary and secondary local tasks
  182. $vars['tabs'] = theme('menu_local_tasks', 'primary');
  183. $vars['tabs2'] = theme('menu_local_tasks', 'secondary');
  184. // Link site name to frontpage
  185. $vars['site_name'] = l($vars['site_name'], '<front>');
  186. // Don't render the attributes yet so subthemes can alter them
  187. $vars['attr'] = $attr;
  188. // Skip navigation links (508).
  189. $vars['skipnav'] = "<a id='skipnav' href='#content'>" . t('Skip navigation') ."</a>";
  190. }
  191. /**
  192. * Implementation of preprocess_block().
  193. */
  194. function tao_preprocess_block(&$vars) {
  195. // Hide blocks with no content.
  196. $vars['hide'] = empty($vars['block']->content);
  197. $attr = array();
  198. $attr['id'] = "block-{$vars['block']->module}-{$vars['block']->delta}";
  199. $attr['class'] = "block block-{$vars['block']->module}";
  200. $vars['attr'] = $attr;
  201. $vars['hook'] = 'block';
  202. $vars['title'] = !empty($vars['block']->subject) ? $vars['block']->subject : '';
  203. $vars['content'] = $vars['block']->content;
  204. $vars['is_prose'] = ($vars['block']->module == 'block') ? TRUE : FALSE;
  205. }
  206. /**
  207. * Implementation of preprocess_box().
  208. */
  209. function tao_preprocess_box(&$vars) {
  210. $attr = array();
  211. $attr['class'] = "box";
  212. $vars['attr'] = $attr;
  213. $vars['hook'] = 'box';
  214. }
  215. /**
  216. * Implementation of preprocess_node().
  217. */
  218. function tao_preprocess_node(&$vars) {
  219. $attr = array();
  220. $attr['id'] = "node-{$vars['node']->nid}";
  221. $attr['class'] = "node node-{$vars['node']->type}";
  222. $attr['class'] .= $vars['node']->sticky ? ' sticky' : '';
  223. $vars['attr'] = $attr;
  224. $vars['hook'] = 'node';
  225. $vars['is_prose'] = TRUE;
  226. // Add print customizations
  227. if (isset($_GET['print'])) {
  228. $vars['post_object'] = tao_print_book_children($vars['node']);
  229. }
  230. }
  231. /**
  232. * Implementation of preprocess_comment().
  233. */
  234. function tao_preprocess_comment(&$vars) {
  235. $attr = array();
  236. $attr['id'] = "comment-{$vars['comment']->cid}";
  237. $attr['class'] = "comment {$vars['status']}";
  238. $vars['attr'] = $attr;
  239. $vars['hook'] = 'comment';
  240. $vars['is_prose'] = TRUE;
  241. }
  242. /**
  243. * Implementation of preprocess_fieldset().
  244. */
  245. function tao_preprocess_fieldset(&$vars) {
  246. $element = $vars['element'];
  247. $attr = isset($element['#attributes']) ? $element['#attributes'] : array();
  248. $attr['class'] = !empty($attr['class']) ? $attr['class'] : '';
  249. $attr['class'] .= ' fieldset';
  250. $attr['class'] .= !empty($element['#title']) ? ' titled' : '';
  251. $attr['class'] .= !empty($element['#collapsible']) ? ' collapsible' : '';
  252. $attr['class'] .= !empty($element['#collapsible']) && !empty($element['#collapsed']) ? ' collapsed' : '';
  253. $vars['attr'] = $attr;
  254. $description = !empty($element['#description']) ? "<div class='description'>{$element['#description']}</div>" : '';
  255. $children = !empty($element['#children']) ? $element['#children'] : '';
  256. $value = !empty($element['#value']) ? $element['#value'] : '';
  257. $vars['content'] = $description . $children . $value;
  258. $vars['title'] = !empty($element['#title']) ? $element['#title'] : '';
  259. if (!empty($element['#collapsible'])) {
  260. $vars['title'] = l(filter_xss_admin($vars['title']), $_GET['q'], array('fragment' => 'fieldset', 'html' => TRUE));
  261. }
  262. $vars['hook'] = 'fieldset';
  263. }
  264. /**
  265. * Implementation of preprocess_form_element().
  266. * Take a more sensitive/delineative approach toward theming form elements.
  267. */
  268. function tao_preprocess_form_element(&$vars) {
  269. $element = $vars['element'];
  270. // Main item attributes.
  271. $vars['attr'] = array();
  272. $vars['attr']['class'] = 'form-item';
  273. $vars['attr']['id'] = !empty($element['#id']) ? "{$element['#id']}-wrapper" : NULL;
  274. if (!empty($element['#type']) && in_array($element['#type'], array('checkbox', 'radio'))) {
  275. $vars['attr']['class'] .= ' form-option';
  276. }
  277. $vars['description'] = isset($element['#description']) ? $element['#description'] : '';
  278. // Generate label markup
  279. if (!empty($element['#title'])) {
  280. $t = get_t();
  281. $required_title = $t('This field is required.');
  282. $required = !empty($element['#required']) ? "<span class='form-required' title='{$required_title}'>*</span>" : '';
  283. $vars['label_title'] = $t('!title: !required', array('!title' => filter_xss_admin($element['#title']), '!required' => $required));
  284. $vars['label_attr'] = array();
  285. if (!empty($element['#id'])) {
  286. $vars['label_attr']['for'] = $element['#id'];
  287. }
  288. // Indicate that this form item is labeled
  289. $vars['attr']['class'] .= ' form-item-labeled';
  290. }
  291. }
  292. /**
  293. * Preprocessor for theme_print_header().
  294. */
  295. function tao_preprocess_print_header(&$vars) {
  296. $vars = array(
  297. 'base_path' => base_path(),
  298. 'theme_path' => base_path() .'/'. path_to_theme(),
  299. 'site_name' => variable_get('site_name', 'Drupal'),
  300. );
  301. $count ++;
  302. }
  303. /**
  304. * Function overrides =================================================
  305. */
  306. /**
  307. * Override of theme_menu_local_tasks().
  308. * Add argument to allow primary/secondary local tasks to be printed
  309. * separately. Use theme_links() markup to consolidate.
  310. */
  311. function tao_menu_local_tasks($type = '') {
  312. if ($primary = menu_primary_local_tasks()) {
  313. $primary = "<ul class='links primary-tabs'>{$primary}</ul>";
  314. }
  315. if ($secondary = menu_secondary_local_tasks()) {
  316. $secondary = "<ul class='links secondary-tabs'>$secondary</ul>";
  317. }
  318. switch ($type) {
  319. case 'primary':
  320. return $primary;
  321. case 'secondary':
  322. return $secondary;
  323. default:
  324. return $primary . $secondary;
  325. }
  326. }
  327. /**
  328. * Override of theme_file().
  329. * Reduces the size of upload fields which are by default far too long.
  330. */
  331. function tao_file($element) {
  332. _form_set_class($element, array('form-file'));
  333. $attr = $element['#attributes'] ? ' '. drupal_attributes($element['#attributes']) : '';
  334. return theme('form_element', $element, "<input type='file' name='{$element['#name']}' id='{$element['#id']}' size='15' {$attr} />");
  335. }
  336. /**
  337. * Override of theme_blocks().
  338. * Allows additional theme functions to be defined per region to
  339. * control block display on a per-region basis. Falls back to default
  340. * block region handling if no region-specific overrides are found.
  341. */
  342. function tao_blocks($region) {
  343. // Allow theme functions some additional control over regions.
  344. $registry = theme_get_registry();
  345. if (isset($registry['blocks_'. $region])) {
  346. return theme('blocks_'. $region);
  347. }
  348. return module_exists('context') && function_exists('context_blocks') ? context_blocks($region) : theme_blocks($region);
  349. }
  350. /**
  351. * Override of theme_username().
  352. */
  353. function tao_username($object) {
  354. if (!empty($object->name)) {
  355. // Shorten the name when it is too long or it will break many tables.
  356. $name = drupal_strlen($object->name) > 20 ? drupal_substr($object->name, 0, 15) .'...' : $object->name;
  357. $name = check_plain($name);
  358. // Default case -- we have a real Drupal user here.
  359. if ($object->uid && user_access('access user profiles')) {
  360. return l($name, 'user/'. $object->uid, array('attributes' => array('class' => 'username', 'title' => t('View user profile.'))));
  361. }
  362. // Handle cases where user is not registered but has a link or name available.
  363. else if (!empty($object->homepage)) {
  364. return l($name, $object->homepage, array('attributes' => array('class' => 'username', 'rel' => 'nofollow')));
  365. }
  366. // Produce an unlinked username.
  367. else {
  368. return "<span class='username'>{$name}</span>";
  369. }
  370. }
  371. return "<span class='username'>". variable_get('anonymous', t('Anonymous')) ."</span>";
  372. }
  373. /**
  374. * Override of theme_pager().
  375. * Easily one of the most obnoxious theming jobs in Drupal core.
  376. * Goals: consolidate functionality into less than 5 functions and
  377. * ensure the markup will not conflict with major other styles
  378. * (theme_item_list() in particular).
  379. */
  380. function tao_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
  381. $pager_list = theme('pager_list', $tags, $limit, $element, $parameters, $quantity);
  382. $links = array();
  383. $links['pager-first'] = theme('pager_first', ($tags[0] ? $tags[0] : t('First')), $limit, $element, $parameters);
  384. $links['pager-previous'] = theme('pager_previous', ($tags[1] ? $tags[1] : t('Prev')), $limit, $element, 1, $parameters);
  385. $links['pager-next'] = theme('pager_next', ($tags[3] ? $tags[3] : t('Next')), $limit, $element, 1, $parameters);
  386. $links['pager-last'] = theme('pager_last', ($tags[4] ? $tags[4] : t('Last')), $limit, $element, $parameters);
  387. $links = array_filter($links);
  388. $pager_links = theme('links', $links, array('class' => 'links pager pager-links'));
  389. if ($pager_list) {
  390. return "<div class='pager clear-block'>$pager_list $pager_links</div>";
  391. }
  392. }
  393. /**
  394. * Split out page list generation into its own function.
  395. */
  396. function tao_pager_list($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
  397. global $pager_page_array, $pager_total, $theme_key;
  398. if ($pager_total[$element] > 1) {
  399. // Calculate various markers within this pager piece:
  400. // Middle is used to "center" pages around the current page.
  401. $pager_middle = ceil($quantity / 2);
  402. // current is the page we are currently paged to
  403. $pager_current = $pager_page_array[$element] + 1;
  404. // first is the first page listed by this pager piece (re quantity)
  405. $pager_first = $pager_current - $pager_middle + 1;
  406. // last is the last page listed by this pager piece (re quantity)
  407. $pager_last = $pager_current + $quantity - $pager_middle;
  408. // max is the maximum page number
  409. $pager_max = $pager_total[$element];
  410. // End of marker calculations.
  411. // Prepare for generation loop.
  412. $i = $pager_first;
  413. if ($pager_last > $pager_max) {
  414. // Adjust "center" if at end of query.
  415. $i = $i + ($pager_max - $pager_last);
  416. $pager_last = $pager_max;
  417. }
  418. if ($i <= 0) {
  419. // Adjust "center" if at start of query.
  420. $pager_last = $pager_last + (1 - $i);
  421. $i = 1;
  422. }
  423. // End of generation loop preparation.
  424. $links = array();
  425. // When there is more than one page, create the pager list.
  426. if ($i != $pager_max) {
  427. // Now generate the actual pager piece.
  428. for ($i; $i <= $pager_last && $i <= $pager_max; $i++) {
  429. if ($i < $pager_current) {
  430. $links["$i pager-item"] = theme('pager_previous', $i, $limit, $element, ($pager_current - $i), $parameters);
  431. }
  432. if ($i == $pager_current) {
  433. $links["$i pager-current"] = array('title' => $i);
  434. }
  435. if ($i > $pager_current) {
  436. $links["$i pager-item"] = theme('pager_next', $i, $limit, $element, ($i - $pager_current), $parameters);
  437. }
  438. }
  439. return theme('links', $links, array('class' => 'links pager pager-list'));
  440. }
  441. }
  442. return '';
  443. }
  444. /**
  445. * Return an array suitable for theme_links() rather than marked up HTML link.
  446. */
  447. function tao_pager_link($text, $page_new, $element, $parameters = array(), $attributes = array()) {
  448. $page = isset($_GET['page']) ? $_GET['page'] : '';
  449. if ($new_page = implode(',', pager_load_array($page_new[$element], $element, explode(',', $page)))) {
  450. $parameters['page'] = $new_page;
  451. }
  452. $query = array();
  453. if (count($parameters)) {
  454. $query[] = drupal_query_string_encode($parameters, array());
  455. }
  456. $querystring = pager_get_querystring();
  457. if ($querystring != '') {
  458. $query[] = $querystring;
  459. }
  460. // Set each pager link title
  461. if (!isset($attributes['title'])) {
  462. static $titles = NULL;
  463. if (!isset($titles)) {
  464. $titles = array(
  465. t('« first') => t('Go to first page'),
  466. t('‹ previous') => t('Go to previous page'),
  467. t('next ›') => t('Go to next page'),
  468. t('last »') => t('Go to last page'),
  469. );
  470. }
  471. if (isset($titles[$text])) {
  472. $attributes['title'] = $titles[$text];
  473. }
  474. else if (is_numeric($text)) {
  475. $attributes['title'] = t('Go to page @number', array('@number' => $text));
  476. }
  477. }
  478. return array(
  479. 'title' => $text,
  480. 'href' => $_GET['q'],
  481. 'attributes' => $attributes,
  482. 'query' => count($query) ? implode('&', $query) : NULL,
  483. );
  484. }
  485. /**
  486. * Override of theme_views_mini_pager().
  487. */
  488. function tao_views_mini_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
  489. global $pager_page_array, $pager_total;
  490. // Calculate various markers within this pager piece:
  491. // Middle is used to "center" pages around the current page.
  492. $pager_middle = ceil($quantity / 2);
  493. // current is the page we are currently paged to
  494. $pager_current = $pager_page_array[$element] + 1;
  495. // max is the maximum page number
  496. $pager_max = $pager_total[$element];
  497. // End of marker calculations.
  498. $links = array();
  499. if ($pager_total[$element] > 1) {
  500. $links['pager-previous'] = theme('pager_previous', (isset($tags[1]) ? $tags[1] : t('‹‹')), $limit, $element, 1, $parameters);
  501. $links['pager-current'] = array('title' => t('@current of @max', array('@current' => $pager_current, '@max' => $pager_max)));
  502. $links['pager-next'] = theme('pager_next', (isset($tags[3]) ? $tags[3] : t('››')), $limit, $element, 1, $parameters);
  503. return theme('links', $links, array('class' => 'links pager views-mini-pager'));
  504. }
  505. }