1 <?php 2 if (!defined('DOKU_INC')) die(); /* must be run from within DokuWiki */ 3 4 5 //Library of template function 6 require_once(__DIR__ . '/class/TplUtility.php'); 7 8 use Combostrap\TplUtility; 9 use dokuwiki\Extension\Event; 10 11 12 global $ID; 13 global $lang; 14 global $ACT; 15 global $conf; 16 17 18 /** 19 * The Content first because it contains 20 * also the front matter that may influence the other bars 21 * 22 * If the do action is edit, php plugin uses echo 23 * a lot and the buffer is too small, we got then a buffer overflow 24 * 25 * Other action takes place further where the content should be 26 */ 27 $mainHtml = ""; 28 if ($ACT === 'show') { 29 $mainHtml = TplUtility::tpl_content($prependTOC = false); 30 } 31 32 /** 33 * Sidebar 34 */ 35 $sidebarName = TplUtility::getSideSlotPageName(); 36 37 $nearestSidebar = page_findnearest($sidebarName); 38 $showSideBar = $nearestSidebar !== false && ($ACT === 'show'); 39 if ($showSideBar) { 40 /** 41 * Even if there is no sidebar 42 * the rendering may output 43 * debug information in the form of 44 * an HTML comment 45 */ 46 $sideBarHtml = TplUtility::renderSlot($nearestSidebar); 47 } 48 49 50 /** 51 * Sidekickbar 52 */ 53 $sideKickPageName = TplUtility::getSideKickSlotPageName(); 54 $hasRightSidebar = page_findnearest($sideKickPageName); 55 $showSideKickBar = $hasRightSidebar && ($ACT == 'show'); 56 if ($showSideKickBar) { 57 $sideKickBarHtml = TplUtility::renderSlot($sideKickPageName); 58 } 59 60 /** 61 * Main header and footer 62 */ 63 $nearestMainHeader = page_findnearest(TplUtility::SLOT_MAIN_HEADER_NAME); 64 $showMainHeader = $nearestMainHeader !== false 65 && ($ACT === 'show') 66 && TplUtility::isNotSlot() 67 && TplUtility::isNotRootHome(); 68 if ($showMainHeader !== false) { 69 $mainHeaderHtml = TplUtility::renderSlot($nearestMainHeader); 70 } 71 72 $nearestMainFooter = page_findnearest(TplUtility::SLOT_MAIN_FOOTER_NAME); 73 $showMainFooter = $nearestMainFooter !== false 74 && ($ACT === 'show') 75 && TplUtility::isNotSlot() 76 && TplUtility::isNotRootHome(); 77 if ($showMainFooter !== false) { 78 $mainFooterHtml = TplUtility::renderSlot($nearestMainFooter); 79 } 80 81 82 /** 83 * Headerbar 84 */ 85 $headerBar = TplUtility::getPageHeader(); 86 87 /** 88 * Footerbar 89 */ 90 $footerBar = TplUtility::getFooter(); 91 92 93 /** 94 * Grid 95 */ 96 $gridColumns = tpl_getConf(TplUtility::CONF_GRID_COLUMNS); 97 /** 98 * Layout 99 * 100 * See also: https://1linelayouts.glitch.me/ and https://www.cssportal.com/layout-generator/layout.php 101 * 102 * Two basic layouts for the web: fixed or liquid 103 * A liquid design (also referred to as a fluid or dynamic design) fills the entire browser window by using percentages 104 * rather than fixed pixel values to define the width / height 105 * 106 * dimension = 107 * "fluid" = max-width / min-height 108 * "contained" = 109 * 110 * In fluid web design, the widths of page elements are set proportional to the width of the screen or browser window. 111 * A fluid website expands or contracts based on the width of the current viewport. 112 * 113 * Contained (ie fixed) 114 * https://getbootstrap.com/docs/5.0/layout/containers/ 115 * 116 */ 117 // for the identity forms 118 global $ACT; 119 if (in_array($ACT, ["login", "resendpwd", "register", "profile"])) { 120 $layout = "median"; 121 } else { 122 $layout = p_get_metadata($ID, "layout"); 123 } 124 if ($layout === "median") { 125 $maximalWidthMain = 8; 126 } else { 127 $maximalWidthMain = $gridColumns; 128 } 129 $sidebarScale = 3; 130 $sideKickBarScale = 3; 131 132 switch ($ACT) { 133 case "show": 134 if ($showSideBar) { 135 $mainGridScale = $showSideKickBar ? $gridColumns - $sidebarScale - $sideKickBarScale : $gridColumns - $sidebarScale; 136 } else { 137 $mainGridScale = $showSideKickBar ? $gridColumns - $sideKickBarScale : $maximalWidthMain; 138 } 139 break; 140 default: 141 $mainGridScale = $gridColumns; 142 } 143 144 145 /** 146 * Landing page 147 */ 148 $landingPageGutter = ""; 149 $mainIsContained = true; 150 if ($ACT != "show") { 151 $mainIsContained = true; 152 } else { 153 if ($layout == "landing") { 154 $mainIsContained = false; 155 // No gutter on x otherwise there is a overflow on the right 156 $landingPageGutter = "style=\"--bs-gutter-x: 0\""; 157 } 158 } 159 $mainContainedClasses = ""; 160 if ($mainIsContained) { 161 $mainContainedClasses = "container mb-3"; 162 } 163 164 /** 165 * Bootstrap meta-headers 166 */ 167 TplUtility::registerHeaderHandler(); 168 169 /** 170 * Default rem font size 171 */ 172 $rootStyle = ""; 173 $htmlRem = TplUtility::getRem(); 174 if ($htmlRem != null) { 175 $rootStyle = "style=\"font-size:{$htmlRem}px\""; 176 } 177 178 /** 179 * Railbar 180 * Railbar can add snippet in the head 181 * And should then be could before the HTML output 182 */ 183 $railBar = TplUtility::getRailBar(); 184 185 /** 186 * The output buffer should be empty on show 187 * and can be not empty on other do action 188 */ 189 $outputBuffer = TplUtility::outputBuffer(); 190 191 192 ?> 193 194 <?php // DocType Required: https://getbootstrap.com/docs/5.0/getting-started/introduction/#html5-doctype ?> 195 <!DOCTYPE html > 196 <?php 197 /** 198 * Lang for a page 199 * 200 * https://www.w3.org/International/questions/qa-html-language-declarations 201 * * Always use a language attribute on the html element. 202 * * When serving XHTML 1.x (ie. using a MIME type such as application/xhtml+xml), 203 * use both the lang attribute and the xml:lang attribute together 204 * 205 * See also {@link \ComboStrap\Lang::processLangAttribute()} for the localization of an element 206 * 207 * @var $javascriptRTL - put the button to the end when the page has a language direction of rtl 208 */ 209 $javascriptRTL = ""; 210 if ($lang['direction'] == "rtl") { 211 $javascriptRTL = <<<EOF 212 <script> 213 document.addEventListener('DOMContentLoaded', () => { 214 Array.from(document.getElementsByClassName("secedit")).forEach(e=>e.classList.add('float-end')); 215 } 216 ); 217 </script> 218 EOF; 219 220 } 221 ?> 222 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang'] ?>" lang="<?php echo $conf['lang'] ?>" 223 dir="<?php echo $lang['direction'] ?>" <?php echo $rootStyle ?>> 224 <head> 225 226 <?php // Avoid using character entities in your HTML, provided their encoding matches that of the document (generally UTF-8) ?> 227 <meta charset="utf-8"/> 228 229 <?php // Responsive meta tag ?> 230 <meta name="viewport" content="width=device-width,initial-scale=1"/> 231 232 <?php // Headers ?> 233 <?php tpl_metaheaders() ?> 234 235 <title><?php TplUtility::renderPageTitle() ?></title> 236 237 <?php // Favicon ?> 238 <?php echo TplUtility::renderFaviconMetaLinks() ?> 239 240 <?php 241 /** 242 * In case of a RTL lang, 243 * we put the secedit button to the left 244 */ 245 echo $javascriptRTL; 246 ?> 247 248 <?php 249 /** 250 * When we have a landing page, the railbar 251 * which is by default on the right side is not visible 252 * This setting will set up inside and make it visible alongside the page 253 * We may also just put it completely in the offcanvas 254 * See for the HTML code {@link TplUtility::getRailBar()} 255 */ 256 if ($layout == "landing" & $ACT == "show") { ?> 257 <style> 258 #railbar-fixed { 259 right: 44px !important; 260 } 261 </style> 262 <?php } 263 // slot-combo is relative to position the edit button 264 ?> 265 <style> 266 .slot-combo { 267 position: relative; 268 } 269 </style> 270 271 </head> 272 <?php 273 // * tpl_classes will add the dokuwiki class. See https://www.dokuwiki.org/devel:templates#dokuwiki_class 274 // * dokuwiki__top ID is needed for the "Back to top" utility 275 // * used also by some plugins 276 ?> 277 <body class="dokuwiki"> 278 279 <?php 280 echo $headerBar 281 282 // Relative positioning is important for the positioning of the pagetools 283 ?> 284 <div class="<?php echo $mainContainedClasses ?> <?php echo tpl_classes() ?> " style="position: relative"> 285 286 287 <?php // To go at the top of the page, style is for the fix top page --> ?> 288 <div id="dokuwiki__top"></div> 289 290 291 <?php 292 // The global message array 293 html_msgarea() 294 ?> 295 296 297 <?php 298 // A trigger to show content on the top part of the website 299 $data = "";// Mandatory 300 Event::createAndTrigger('TPL_PAGE_TOP_OUTPUT', $data); 301 ?> 302 303 304 <div class="row justify-content-md-center" <?php echo($landingPageGutter) ?>> 305 306 307 <?php if ($ACT === "show") { ?> 308 309 <?php 310 // SIDE BAR 311 if ($showSideBar): ?> 312 <div role="complementary" 313 class="slot-combo col-md-<?php echo($sidebarScale) ?> order-last order-md-first d-print-none"> 314 315 <?php echo $sideBarHtml ?> 316 317 </div> 318 <?php endif; ?> 319 320 <main class="col-md-<?php echo($mainGridScale) ?> order-first"> 321 322 <?php if ($showMainHeader) { ?> 323 <div id="main-header" class="slot-combo"> 324 <?php echo $mainHeaderHtml; ?> 325 </div> 326 <?php } 327 // Add a p around the content to enable the reader view in Mozilla 328 // https://github.com/mozilla/readability 329 // But Firefox close the P because they must contain only inline element ??? 330 echo $outputBuffer; 331 332 echo $mainHtml; 333 if ($showMainFooter) { ?> 334 <div id="main-footer" class="slot-combo"> 335 <?php echo $mainFooterHtml; ?> 336 </div> 337 <?php } 338 ?> 339 </main> 340 341 <?php if ($showSideKickBar): // Sidekick bar ?> 342 343 <div role="complementary" 344 class="col-md-<?php echo($sideKickBarScale) ?> slot-combo order-xs-2 order-md-last d-print-none"> 345 346 <?php 347 tpl_flush(); 348 349 echo $sideKickBarHtml; 350 351 // A trigger to show content on the sidebar part of the website 352 $data = "";// Mandatory 353 Event::createAndTrigger('TPL_SIDEBAR_BOTTOM_OUTPUT', $data); 354 ?> 355 356 </div> 357 <?php endif; // end show content?> 358 359 <?php } else { // do not use the main html element for do/admin content, main is reserved for the styling of the page content ?> 360 <main class="col-md-<?php echo($mainGridScale) ?>"> 361 <?php 362 // all other action are using the php buffer 363 // we can then have an overflow 364 // the buffer is flushed 365 // this is why we output the content of do page here 366 echo TplUtility::tpl_content($prependTOC = true); 367 ?> 368 </main> 369 <?php } ?> 370 371 </div> 372 373 <?php echo $railBar ?> 374 375 </div> 376 377 378 <?php 379 // Footer 380 echo $footerBar; 381 // Powered By 382 echo TplUtility::getPoweredBy(); 383 // The stylesheet (before indexer work and script at the end) 384 TplUtility::addPreloadedResources(); 385 ?> 386 387 388 <div class="d-none"> 389 <?php 390 // Indexer (Background tasks) 391 tpl_indexerWebBug() 392 ?> 393 </div> 394 395 </body> 396 </html> 397