1<?php 2 3namespace dokuwiki\template\mikio; 4 5/** 6 * DokuWiki Mikio Template 7 * 8 * @link http://dokuwiki.org/template:mikio 9 * @author James Collins <james.collins@outlook.com.au> 10 * @license MIT License (https://raw.githubusercontent.com/nomadjimbob/Mikio/master/LICENSE) 11 */ 12 13if (!defined('DOKU_INC')) die(); 14 15require_once('inc/simple_html_dom.php'); 16 17class Template { 18 public $tplDir = ''; 19 public $baseDir = ''; 20 21 22 /** 23 * Class constructor 24 * 25 * @author James Collins <james.collins@outlook.com.au> 26 */ 27 public function __construct() { 28 $this->tplDir = tpl_incdir(); 29 $this->baseDir = tpl_basedir(); 30 31 $this->_registerHooks(); 32 } 33 34 35 /** 36 * Get the singleton instance 37 * 38 * @return Template 39 */ 40 public static function getInstance() 41 { 42 43 static $instance = null; 44 45 if ($instance === null) { 46 $instance = new Template(); 47 } 48 49 return $instance; 50 51 } 52 53 /** 54 * Register themes DokuWiki hooks 55 * 56 * @author James Collins <james.collins@outlook.com.au> 57 */ 58 private function _registerHooks() { 59 global $EVENT_HANDLER; 60 61 $events_dispatcher = array( 62 'TPL_METAHEADER_OUTPUT' => 'metaheadersHandler', 63 'TPL_CONTENT_DISPLAY' => 'contentHandler', 64 ); 65 66 foreach ($events_dispatcher as $event => $method) { 67 $EVENT_HANDLER->register_hook($event, 'BEFORE', $this, $method); 68 } 69 } 70 71 72 /** 73 * DokuWiki META Header event handler 74 * 75 * @author James Collins <james.collins@outlook.com.au> 76 */ 77 public function metaHeadersHandler(\Doku_Event $event) { 78 $stylesheets = array(); 79 $scripts = array(); 80 81 if($this->getConf('useTheme') != '') { 82 if(file_exists($this->tplDir . 'themes/' . $this->getConf('useTheme') . '/style.css')) { 83 $stylesheets[] = $this->baseDir . 'themes/' . $this->getConf('useTheme') . '/style.css'; 84 } 85 } 86 87 $stylesheets[] = $this->baseDir . 'css/mikio.css'; 88 $stylesheets[] = $this->baseDir . 'css/bootstrap.min.css'; 89 90 if($this->getConf('includeFontAwesome') == true) $stylesheets[] = $this->baseDir . 'assets/fontawesome/css/all.min.css'; 91 92 $scripts[] = $this->baseDir . 'js/bootstrap.min.js'; 93 94 foreach ($stylesheets as $style) { 95 array_unshift($event->data['link'], array( 96 'type' => 'text/css', 97 'rel' => 'stylesheet', 98 'href' => $style 99 )); 100 } 101 102 foreach ($scripts as $script) { 103 $event->data['script'][] = array( 104 'type' => 'text/javascript', 105 '_data' => '', 106 'src' => $script 107 ); 108 } 109 } 110 111 112 /** 113 * DokuWiki content event handler 114 * 115 * @author James Collins <james.collins@outlook.com.au> 116 */ 117 public function contentHandler(\Doku_Event $event) 118 { 119 $event->data = $this->normalizeContent($event->data); 120 } 121 122 123 /** 124 * Parse configuration options 125 * 126 * @author James Collins <james.collins@outlook.com.au> 127 * 128 * @param string $key The configuration key to retreive 129 * @param mixed $default If key doesn't exist, return this value 130 * @return mixed Parsed value of configuration 131 */ 132 public function getConf($key, $default = false) { 133 global $ACT, $conf; 134 135 $value = tpl_getConf($key, $default); 136 137 switch($key) { 138 139 case 'navbar': // TODO is this needed? 140 $value = explode(',', $value); 141 break; 142 143 case 'showSidebar': 144 if ($ACT !== 'show') { 145 return false; 146 } 147 148 return page_findnearest($conf['sidebar'], $this->getConf('useACL')); 149 150 case 'navbarMenuStyle': 151 if($value != 'text') { 152 if(!$this->getConf('useFontAwesome')) { 153 return 'text'; 154 } 155 } 156 } 157 158 return $value; 159 } 160 161 162 /** 163 * Icon 164 * 165 * @author James Collins <james.collins@outlook.com.au> 166 * 167 * @param string $type The type of icon to return 168 * @return string HTML for icon element 169 */ 170 public function icon($type) { 171 if($this->getConf('useFontAwesome')) { 172 return '<i class="fa fa-' . $type . '" aria-hidden="true"></i>'; 173 } 174 175 return ''; 176 } 177 178 179 /** 180 * Print the Navbar menu title/icon 181 * 182 * @author James Collins <james.collins@outlook.com.au> 183 * 184 * @param string $type The type of icon to return 185 * @return string HTML for icon element 186 */ 187 public function navbarMenuTitle($title, $icon) { 188 global $lang; 189 190 $title = ''; 191 192 if($this->getConf('navbarMenuStyle') != 'text') { 193 $title .= $this->icon($icon); 194 } 195 196 if($this->getConf('navbarMenuStyle') != 'icon') { 197 $title .= $lang['user_tools']; 198 } 199 200 echo $title; 201 } 202 203 204 /** 205 * Add class to first DOM element 206 * 207 * @author James Collins <james.collins@outlook.com.au> 208 * 209 * @param string $content HTML DOM 210 * @param string $class Class to add DOM elements 211 * @return string HTML DOM with class added 212 */ 213 public function elementAddClass($html, $class) { 214 preg_match('/class.*?".*?"/', $html, $matches); 215 if(count($matches) > 0) { 216 preg_match('/[" ]'.$class.'[" ]/', $matches[0], $matches); 217 if(count($matches) == 0) { 218 return preg_replace('/(class.*?=.*?")/', '${1}'.$class.' ', $html, 1); 219 } 220 } else { 221 return preg_replace('/>/', 'class="'.$class.'">', $html, 1); 222 } 223 224 return $html; 225 } 226 227 228 /** 229 * Include Sidebar 230 * 231 * @author James Collins <james.collins@outlook.com.au> 232 * 233 * @param string $type Sidebar type 234 * @return boolean If sidebar was added 235 */ 236 public function includeSidebar($type) { 237 global $conf; 238 239 switch($type) { 240 case 'left': 241 if($this->getConf('showSidebar')) { 242 echo '<aside>'; 243 tpl_includeFile('sidebarheader.html'); 244 tpl_include_page($conf['sidebar'], 1, 1); 245 tpl_includeFile('sidebarfooter.html'); 246 echo '</aside>'; 247 248 return true; 249 } 250 251 return false; 252 } 253 254 return false; 255 } 256 257 258 public function includeBreadcrumbs() { 259 global $conf; 260 261 if($conf['breadcrumbs']) { 262 print_r(breadcrumbs()); 263 tpl_breadcrumbs('|'); 264 } 265 266 if($conf['youarehere']) { 267 // print_r(youarehere()); 268 tpl_youarehere('|'); 269 } 270 271 272 273 274 // $crumbs = breadcrumbs(); 275 276 // print '<ol class="breadcrumb">'; 277 // print '<li>' . rtrim($lang['breadcrumb'], ':') . '</li>'; 278 279 // $last = count($crumbs); 280 // $i = 0; 281 282 // foreach ($crumbs as $id => $name) { 283 284 // $i++; 285 286 // print($i == $last) ? '<li class="active">' : '<li>'; 287 // tpl_link(wl($id), hsc($name), 'title="' . $id . '"'); 288 // print '</li>'; 289 290 // if ($i == $last) { 291 // print '</ol>'; 292 // } 293 294 // } 295 296 // print_r($crumbs); 297 } 298 299 /** 300 * Parse HTML for bootstrap 301 * 302 * @author James Collins <james.collins@outlook.com.au> 303 * 304 * @param string $content HTML content to parse 305 * @return string Parsed HTML for bootstrap 306 */ 307 public function normalizeContent($content) { 308 $html = new \simple_html_dom; 309 $html->load($content, true, false); 310 311 # Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB) 312 if (!$html) { 313 return $content; 314 } 315 316 # Hide page title if hero is enabled 317 if($this->getConf('useHeroTitle')) { 318 $pageTitle = tpl_pagetitle(null, true); 319 320 foreach($html->find('h1,h2,h3,h4') as $elm) { 321 if($elm->innertext == $pageTitle) { 322 $elm->innertext = ''; 323 break; 324 } 325 } 326 } 327 328 # Buttons 329 foreach ($html->find('.button') as $elm) { 330 if ($elm->tag == 'form') { 331 continue; 332 } 333 $elm->class .= ' btn'; 334 } 335 336 foreach ($html->find('[type=button], [type=submit], [type=reset]') as $elm) { 337 $elm->class .= ' btn btn-outline-secondary'; 338 } 339 340 # Section Edit Button 341 foreach ($html->find('.btn_secedit [type=submit]') as $elm) { 342 $elm->class .= ' btn-sm'; 343 } 344 345 # Section Edit icons 346 foreach ($html->find('.secedit.editbutton_section button') as $elm) { 347 $elm->innertext = '<i class="fa fa-edit" aria-hidden="true"></i> ' . $elm->innertext; 348 } 349 350 $content = $html->save(); 351 352 $html->clear(); 353 unset($html); 354 355 return $content; 356 } 357} 358 359global $TEMPLATE; 360 361$TEMPLATE = \dokuwiki\template\mikio\Template::getInstance();