1<?php 2/** 3 * DokuWiki Congrid Template: template functions 4 * 5 * @author LarsDW223 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 */ 8 9// must be run from within DokuWiki 10if (!defined('DOKU_INC')) die(); 11 12require_once(dirname(__FILE__).'/tpl_default.php'); 13 14/* The type is well-known and by it's name it is clear what to do, 15 e.g. 'title', 'content', 'sitetools'... */ 16define(TEMPLATE_KNOWN_TYPE, 1); 17/* The type is unknown and it is not clear what to do. 18 An empty cell will be rendered with some error text. */ 19define(TEMPLATE_INVALID_TYPE, 2); 20/* The type is not known but is a container for other items 21 which could be pages or well-known types. */ 22define(TEMPLATE_CONTAINER_ITEMS, 3); 23/* The type is not known but defines a page which shall be rendered. 24 This can e.g. be used to render the sidebar. */ 25define(TEMPLATE_CONTAINER_PAGES, 4); 26 27/** 28 * Check if the given selector matches the current requests context. 29 * 30 * The selector may include the following simple comparisons: 31 * - "do==value": 32 * value must match the 'do' parameter of the current request URL 33 * - "do!=value": 34 * value must NOT match the 'do' parameter of the current request URL 35 * - "ID==value": 36 * value must match the current page ID 37 * - "ID!=value": 38 * value must NOT match the current page ID 39 * - "page==value": 40 * value must match the 'page' parameter of the current request URL 41 * - "page!=value": 42 * value must NOT match the 'page' parameter of the current request URL 43 * - "ACT==value": 44 * value must match the current action ($ACT) 45 * - "ACT!=value": 46 * value must NOT match the current action ($ACT) 47 * 48 * Multiple comparisons can be given separated by spaces. In this case all 49 * comparisons must be matched to let the whole selector match (logical and). 50 * 51 * The return value 0 means no match. Numbers higher than 0 means a match. 52 * A higher number means a more specific match. 53 * 54 * @param string $selector 55 * @return integer 56 */ 57function tpl_selector_matches($selector) { 58 global $INPUT; 59 global $ID; 60 global $ACT; 61 62 $parts = explode(' ', $selector); 63 $match = 0; 64 $match_count = 0; 65 foreach ($parts as $part) { 66 if ($part == '*') { 67 $match += 1; 68 $match_count++; 69 } else { 70 $part = str_replace(' ', '', $part); 71 if (strncmp($part, 'do==', 4) == 0) { 72 $value = substr($part, 4); 73 if ($INPUT->str('do') == $value) { 74 $match += 2; 75 $match_count++; 76 } 77 } else if (strncmp($part, 'do!=', 4) == 0) { 78 $value = substr($part, 4); 79 if ($INPUT->str('do') != $value) { 80 $match += 2; 81 $match_count++; 82 } 83 } else if (strncmp($part, 'ID==', 4) == 0) { 84 $value = substr($part, 4); 85 if ($ID == $value) { 86 $match += 2; 87 $match_count++; 88 } 89 } else if (strncmp($part, 'ID!=', 4) == 0) { 90 $value = substr($part, 4); 91 if ($ID != $value) { 92 $match += 2; 93 $match_count++; 94 } 95 } else if (strncmp($part, 'page==', 6) == 0) { 96 $value = substr($part, 6); 97 if ($INPUT->str('page') == $value) { 98 $match += 2; 99 $match_count++; 100 } 101 } else if (strncmp($part, 'page!=', 6) == 0) { 102 $value = substr($part, 6); 103 if ($INPUT->str('page') != $value) { 104 $match += 2; 105 $match_count++; 106 } 107 } else if (strncmp($part, 'ACT==', 5) == 0) { 108 $value = substr($part, 5); 109 if ($ACT == $value) { 110 $match += 2; 111 $match_count++; 112 } 113 } else if (strncmp($part, 'ACT!=', 5) == 0) { 114 $value = substr($part, 5); 115 if ($ACT != $value) { 116 $match += 2; 117 $match_count++; 118 } 119 } 120 } 121 } 122 123 if ($match_count == count($parts)) { 124 // All parts matched 125 return $match; 126 } 127 128 // No match or only partial match 129 return 0; 130} 131/** 132 * Select the layout to use as specified in the template's configuration. 133 * 134 * The function JSON decodes the config parameter 'Layouts', selects 135 * the best match and returns the array (Layouts[x]). 136 * 137 * @return array|NULL 138 */ 139function tpl_get_layout() { 140 global $default_layout; 141 global $conf; 142 143 $config = tpl_getConf('Layouts', NULL); 144 if (empty($config)) { 145 $config = $default_layout; 146 } 147 148 $layouts = json_decode($config, true); 149 if ($layouts === NULL) { 150 $layouts = json_decode($default_layout, true); 151 } 152 $layouts = $layouts['layouts']; 153 154 // Go through all selectors and return the best match 155 $best = 0; 156 $best_layout = NULL; 157 for ($index = 0 ; $index < count($layouts) ; $index++) { 158 foreach ($layouts[$index]['select'] as $select) { 159 $match = tpl_selector_matches($select); 160 if ($match > $best) { 161 $best = $match; 162 $best_layout = &$layouts[$index]; 163 } 164 } 165 } 166 167 if ($best > 0) { 168 return $best_layout; 169 } 170 171 // Nothing found! 172 return NULL; 173} 174/** 175 * Check if $name refers to a build-in background and return the 176 * corresponding CSS class name. If $name is unknown, NULL will be returned. 177 * 178 * @param string $name Config-name of the background 179 * @return string|NULL 180 */ 181function tpl_get_background_class($name) { 182 /* Add backgrounds here. 183 For the class name '-' will be replaced with '_'! */ 184 $backgrounds = array('weave', 'upholstery', 'bricks', 'diagonal-stripes', 185 'tablecloth', 'waves', 'lined-paper', 186 'blueprint-grid', 'cicada-stripes', 'honey-comb', 187 'cross-dots', 'cross', 'tartan', 'japanese-cube'); 188 189 if (in_array($name, $backgrounds)) { 190 return str_replace('-', '_', $name); 191 } 192 return NULL; 193} 194/** 195 * Print the opening of the <body> element as specified by @$layout. 196 */ 197function tpl_print_body(array $layout) { 198 $body_class = tpl_get_background_class($layout['background']); 199 if (!empty($body_class)) { 200 print('<body class="'.$body_class.'">'); 201 } else { 202 print('<body>'); 203 } 204} 205/** 206 * Print/generate the 'title' section. 207 */ 208function tpl_generate_title() { 209 global $conf; 210 211 // Get logo either out of the template images folder or data/media folder 212 $logo = tpl_getMediaFile(array(':wiki:logo.png', ':logo.png', 'images/logo.png'), false, $logoSize); 213 $title = $conf['title']; 214 //$tagline = ($conf['tagline']) ? '<span id="dw__tagline">'.$conf['tagline'].'</span>' : ''; 215 216 // Display logo and wiki title in a link to the home page 217 $home = wl(); 218 tpl_link($home, 219 '<img src="'.$logo.'" alt="'.$title.'" id="dw__logo" /><span id="dw__title">'.$title.'</span>', 220 'accesskey="h" title="[H]"'); 221 tpl_flush(); 222} 223/** 224 * Print/generate the 'tagline' section. 225 */ 226function tpl_generate_tagline() { 227 global $conf; 228 229 if ($conf['tagline']) { 230 print('<span id="dw__tagline">'.$conf['tagline'].'</span>'); 231 } 232 tpl_flush(); 233} 234/** 235 * Print/generate the 'trace' section. 236 */ 237function tpl_generate_trace() { 238 global $conf; 239 240 if ($conf['breadcrumbs']) { 241 $sep = tpl_getConf('BreadcrumbsSep', NULL); 242 tpl_breadcrumbs($sep); 243 } 244 tpl_flush(); 245} 246/** 247 * Print/generate the 'youarehere' section. 248 */ 249function tpl_generate_youarehere() { 250 global $conf; 251 252 if ($conf['youarehere']) { 253 $sep = tpl_getConf('YouAreHereSep', NULL); 254 tpl_youarehere($sep); 255 } 256 tpl_flush(); 257} 258/** 259 * Print/generate the 'search' section. 260 */ 261function tpl_generate_search() { 262 tpl_searchform(); 263 tpl_flush(); 264} 265/** 266 * Print/generate the 'sitetools' section. 267 */ 268function tpl_generate_sitetools() { 269 print('<h3 class="a11y">'.$lang['site_tools'].'</h3>'); 270 271 // ToDo: for mobile display as drop down 272 //$mobile = (new \dokuwiki\Menu\MobileMenu())->getDropdown($lang['tools']); 273 //print('<div class="mobileTools">'.$mobile.'</div>'); 274 275 $site = (new \dokuwiki\Menu\SiteMenu())->getListItems('action ', false); 276 print ('<ul>'.$site.'</ul>'); 277 tpl_flush(); 278} 279/** 280 * Print/generate the 'usertools' section. 281 */ 282function tpl_generate_usertools() { 283 global $conf; 284 285 if ($conf['useacl']) { 286 print('<h3 class="a11y">'.$lang['user_tools'].'</h3>'); 287 print('<ul>'); 288 if (!empty($_SERVER['REMOTE_USER'])) { 289 print('<li class="user">'); 290 291 /* 'Logged in as ...' */ 292 tpl_userinfo(); 293 294 print('</li>'); 295 } 296 print((new \dokuwiki\Menu\UserMenu())->getListItems('action ')); 297 print('</ul>'); 298 } 299 tpl_flush(); 300} 301/** 302 * Print/generate the 'pageid' section. 303 * 304 * @param $inside true=render page ID inside of content section, 305 * false=render page ID in extra div/section, 306 */ 307function tpl_generate_pageid($inside=true) { 308 global $ID; 309 310 if ($inside == true) { 311 print('<div class="pageId inside"><span>'.hsc($ID).'</span></div>'); 312 } else { 313 print('<div class="pageId"><span>'.hsc($ID).'</span></div>'); 314 } 315 tpl_flush(); 316} 317/** 318 * Print/generate the 'docinfo' section. 319 * 320 * @param boolean $inside true=render doc-info inside of content section, 321 * false=render doc-info in extra div/section, 322 */ 323function tpl_generate_docinfo($inside=true) { 324 if ($inside == true) { 325 print('<div class="docInfo inside">'); 326 } else { 327 print('<div class="docInfo">'); 328 } 329 tpl_pageinfo(); 330 print('</div>'); 331 tpl_flush(); 332} 333/** 334 * Print/generate the 'toc' section. 335 * 336 * If this is called then there is an extra div containing the toc. 337 * Most likely 'tpl_generate_content()' was called with $toc == false. 338 */ 339function tpl_generate_toc() { 340 tpl_toc(); 341 tpl_flush(); 342} 343/** 344 * Print/generate the 'content' section. 345 * 346 * If this is called then there is an extra div containing the toc. 347 * Most likely 'tpl_generate_content()' was called with $toc == false. 348 * 349 * @param boolean $page_id Render the page ID section 350 * @param boolean $doc_info Render the doc-info section 351 * @param boolean $toc Render the toc section 352 */ 353function tpl_generate_content($page_id=true, $doc_info=true, $toc=true) { 354 355 // Output any messages created by 'msg(...)' calls 356 html_msgarea(); 357 358 if ($page_id == true) { 359 tpl_generate_pageid(); 360 } 361 362 print('<div id="dokuwiki__page" class="page group">'); 363 tpl_flush(); 364 tpl_includeFile('pageheader.html'); 365 366 // Render the real content/the wiki page 367 print('<div id="dokuwiki__top"></div>'); 368 tpl_content($toc); 369 print('<div id="dokuwiki__bottom"></div>'); 370 371 tpl_includeFile('pagefooter.html'); 372 print('</div>'); 373 374 if ($doc_info == true) { 375 tpl_generate_docinfo(); 376 } 377 378 tpl_flush(); 379} 380/** 381 * Print/generate a 'page' section. 382 * 383 * A page section includes a specific wiki page or HTML page and could e.g. 384 * be used to genertae the sidebar. 385 * 386 * @param array $layout Layout to be used 387 * @param string $page Page name 388 * @param array $params Cell params to apply 389 */ 390function tpl_generate_page(array $layout, $page, $params) { 391 if (!empty($params['headline-string-name'])) { 392 print('<h3>'.$lang[$params['headline-string-name']].'</h3>'); 393 } 394 print ('<div class="content">'); 395 tpl_flush(); 396 if (strpos($page, '.html') !== false) { 397 tpl_includeFile($page); 398 } else { 399 tpl_include_page($page, true, true); 400 } 401 print('</div>'); 402 tpl_flush(); 403} 404/** 405 * Print/generate the 'pagetools' section. 406 */ 407function tpl_generate_pagetools() { 408 print('<h3 class="a11y">'.$lang['page_tools'].'</h3>'); 409 print('<div class="tools">'); 410 print(' <ul>'); 411 print((new \dokuwiki\Menu\PageMenu())->getListItems()); 412 print(' </ul>'); 413 print('</div>'); 414 tpl_flush(); 415} 416/** 417 * Print/generate the 'footer' section. 418 */ 419function tpl_generate_footer() { 420 global $conf; 421 422 /* Generate license text */ 423 tpl_license(''); 424 425 print('<div class="buttons">'); 426 /* license button, no wrapper */ 427 tpl_license('button', true, false, false); 428 $target = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : ''; 429 $basedir = tpl_basedir(); 430 print('<a href="https://www.dokuwiki.org/donate" title="Donate" '.$target.'> 431 <img src="'.$basedir.'images/button-donate.gif" width="80" height="15" alt="Donate" /></a> 432 <a href="https://php.net" title="Powered by PHP" '.$target.'> 433 <img src="'.$basedir.'images/button-php.gif" width="80" height="15" alt="Powered by PHP" /></a> 434 <a href="//validator.w3.org/check/referer" title="Valid HTML5" '.$target.'> 435 <img src="'.$basedir.'images/button-html5.png" width="80" height="15" alt="Valid HTML5" /></a> 436 <a href="//jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS" '.$target.'> 437 <img src="'.$basedir.'images/button-css.png" width="80" height="15" alt="Valid CSS" /></a> 438 <a href="https://dokuwiki.org/" title="Driven by DokuWiki" '.$target.'> 439 <img src="'.$basedir.'images/button-dw.png" width="80" height="15" alt="Driven by DokuWiki" /></a>'); 440 print('</div>'); 441 442 tpl_includeFile('footer.html'); 443} 444/** 445 * Create the grid. 446 * 447 * This function validates the 'grid' array contained in @$layout and 448 * performs adjustment if necessary: 449 * - guarantee an equal amount of columns in each row 450 * - rename 'space' to 'empty' 451 */ 452function tpl_create_grid(&$layout) { 453 // The JSON decoding gives us the grid already as an array. 454 // We just do some checks and adjust the array if necessary 455 456 // Get number of max. columns 457 $max_columns = 0; 458 foreach ($layout['grid'] as $row) { 459 $columns = count($row); 460 if ($columns > 0) { 461 if ($columns > $max_columns) { 462 $max_columns = $columns; 463 } 464 } 465 } 466 467 // Rename 'space' to 'empty' 468 $row = 0; 469 for ($row = 0 ; $row < count($layout['grid']) ; $row++) { 470 $columns = count($layout['grid'][$row]); 471 for ($column = 0 ; $column < $columns ; $column++) { 472 if ($layout['grid'][$row][$column] == 'space') { 473 $layout['grid'][$row][$column] = 'empty'; 474 } 475 } 476 } 477 478 // Validate grid: if there are any rows which do not have a number 479 // of columns equal to $max_columns then fill the row up with 'empty' 480 $index = 0; 481 for ($index = 0 ; $index < count($layout['grid']) ; $index++) { 482 $columns = count($layout['grid'][$index]); 483 if ($columns < $max_columns) { 484 for (;$columns < $max_columns ; $columns++) { 485 $layout['grid'][$index][] = 'empty'; 486 } 487 } 488 } 489} 490/** 491 * Returns the CSS params in @params as an CSS formated string. 492 * 493 * @return string 494 */ 495function tpl_get_css_props(array $params) { 496 // Generate CSS props from cell parameters 497 $css_props = ''; 498 if (is_array($params['css'])) { 499 foreach ($params['css'] as $key => $value) { 500 if ($value !== NULL) { 501 $css_props .= ' '.$key.': '.$value.";\n"; 502 } 503 } 504 } 505 return $css_props; 506} 507/** 508 * Print the grid area and CSS params for @$item. 509 * 510 * $item can be the name of a well-known build-in section like 'title' 511 * or 'content'. Or it can be the name of a user-defined container 512 * which then includes well-known items or pages. 513 * 514 * @param array $layout Layout to use 515 * @param string $item Item type or name to render 516 */ 517function tpl_print_grid_area($layout, $item) { 518 $params = tpl_get_cell_params($layout, $item); 519 520 // Generate CSS props from cell parameters 521 $css_props = tpl_get_css_props($params); 522 523 switch ($item) { 524 case 'sitetools': 525 print("#dokuwiki__site div.dokuwiki__sitetools {\n grid-area: sitetools;\n"); 526 break; 527 case 'usertools': 528 print("#dokuwiki__site div.dokuwiki__usertools {\n grid-area: usertools;\n"); 529 break; 530 case 'pagetools': 531 print("#dokuwiki__site div.dokuwiki__pagetools {\n grid-area: pagetools;\n"); 532 break; 533 case 'title': 534 print("#dokuwiki__site div.dokuwiki__title {\n grid-area: title;\n"); 535 break; 536 case 'tagline': 537 print("#dokuwiki__site div.dokuwiki__tagline {\n grid-area: tagline;\n"); 538 break; 539 case 'trace': 540 print("#dokuwiki__site div.trace { grid-area:\n trace;\n"); 541 break; 542 case 'youarehere': 543 print("#dokuwiki__site div.youarehere {\n grid-area: youarehere;\n"); 544 break; 545 case 'toc': 546 print("#dokuwiki__site div.dokuwiki__toc {\n grid-area: toc;\n"); 547 break; 548 case 'content': 549 print("#dokuwiki__site div.dokuwiki__content {\n grid-area: content;\n"); 550 break; 551 case 'empty': 552 print("#dokuwiki__site div.grid-empty {\n grid-area: empty;\n"); 553 break; 554 case 'search': 555 print("#dokuwiki__site div.search {\n grid-area: search;\n"); 556 break; 557 case 'footer': 558 print("#dokuwiki__site #dokuwiki__footer {\n grid-area: footer;\n"); 559 break; 560 case 'scroll-up-area': 561 print("#dokuwiki__site div.scroll_up_area {\n grid-area: scroll-up-area;\n"); 562 break; 563 case 'scroll-down-area': 564 print("#dokuwiki__site div.scroll_down_area {\n grid-area: scroll-down-area;\n"); 565 break; 566 567 default: 568 if ($params['id'] != 'default') { 569 print("#dokuwiki__site div.".$item." {\n grid-area: ".$item.";\n"); 570 } else { 571 print('<!-- INVALID: div.'.$item.' { grid-area: '.$item.'; } -->'); 572 } 573 break; 574 } 575 if (!empty($css_props)) { 576 print($css_props); 577 } 578 print("}\n"); 579 580 // Also add css props for included items or pages 581 $todo = array(); 582 if (is_array($params['items'])) { 583 $todo = array_merge($todo, $params['items']); 584 } else if (is_array($params['pages'])) { 585 $todo = array_merge($todo, $params['pages']); 586 } 587 foreach ($todo as $name) { 588 $params = tpl_get_cell_params($layout, $name); 589 $css_props = tpl_get_css_props($params); 590 if (!empty($css_props)) { 591 print("#dokuwiki__site div.".$name." {\n".$css_props."}\n"); 592 } 593 } 594} 595/** 596 * Print the main grid definition. 597 * 598 * @param array $layout Layout to use 599 */ 600function tpl_print_grid(array $layout) { 601 $max_rows = count($layout['grid']); 602 $total_vert_space = $layout['grid-vert-space']; 603 if ($max_rows > 1) { 604 $vert_space = round($total_vert_space / ($max_rows - 1)); 605 $row_size = round((100 - $total_vert_space) / $max_rows); 606 } else { 607 $vert_space = 0; 608 $row_size = 100; 609 } 610 611 $max_columns = count($layout['grid'][0]); 612 $total_horiz_space = 10; 613 if ($max_columns > 1) { 614 $horiz_space = round($total_horiz_space / ($max_columns - 1)); 615 $column_size = round((100 - $total_horiz_space) / $max_columns); 616 } else { 617 $horiz_space = 0; 618 $column_size = 100; 619 } 620 621 print("<style>\n"); 622 print("#dokuwiki__site {\n"); 623 print(" display: grid;\n"); 624 print(" height: ".$layout['height'].";\n"); 625 print(" position: relative;\n"); 626 print(" top: ".$layout['top'].";\n"); 627 print(" margin: 0 auto;\n"); 628 print(" grid-column-gap: ".$horiz_space."%;\n"); 629 print(" grid-template-columns:"); 630 for ($column = 0 ; $column < $max_columns ; $column++) { 631 print(" ".$column_size."%"); 632 } 633 print(";\n"); 634 print(" grid-template-rows:"); 635 for ($row = 0 ; $row < $max_rows ; $row++) { 636 print(" ".$row_size."%"); 637 } 638 print(";\n"); 639 print(" grid-row-gap: ".$vert_space."%;\n"); 640 print(" justify-content: center;\n"); 641 print(" grid-template-areas:\n"); 642 643 for ($row = 0 ; $row < count($layout['grid']) ; $row++) { 644 print(" '"); 645 for ($column = 0 ; $column < count($layout['grid'][$row]) ; $column++) { 646 $item = $layout['grid'][$row][$column]; 647 if ($item != 'empty') { 648 print($item); 649 } else { 650 print('.'); 651 } 652 if ($column+1 < count($layout['grid'][$row])) { 653 print(' '); 654 } 655 } 656 if ($row+1 < count($layout['grid'])) { 657 print("'\n"); 658 } else { 659 print("';\n"); 660 } 661 } 662 print(" }\n"); 663 664 $done = array(); 665 for ($row = 0 ; $row < count($layout['grid']) ; $row++) { 666 foreach ($layout['grid'][$row] as $item) { 667 if (array_search($item, $done) === false) { 668 $done[] = $item; 669 tpl_print_grid_area($layout, $item); 670 } 671 } 672 } 673 674 print("</style>\n"); 675 tpl_flush(); 676} 677/** 678 * Print a div/cell's content of the grid. 679 * 680 * This prints the surrounding div and then calls the appropriate 681 * function to generate the content. 682 * 683 * @param array $layout Layout to use 684 * @param string $type Type or name to render 685 * @param string $params Cell params to use 686 * @param $level FIXME: unused for now? Remove it? 687 */ 688function tpl_generate_div(array &$layout, $type, array $params, $level=1) { 689 $divclass = ''; 690 691 if ($params['flex']['direction'] == 'column') { 692 $divclass .= 'flex-column '; 693 if ($params['flex']['mode'] == 'same-size') { 694 $divclass .= ' same_height '; 695 } 696 } else if ($params['flex']['direction'] == 'row') { 697 $divclass .= ' flex-row '; 698 if ($params['flex']['mode'] == 'same-size') { 699 $divclass .= ' same_width '; 700 } 701 } 702 703 // Assign class for item 704 $scroll = ''; 705 $invalid = false; 706 $item_type = TEMPLATE_KNOWN_TYPE; 707 switch ($type) 708 { 709 case 'title': 710 $divclass .= 'dokuwiki__title'; 711 break; 712 713 case 'tagline': 714 $divclass .= 'dokuwiki__tagline'; 715 break; 716 717 case 'toc': 718 $divclass .= 'dokuwiki__toc'; 719 break; 720 721 case 'content': 722 $divclass .= 'dokuwiki__content'; 723 break; 724 725 case 'space': 726 $divclass .= 'grid-empty'; 727 break; 728 729 case 'trace': 730 $divclass .= 'trace'; 731 break; 732 733 case 'youarehere': 734 $divclass .= 'youarehere'; 735 break; 736 737 case 'sitetools': 738 $divclass .= 'dokuwiki__sitetools toolslist'; 739 break; 740 741 case 'usertools': 742 $divclass .= 'dokuwiki__usertools toolslist'; 743 break; 744 745 case 'pagetools': 746 $divclass .= 'dokuwiki__pagetools toolslist'; 747 break; 748 749 case 'scroll-up-area': 750 $divclass .= 'scroll_up_area'; 751 $scroll = ' onmouseover="scroll_up();" onmouseout="stop_scroll();"'; 752 break; 753 754 case 'scroll-down-area': 755 $divclass .= 'scroll_down_area'; 756 $scroll = ' onmouseover="scroll_down();" onmouseout="stop_scroll();"'; 757 break; 758 759 default: 760 if ($params['id'] == 'default' && empty($params['items']) && 761 empty($params['pages'])) { 762 /* The type is not known and points to the default cell or 763 it points do a different cell but it does not define 764 items or pages to include. */ 765 $item_type = TEMPLATE_INVALID_TYPE; 766 $divclass .= 'grid-invalid'; 767 } else { 768 if (!empty($params['items'])) { 769 $childs = count($params['items']); 770 $item_type = TEMPLATE_CONTAINER_ITEMS; 771 $divclass .= 'container_items '.$params['id']; 772 } else { 773 $childs = count($params['pages']); 774 $item_type = TEMPLATE_CONTAINER_PAGES; 775 $divclass .= 'container_pages '.$params['id']; 776 } 777 $divclass .= ' childs'.$childs; 778 } 779 break; 780 } 781 782 // Assign class for border 783 switch ($params['border']) { 784 case 'user': 785 $divclass .= ' border_TSS'; 786 break; 787 case 'semi-transparent'; 788 $divclass .= ' border_semi_transparent'; 789 break; 790 } 791 792 // Assign class for corners 793 switch ($params['corners']) { 794 case 'round': 795 $divclass .= ' corners_round'; 796 break; 797 } 798 799 // Remove text or icons (e.g. for pagetools) 800 switch ($params['list-type']) { 801 case 'no-text': 802 $divclass .= ' no_text'; 803 break; 804 case 'no-icons': 805 $divclass .= ' no_icons'; 806 break; 807 } 808 809 // Add known background class if set 810 if (!empty($params['background'])) { 811 $background = tpl_get_background_class($params['background']); 812 $divclass .= ' '.$background; 813 } 814 815 if ($type == 'content') { 816 print('<div id="dokuwiki__content" class="'.$divclass.'">'."\n"); 817 } else if ($type == 'footer') { 818 print('<div id="dokuwiki__footer" class="'.$divclass.'">'."\n"); 819 } else { 820 print('<div class="'.$divclass.'"'.$scroll.'>'."\n"); 821 } 822 823 switch ($type) 824 { 825 case 'toc': 826 tpl_generate_toc(); 827 break; 828 829 case 'content': 830 $toc = false; 831 if (empty($layout['toc']) || $layout['toc'] == 'on-page') { 832 $toc = true; 833 } 834 tpl_generate_content(true, true, $toc); 835 break; 836 837 case 'title': 838 tpl_generate_title(); 839 break; 840 841 case 'youarehere': 842 tpl_generate_youarehere(); 843 break; 844 845 case 'trace': 846 tpl_generate_trace(); 847 break; 848 849 case 'tagline': 850 tpl_generate_tagline(); 851 break; 852 853 case 'search': 854 tpl_generate_search(); 855 break; 856 857 case 'sitetools': 858 tpl_generate_sitetools(); 859 break; 860 861 case 'usertools': 862 tpl_generate_usertools(); 863 break; 864 865 case 'pagetools': 866 tpl_generate_pagetools(); 867 break; 868 869 case 'footer': 870 tpl_generate_footer(); 871 break; 872 873 case 'scroll-up-area': 874 print('<img src="'.tpl_basedir().'/images/baseline-arrow_upward-24px.svg" alt="Up" />'); 875 break; 876 877 case 'scroll-down-area': 878 print('<img src="'.tpl_basedir().'/images/baseline-arrow_downward-24px.svg" alt="Down" />'); 879 break; 880 881 case 'space': 882 case 'empty': 883 case '.': 884 print('empty'); 885 break; 886 887 default: 888 switch ($item_type) { 889 case TEMPLATE_INVALID_TYPE: 890 print('<div>Invalid cell type ("'.$type.'")</div>'); 891 print('<div>Cell id ("'.$params['id'].'")</div>'); 892 break; 893 case TEMPLATE_CONTAINER_ITEMS: 894 foreach ($params['items'] as $item) { 895 $params = tpl_get_cell_params($layout, $item); 896 tpl_generate_div($layout, $item, $params, $level+1); 897 } 898 break; 899 case TEMPLATE_CONTAINER_PAGES: 900 foreach ($params['pages'] as $page) { 901 $params = tpl_get_cell_params($layout, $page); 902 tpl_generate_page($layout, $page, $params); 903 } 904 break; 905 } 906 break; 907 } 908 909 print('</div>'."\n"); 910} 911/** 912 * Return params set for @$cell in @$layout. 913 * 914 * If no specific params are found for $cell the nthe default params 915 * are returned (from the cell with ID 'default'). 916 * 917 * @param array $layout Layout to use 918 * @param string $cell Type or name to render 919 */ 920function tpl_get_cell_params(array $layout, $cell) { 921 $default = NULL; 922 foreach ($layout['cells'] as $params) { 923 if ($params['id'] == $cell) { 924 // Found params/match 925 return $params; 926 } else if ($params['id'] == 'default') { 927 // Remember default 928 $default = $params; 929 } 930 } 931 932 // No match, return default 933 return $default; 934} 935/** 936 * Generate all cells/divs. 937 * 938 * @param array $layout Layout to use 939 */ 940function tpl_generate_grid_cells(array $layout) { 941 $done = array(); 942 for ($row = 0 ; $row < count($layout['grid']) ; $row++) { 943 foreach ($layout['grid'][$row] as $item) { 944 if (array_search($item, $done) === false) { 945 $done[] = $item; 946 if ($item != 'empty' && $item != 'space') { 947 $params = tpl_get_cell_params($layout, $item); 948 tpl_generate_div($layout, $item, $params); 949 } else { 950 print('<div class="grid-empty"></div>'); 951 } 952 } 953 } 954 } 955} 956/** 957 * Print class attribute for 'dokuwiki__site'. 958 * 959 * @param array $layout Layout to use 960 */ 961function tpl_print_site_class($layout) 962{ 963 $classes = 'dokuwiki'; 964 if (empty($layout['theme'])) { 965 $classes .= ' white'; 966 } else { 967 switch ($layout['theme']) { 968 case 'template-style-settings': 969 $classes .= ' TSS'; 970 break; 971 972 case 'white': 973 $classes .= ' '.$layout['theme']; 974 break; 975 976 default: 977 $classes .= ' white'; 978 break; 979 } 980 } 981 print('class="'.$classes.'"'); 982} 983