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