1c165b184SJames Collins<?php 247161538SJames Collins 347161538SJames Collinsnamespace dokuwiki\template\mikio; 447161538SJames Collins 5c165b184SJames Collins/** 6c165b184SJames Collins * DokuWiki Mikio Template 7c165b184SJames Collins * 8c165b184SJames Collins * @link http://dokuwiki.org/template:mikio 9c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 10c165b184SJames Collins * @license MIT License (https://raw.githubusercontent.com/nomadjimbob/Mikio/master/LICENSE) 11c165b184SJames Collins */ 12c165b184SJames Collins 13c165b184SJames Collinsif (!defined('DOKU_INC')) die(); 14c165b184SJames Collins 15c165b184SJames Collinsrequire_once('inc/simple_html_dom.php'); 16c165b184SJames Collins 1747161538SJames Collinsclass Template { 18c165b184SJames Collins public $tplDir = ''; 19c165b184SJames Collins public $baseDir = ''; 20c165b184SJames Collins 21c165b184SJames Collins 22c165b184SJames Collins /** 23c165b184SJames Collins * Class constructor 24c165b184SJames Collins * 25c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 26c165b184SJames Collins */ 27c165b184SJames Collins public function __construct() { 28c165b184SJames Collins $this->tplDir = tpl_incdir(); 29c165b184SJames Collins $this->baseDir = tpl_basedir(); 30c165b184SJames Collins 31c165b184SJames Collins $this->_registerHooks(); 32c165b184SJames Collins } 33c165b184SJames Collins 34c165b184SJames Collins 35c165b184SJames Collins /** 3647161538SJames Collins * Get the singleton instance 3747161538SJames Collins * 3847161538SJames Collins * @return Template 3947161538SJames Collins */ 4047161538SJames Collins public static function getInstance() 4147161538SJames Collins { 4247161538SJames Collins 4347161538SJames Collins static $instance = null; 4447161538SJames Collins 4547161538SJames Collins if ($instance === null) { 4647161538SJames Collins $instance = new Template(); 4747161538SJames Collins } 4847161538SJames Collins 4947161538SJames Collins return $instance; 5047161538SJames Collins 5147161538SJames Collins } 5247161538SJames Collins 5347161538SJames Collins /** 54c165b184SJames Collins * Register themes DokuWiki hooks 55c165b184SJames Collins * 56c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 57c165b184SJames Collins */ 58c165b184SJames Collins private function _registerHooks() { 59c165b184SJames Collins global $EVENT_HANDLER; 60c165b184SJames Collins 61c165b184SJames Collins $events_dispatcher = array( 62c165b184SJames Collins 'TPL_METAHEADER_OUTPUT' => 'metaheadersHandler', 63c165b184SJames Collins 'TPL_CONTENT_DISPLAY' => 'contentHandler', 64c165b184SJames Collins ); 65c165b184SJames Collins 66c165b184SJames Collins foreach ($events_dispatcher as $event => $method) { 67c165b184SJames Collins $EVENT_HANDLER->register_hook($event, 'BEFORE', $this, $method); 68c165b184SJames Collins } 69c165b184SJames Collins } 70c165b184SJames Collins 71c165b184SJames Collins 72c165b184SJames Collins /** 73c165b184SJames Collins * DokuWiki META Header event handler 74c165b184SJames Collins * 75c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 76c165b184SJames Collins */ 7747161538SJames Collins public function metaHeadersHandler(\Doku_Event $event) { 78c165b184SJames Collins $stylesheets = array(); 79c165b184SJames Collins $scripts = array(); 80c165b184SJames Collins 81c165b184SJames Collins if($this->getConf('useTheme') != '') { 82*75adba86SJames Collins if(file_exists($this->tplDir . 'themes/' . $this->getConf('useTheme') . '/style.less')) { 83*75adba86SJames Collins $stylesheets[] = $this->baseDir . 'themes/' . $this->getConf('useTheme') . '/style.less'; 84c165b184SJames Collins } 85c165b184SJames Collins } 86c165b184SJames Collins 87*75adba86SJames Collins // $stylesheets[] = $this->baseDir . 'css/mikio.less'; 88*75adba86SJames Collins // $stylesheets[] = $this->baseDir . 'css/bootstrap.min.css'; 89c165b184SJames Collins 90c165b184SJames Collins if($this->getConf('includeFontAwesome') == true) $stylesheets[] = $this->baseDir . 'assets/fontawesome/css/all.min.css'; 91c165b184SJames Collins 92c165b184SJames Collins $scripts[] = $this->baseDir . 'js/bootstrap.min.js'; 93c165b184SJames Collins 94c165b184SJames Collins foreach ($stylesheets as $style) { 95c165b184SJames Collins array_unshift($event->data['link'], array( 96c165b184SJames Collins 'type' => 'text/css', 97c165b184SJames Collins 'rel' => 'stylesheet', 98c165b184SJames Collins 'href' => $style 99c165b184SJames Collins )); 100c165b184SJames Collins } 101c165b184SJames Collins 102c165b184SJames Collins foreach ($scripts as $script) { 103c165b184SJames Collins $event->data['script'][] = array( 104c165b184SJames Collins 'type' => 'text/javascript', 105c165b184SJames Collins '_data' => '', 106c165b184SJames Collins 'src' => $script 107c165b184SJames Collins ); 108c165b184SJames Collins } 109c165b184SJames Collins } 110c165b184SJames Collins 111c165b184SJames Collins 112c165b184SJames Collins /** 113c165b184SJames Collins * DokuWiki content event handler 114c165b184SJames Collins * 115c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 116c165b184SJames Collins */ 11747161538SJames Collins public function contentHandler(\Doku_Event $event) 118c165b184SJames Collins { 119*75adba86SJames Collins $event->data = $this->parseContent($event->data); 120c165b184SJames Collins } 121c165b184SJames Collins 122c165b184SJames Collins 123c165b184SJames Collins /** 124c165b184SJames Collins * Parse configuration options 125c165b184SJames Collins * 126c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 127c165b184SJames Collins * 128c165b184SJames Collins * @param string $key The configuration key to retreive 129c165b184SJames Collins * @param mixed $default If key doesn't exist, return this value 130c165b184SJames Collins * @return mixed Parsed value of configuration 131c165b184SJames Collins */ 132c165b184SJames Collins public function getConf($key, $default = false) { 133c165b184SJames Collins global $ACT, $conf; 134c165b184SJames Collins 135c165b184SJames Collins $value = tpl_getConf($key, $default); 136c165b184SJames Collins 137c165b184SJames Collins switch($key) { 138c165b184SJames Collins 139c165b184SJames Collins case 'navbar': // TODO is this needed? 140c165b184SJames Collins $value = explode(',', $value); 141c165b184SJames Collins break; 142c165b184SJames Collins 143c165b184SJames Collins case 'showSidebar': 144c165b184SJames Collins if ($ACT !== 'show') { 145c165b184SJames Collins return false; 146c165b184SJames Collins } 147c165b184SJames Collins 148c165b184SJames Collins return page_findnearest($conf['sidebar'], $this->getConf('useACL')); 149c165b184SJames Collins 150c165b184SJames Collins case 'navbarMenuStyle': 151c165b184SJames Collins if($value != 'text') { 152c165b184SJames Collins if(!$this->getConf('useFontAwesome')) { 153c165b184SJames Collins return 'text'; 154c165b184SJames Collins } 155c165b184SJames Collins } 156*75adba86SJames Collins 157*75adba86SJames Collins break; 158*75adba86SJames Collins 159*75adba86SJames Collins case 'navbarMenuPosition': 160*75adba86SJames Collins if($value == 'right') { 161*75adba86SJames Collins return 'ml-md-auto'; 162*75adba86SJames Collins } 163*75adba86SJames Collins 164*75adba86SJames Collins return ''; 165*75adba86SJames Collins 166*75adba86SJames Collins case 'breadcrumbsLoc': 167*75adba86SJames Collins if(!$this->getConf('useHeroTitle') && $value == 'hero') { 168*75adba86SJames Collins return 'top'; 169*75adba86SJames Collins } 170*75adba86SJames Collins 171*75adba86SJames Collins if($value != 'top' && $value != 'hero' && $value != 'page') { 172*75adba86SJames Collins return 'page'; 173*75adba86SJames Collins } 174*75adba86SJames Collins 175*75adba86SJames Collins break; 176c165b184SJames Collins } 177c165b184SJames Collins 178c165b184SJames Collins return $value; 179c165b184SJames Collins } 180c165b184SJames Collins 181c165b184SJames Collins 182c165b184SJames Collins /** 183c165b184SJames Collins * Icon 184c165b184SJames Collins * 185c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 186c165b184SJames Collins * 187c165b184SJames Collins * @param string $type The type of icon to return 188c165b184SJames Collins * @return string HTML for icon element 189c165b184SJames Collins */ 190c165b184SJames Collins public function icon($type) { 191c165b184SJames Collins if($this->getConf('useFontAwesome')) { 192c165b184SJames Collins return '<i class="fa fa-' . $type . '" aria-hidden="true"></i>'; 193c165b184SJames Collins } 194c165b184SJames Collins 195c165b184SJames Collins return ''; 196c165b184SJames Collins } 197c165b184SJames Collins 198c165b184SJames Collins 199c165b184SJames Collins /** 200c165b184SJames Collins * Print the Navbar menu title/icon 201c165b184SJames Collins * 202c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 203c165b184SJames Collins * 204c165b184SJames Collins * @param string $type The type of icon to return 205c165b184SJames Collins * @return string HTML for icon element 206c165b184SJames Collins */ 207c165b184SJames Collins public function navbarMenuTitle($title, $icon) { 208c165b184SJames Collins global $lang; 209c165b184SJames Collins 210c165b184SJames Collins $title = ''; 211c165b184SJames Collins 212c165b184SJames Collins if($this->getConf('navbarMenuStyle') != 'text') { 213c165b184SJames Collins $title .= $this->icon($icon); 214c165b184SJames Collins } 215c165b184SJames Collins 216c165b184SJames Collins if($this->getConf('navbarMenuStyle') != 'icon') { 217c165b184SJames Collins $title .= $lang['user_tools']; 218c165b184SJames Collins } 219c165b184SJames Collins 220c165b184SJames Collins echo $title; 221c165b184SJames Collins } 222c165b184SJames Collins 223c165b184SJames Collins 224c165b184SJames Collins /** 225c165b184SJames Collins * Add class to first DOM element 226c165b184SJames Collins * 227c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 228c165b184SJames Collins * 229c165b184SJames Collins * @param string $content HTML DOM 230c165b184SJames Collins * @param string $class Class to add DOM elements 231c165b184SJames Collins * @return string HTML DOM with class added 232c165b184SJames Collins */ 233c165b184SJames Collins public function elementAddClass($html, $class) { 234c165b184SJames Collins preg_match('/class.*?".*?"/', $html, $matches); 235c165b184SJames Collins if(count($matches) > 0) { 236c165b184SJames Collins preg_match('/[" ]'.$class.'[" ]/', $matches[0], $matches); 237c165b184SJames Collins if(count($matches) == 0) { 238c165b184SJames Collins return preg_replace('/(class.*?=.*?")/', '${1}'.$class.' ', $html, 1); 239c165b184SJames Collins } 240c165b184SJames Collins } else { 241c165b184SJames Collins return preg_replace('/>/', 'class="'.$class.'">', $html, 1); 242c165b184SJames Collins } 243c165b184SJames Collins 244c165b184SJames Collins return $html; 245c165b184SJames Collins } 246c165b184SJames Collins 247c165b184SJames Collins 248c165b184SJames Collins /** 249c165b184SJames Collins * Include Sidebar 250c165b184SJames Collins * 251c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 252c165b184SJames Collins * 253c165b184SJames Collins * @param string $type Sidebar type 254c165b184SJames Collins * @return boolean If sidebar was added 255c165b184SJames Collins */ 256c165b184SJames Collins public function includeSidebar($type) { 257c165b184SJames Collins global $conf; 258c165b184SJames Collins 259c165b184SJames Collins switch($type) { 260c165b184SJames Collins case 'left': 261c165b184SJames Collins if($this->getConf('showSidebar')) { 262c165b184SJames Collins echo '<aside>'; 263c165b184SJames Collins tpl_includeFile('sidebarheader.html'); 264c165b184SJames Collins tpl_include_page($conf['sidebar'], 1, 1); 265c165b184SJames Collins tpl_includeFile('sidebarfooter.html'); 266c165b184SJames Collins echo '</aside>'; 267c165b184SJames Collins 268c165b184SJames Collins return true; 269c165b184SJames Collins } 270c165b184SJames Collins 271c165b184SJames Collins return false; 272c165b184SJames Collins } 273c165b184SJames Collins 274c165b184SJames Collins return false; 275c165b184SJames Collins } 276c165b184SJames Collins 277c165b184SJames Collins 278*75adba86SJames Collins /** 279*75adba86SJames Collins * Print out breadcrumbs 280*75adba86SJames Collins * 281*75adba86SJames Collins * @author James Collins <james.collins@outlook.com.au> 282*75adba86SJames Collins * 283*75adba86SJames Collins * @param string $location Location of breadcrumbs 284*75adba86SJames Collins */ 285*75adba86SJames Collins public function includeBreadcrumbs($location) { 286*75adba86SJames Collins if($location == $this->getConf('breadcrumbsLoc')) { 28747161538SJames Collins global $conf; 28847161538SJames Collins 289*75adba86SJames Collins print '<div class="mikio-breadcrumbs">'; 290*75adba86SJames Collins 29147161538SJames Collins if($conf['breadcrumbs']) { 292*75adba86SJames Collins tpl_breadcrumbs(); 29347161538SJames Collins } 29447161538SJames Collins 29547161538SJames Collins if($conf['youarehere']) { 296*75adba86SJames Collins tpl_youarehere(); 297*75adba86SJames Collins } 298*75adba86SJames Collins 299*75adba86SJames Collins print '</div>'; 300*75adba86SJames Collins } 30147161538SJames Collins } 30247161538SJames Collins 30347161538SJames Collins 304*75adba86SJames Collins /** 305*75adba86SJames Collins * Print out hero 306*75adba86SJames Collins * 307*75adba86SJames Collins * @author James Collins <james.collins@outlook.com.au> 308*75adba86SJames Collins */ 309*75adba86SJames Collins public function includeHero() { 310*75adba86SJames Collins global $ACT; 31147161538SJames Collins 312*75adba86SJames Collins if($ACT === 'show') { 313*75adba86SJames Collins if($this->getConf('useHeroTitle')) { 314*75adba86SJames Collins print '<div class="mikio-hero d-flex flex-row">'; 315*75adba86SJames Collins print '<div class="mikio-hero-text flex-grow-1">'; 316*75adba86SJames Collins $this->includeBreadcrumbs('hero'); 317*75adba86SJames Collins print '<h1 id="mikio-hero-title">'; 318*75adba86SJames Collins tpl_pagetitle(); 319*75adba86SJames Collins print '</h1>'; 320*75adba86SJames Collins print '<h2 id="mikio-hero-subtext">'; 321*75adba86SJames Collins print ''; // TODO Find subtext in page? 322*75adba86SJames Collins print '</h2>'; 323*75adba86SJames Collins print '</div>'; 32447161538SJames Collins 325*75adba86SJames Collins $hero_image = tpl_getMediaFile(array(':hero.png', ':hero.jpg', ':wiki:hero.png', ':wiki:hero.jpg', 'images/hero.png', 'images/hero.jpg'), false); 326*75adba86SJames Collins if($hero_image != '') $hero_image = ' style="background-image:url(\''.$hero_image.'\');"'; 32747161538SJames Collins 328*75adba86SJames Collins print '<div class="mikio-hero-image"' . $hero_image . '></div>'; 329*75adba86SJames Collins print '</div>'; 33047161538SJames Collins } 331*75adba86SJames Collins } 332*75adba86SJames Collins } 333*75adba86SJames Collins 334*75adba86SJames Collins 335*75adba86SJames Collins /** 336*75adba86SJames Collins * Print out TOC 337*75adba86SJames Collins * 338*75adba86SJames Collins * @author James Collins <james.collins@outlook.com.au> 339*75adba86SJames Collins */ 340*75adba86SJames Collins public function includeTOC($location) { 341*75adba86SJames Collins if($this->getConf('tocfullheight') && $location === 'full') { 342*75adba86SJames Collins print '<div class="mikio-toc mikio-toc-full">'; 343*75adba86SJames Collins tpl_toc(); 344*75adba86SJames Collins print '</div>'; 345*75adba86SJames Collins } else if(!$this->getConf('tocfullheight') && $location === 'float') { 346*75adba86SJames Collins print '<div class="mikio-toc mikio-toc-float">'; 347*75adba86SJames Collins tpl_toc(); 348*75adba86SJames Collins print '</div>'; 349*75adba86SJames Collins } 350*75adba86SJames Collins } 351*75adba86SJames Collins 35247161538SJames Collins 353c165b184SJames Collins /** 354c165b184SJames Collins * Parse HTML for bootstrap 355c165b184SJames Collins * 356c165b184SJames Collins * @author James Collins <james.collins@outlook.com.au> 357c165b184SJames Collins * 358c165b184SJames Collins * @param string $content HTML content to parse 359c165b184SJames Collins * @return string Parsed HTML for bootstrap 360c165b184SJames Collins */ 361*75adba86SJames Collins public function parseContent($content) { 36247161538SJames Collins $html = new \simple_html_dom; 363c165b184SJames Collins $html->load($content, true, false); 364c165b184SJames Collins 365c165b184SJames Collins # Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB) 366c165b184SJames Collins if (!$html) { 367c165b184SJames Collins return $content; 368c165b184SJames Collins } 369c165b184SJames Collins 370*75adba86SJames Collins 37147161538SJames Collins # Hide page title if hero is enabled 37247161538SJames Collins if($this->getConf('useHeroTitle')) { 37347161538SJames Collins $pageTitle = tpl_pagetitle(null, true); 37447161538SJames Collins 37547161538SJames Collins foreach($html->find('h1,h2,h3,h4') as $elm) { 37647161538SJames Collins if($elm->innertext == $pageTitle) { 37747161538SJames Collins $elm->innertext = ''; 37847161538SJames Collins break; 37947161538SJames Collins } 38047161538SJames Collins } 38147161538SJames Collins } 382c165b184SJames Collins 383c165b184SJames Collins # Buttons 384c165b184SJames Collins foreach ($html->find('.button') as $elm) { 385c165b184SJames Collins if ($elm->tag == 'form') { 386c165b184SJames Collins continue; 387c165b184SJames Collins } 388c165b184SJames Collins $elm->class .= ' btn'; 389c165b184SJames Collins } 390c165b184SJames Collins 391c165b184SJames Collins foreach ($html->find('[type=button], [type=submit], [type=reset]') as $elm) { 392c165b184SJames Collins $elm->class .= ' btn btn-outline-secondary'; 393c165b184SJames Collins } 394c165b184SJames Collins 395c165b184SJames Collins # Section Edit Button 396c165b184SJames Collins foreach ($html->find('.btn_secedit [type=submit]') as $elm) { 397c165b184SJames Collins $elm->class .= ' btn-sm'; 398c165b184SJames Collins } 399c165b184SJames Collins 400c165b184SJames Collins # Section Edit icons 401c165b184SJames Collins foreach ($html->find('.secedit.editbutton_section button') as $elm) { 402c165b184SJames Collins $elm->innertext = '<i class="fa fa-edit" aria-hidden="true"></i> ' . $elm->innertext; 403c165b184SJames Collins } 404c165b184SJames Collins 405c165b184SJames Collins $content = $html->save(); 406c165b184SJames Collins 407c165b184SJames Collins $html->clear(); 408c165b184SJames Collins unset($html); 409c165b184SJames Collins 410c165b184SJames Collins return $content; 411c165b184SJames Collins } 412c165b184SJames Collins} 41347161538SJames Collins 41447161538SJames Collinsglobal $TEMPLATE; 41547161538SJames Collins 41647161538SJames Collins$TEMPLATE = \dokuwiki\template\mikio\Template::getInstance();