xref: /template/mikio/mikio.php (revision 2b4583abab306b8eb94c98b5ea77d885731fe2f3)
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',
63*2b4583abSJames 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*2b4583abSJames Collins            if(file_exists($this->tplDir . 'themes/' . $this->getConf('useTheme') . '/style.css')) {
83*2b4583abSJames Collins                $stylesheets[] = $this->baseDir . 'themes/' . $this->getConf('useTheme') . '/style.css';
84*2b4583abSJames Collins            }
85*2b4583abSJames Collins            if(file_exists($this->tplDir . 'themes/' . $this->getConf('useTheme') . '/script.js')) {
86*2b4583abSJames Collins                $scripts[] = $this->baseDir . 'themes/' . $this->getConf('useTheme') . '/script.js';
87c165b184SJames Collins            }
88c165b184SJames Collins        }
89c165b184SJames Collins
90c165b184SJames Collins        if($this->getConf('includeFontAwesome') == true) $stylesheets[] = $this->baseDir . 'assets/fontawesome/css/all.min.css';
91c165b184SJames Collins
92*2b4583abSJames Collins        $scripts[] = $this->baseDir . 'assets/bootstrap/popper.min.js';
93*2b4583abSJames Collins        $scripts[] = $this->baseDir . 'assets/bootstrap/bootstrap.min.js';
94*2b4583abSJames Collins        $stylesheets[] = $this->baseDir . 'assets/bootstrap/bootstrap.min.css';
95*2b4583abSJames Collins        $stylesheets[] = $this->baseDir . 'assets/mikio.css';
96c165b184SJames Collins
97c165b184SJames Collins        foreach ($stylesheets as $style) {
98c165b184SJames Collins            array_unshift($event->data['link'], array(
99c165b184SJames Collins                'type' => 'text/css',
100c165b184SJames Collins                'rel'  => 'stylesheet',
101c165b184SJames Collins                'href' => $style
102c165b184SJames Collins            ));
103c165b184SJames Collins        }
104c165b184SJames Collins
105c165b184SJames Collins        foreach ($scripts as $script) {
106c165b184SJames Collins            $event->data['script'][] = array(
107c165b184SJames Collins                 'type'  => 'text/javascript',
108c165b184SJames Collins              '_data' => '',
109c165b184SJames Collins              'src'   => $script
110c165b184SJames Collins          );
111c165b184SJames Collins      }
112c165b184SJames Collins    }
113c165b184SJames Collins
114c165b184SJames Collins
115c165b184SJames Collins    /**
116c165b184SJames Collins     * DokuWiki content event handler
117c165b184SJames Collins     *
118c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
119c165b184SJames Collins     */
12047161538SJames Collins    public function contentHandler(\Doku_Event $event)
121c165b184SJames Collins    {
12275adba86SJames Collins        $event->data = $this->parseContent($event->data);
123c165b184SJames Collins    }
124c165b184SJames Collins
125c165b184SJames Collins
126c165b184SJames Collins    /**
127c165b184SJames Collins     * Parse configuration options
128c165b184SJames Collins     *
129c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
130c165b184SJames Collins     *
131c165b184SJames Collins     * @param   string  $key        The configuration key to retreive
132c165b184SJames Collins     * @param   mixed   $default    If key doesn't exist, return this value
133c165b184SJames Collins     * @return  mixed               Parsed value of configuration
134c165b184SJames Collins     */
135c165b184SJames Collins    public function getConf($key, $default = false) {
136c165b184SJames Collins        global $ACT, $conf;
137c165b184SJames Collins
138c165b184SJames Collins        $value = tpl_getConf($key, $default);
139c165b184SJames Collins
140c165b184SJames Collins        switch($key) {
141c165b184SJames Collins
142c165b184SJames Collins            case 'navbar':  // TODO is this needed?
143c165b184SJames Collins                $value = explode(',', $value);
144c165b184SJames Collins                break;
145c165b184SJames Collins
146c165b184SJames Collins            case 'showSidebar':
147c165b184SJames Collins                if ($ACT !== 'show') {
148c165b184SJames Collins                    return false;
149c165b184SJames Collins                }
150c165b184SJames Collins
151c165b184SJames Collins                return page_findnearest($conf['sidebar'], $this->getConf('useACL'));
152c165b184SJames Collins
153c165b184SJames Collins            case 'navbarMenuStyle':
154c165b184SJames Collins                if($value != 'text') {
155c165b184SJames Collins                    if(!$this->getConf('useFontAwesome')) {
156c165b184SJames Collins                        return 'text';
157c165b184SJames Collins                    }
158c165b184SJames Collins                }
15975adba86SJames Collins
16075adba86SJames Collins            break;
16175adba86SJames Collins
16275adba86SJames Collins            case 'navbarMenuPosition':
16375adba86SJames Collins                if($value == 'right') {
16475adba86SJames Collins                    return 'ml-md-auto';
16575adba86SJames Collins                }
16675adba86SJames Collins
16775adba86SJames Collins                return '';
16875adba86SJames Collins
16975adba86SJames Collins            case 'breadcrumbsLoc':
17075adba86SJames Collins                if(!$this->getConf('useHeroTitle') && $value == 'hero') {
17175adba86SJames Collins                    return 'top';
17275adba86SJames Collins                }
17375adba86SJames Collins
17475adba86SJames Collins                if($value != 'top' && $value != 'hero' && $value != 'page') {
17575adba86SJames Collins                    return 'page';
17675adba86SJames Collins                }
17775adba86SJames Collins
17875adba86SJames Collins                break;
179c165b184SJames Collins        }
180c165b184SJames Collins
181c165b184SJames Collins        return $value;
182c165b184SJames Collins    }
183c165b184SJames Collins
184c165b184SJames Collins
185c165b184SJames Collins    /**
186c165b184SJames Collins     * Icon
187c165b184SJames Collins     *
188c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
189c165b184SJames Collins     *
190c165b184SJames Collins     * @param   string  $type       The type of icon to return
191c165b184SJames Collins     * @return  string              HTML for icon element
192c165b184SJames Collins     */
193c165b184SJames Collins    public function icon($type) {
194c165b184SJames Collins        if($this->getConf('useFontAwesome')) {
195c165b184SJames Collins            return '<i class="fa fa-' . $type . '" aria-hidden="true"></i>';
196c165b184SJames Collins        }
197c165b184SJames Collins
198c165b184SJames Collins        return '';
199c165b184SJames Collins    }
200c165b184SJames Collins
201c165b184SJames Collins
202c165b184SJames Collins    /**
203c165b184SJames Collins     * Print the Navbar menu title/icon
204c165b184SJames Collins     *
205c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
206c165b184SJames Collins     *
207c165b184SJames Collins     * @param   string  $type       The type of icon to return
208c165b184SJames Collins     * @return  string              HTML for icon element
209c165b184SJames Collins     */
210c165b184SJames Collins    public function navbarMenuTitle($title, $icon) {
211c165b184SJames Collins        global $lang;
212c165b184SJames Collins
213addbeb3bSJames Collins        $menu = '';
214c165b184SJames Collins
215c165b184SJames Collins        if($this->getConf('navbarMenuStyle') != 'text') {
216addbeb3bSJames Collins            $menu .= $this->icon($icon);
217c165b184SJames Collins        }
218c165b184SJames Collins
219c165b184SJames Collins        if($this->getConf('navbarMenuStyle') != 'icon') {
220addbeb3bSJames Collins            $menu .= $lang[$title];
221c165b184SJames Collins        }
222c165b184SJames Collins
223addbeb3bSJames Collins        echo $menu;
224c165b184SJames Collins    }
225c165b184SJames Collins
226c165b184SJames Collins
227c165b184SJames Collins     /**
228c165b184SJames Collins     * Add class to first DOM element
229c165b184SJames Collins     *
230c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
231c165b184SJames Collins     *
232c165b184SJames Collins     * @param   string  $content    HTML DOM
233c165b184SJames Collins     * @param   string  $class      Class to add DOM elements
234c165b184SJames Collins     * @return  string              HTML DOM with class added
235c165b184SJames Collins     */
236c165b184SJames Collins    public function elementAddClass($html, $class) {
237c165b184SJames Collins        preg_match('/class.*?".*?"/', $html, $matches);
238c165b184SJames Collins        if(count($matches) > 0) {
239c165b184SJames Collins            preg_match('/[" ]'.$class.'[" ]/', $matches[0], $matches);
240c165b184SJames Collins            if(count($matches) == 0) {
241c165b184SJames Collins                return preg_replace('/(class.*?=.*?")/', '${1}'.$class.' ', $html, 1);
242c165b184SJames Collins            }
243c165b184SJames Collins        } else {
244c165b184SJames Collins            return preg_replace('/>/', 'class="'.$class.'">', $html, 1);
245c165b184SJames Collins        }
246c165b184SJames Collins
247c165b184SJames Collins        return $html;
248c165b184SJames Collins    }
249c165b184SJames Collins
250c165b184SJames Collins
251c165b184SJames Collins    /**
252*2b4583abSJames Collins     * Include Page
253*2b4583abSJames Collins     *
254*2b4583abSJames Collins     * @author  James Collins <james.collins@outlook.com.au>
255*2b4583abSJames Collins     *
256*2b4583abSJames Collins     * @param   string  $location
257*2b4583abSJames Collins     * @param   boolean $return
258*2b4583abSJames Collins     * @return  string
259*2b4583abSJames Collins     */
260*2b4583abSJames Collins    public function includePage($location, $return = false)
261*2b4583abSJames Collins    {
262*2b4583abSJames Collins
263*2b4583abSJames Collins        $content = '';
264*2b4583abSJames Collins
265*2b4583abSJames Collins        if($content === '') $content = tpl_include_page($location, 0, 1, $this->getConf('useACL'));
266*2b4583abSJames Collins
267*2b4583abSJames Collins        if($content === '') return '';
268*2b4583abSJames Collins
269*2b4583abSJames Collins        $content = $this->parseContent($content);
270*2b4583abSJames Collins
271*2b4583abSJames Collins        if($return) return $content;
272*2b4583abSJames Collins
273*2b4583abSJames Collins        print $content;
274*2b4583abSJames Collins        return '';
275*2b4583abSJames Collins    }
276*2b4583abSJames Collins
277*2b4583abSJames Collins    public function includeLoggedIn() {
278*2b4583abSJames Collins        if (!empty($_SERVER['REMOTE_USER'])) {
279*2b4583abSJames Collins            echo '<li class="user navbar-text text-nowrap">';
280*2b4583abSJames Collins            tpl_userinfo(); /* 'Logged in as ...' */
281*2b4583abSJames Collins            echo '</li>';
282*2b4583abSJames Collins        }
283*2b4583abSJames Collins    }
284*2b4583abSJames Collins
285*2b4583abSJames Collins
286*2b4583abSJames Collins    /**
287*2b4583abSJames Collins     * Include Menus
288*2b4583abSJames Collins     *
289*2b4583abSJames Collins     * @author  James Collins <james.collins@outlook.com.au>
290*2b4583abSJames Collins     *
291*2b4583abSJames Collins     * @param   string  $location
292*2b4583abSJames Collins     */
293*2b4583abSJames Collins    public function includeMenu($location) {
294*2b4583abSJames Collins        global $lang;
295*2b4583abSJames Collins        global $USERINFO;
296*2b4583abSJames Collins
297*2b4583abSJames Collins        $conf = $this->getConf('navbarIconsText');
298*2b4583abSJames Collins        $dropdown = $this->getConf('navbarUseDropdown');
299*2b4583abSJames Collins        $hideIcons = ($conf == 'text');
300*2b4583abSJames Collins        $hideText = ($conf == 'icons');
301*2b4583abSJames Collins        $guestMode = $this->getConf('navbarGuestHide') && ($USERINFO == false);
302*2b4583abSJames Collins
303*2b4583abSJames Collins        if(!$hideText && !$hideIcons) $hideText = false;
304*2b4583abSJames Collins
305*2b4583abSJames Collins        if(!$guestMode) {
306*2b4583abSJames Collins            // Page tools
307*2b4583abSJames Collins            $items = (new \dokuwiki\Menu\PageMenu())->getItems();
308*2b4583abSJames Collins            print '<li id="dokuwiki__pagetools" class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . (!$hideIcons ? $this->icon('file') : '') . (!$hideText ? $lang['page_tools'] : '') . '</a><div class="dropdown-menu dropdown-menu-right">';
309*2b4583abSJames Collins            foreach($items as $item) {
310*2b4583abSJames Collins                if($item->getType() != 'top') {
311*2b4583abSJames Collins                    print '<a class="' . ($dropdown ? 'dropdown-item' : 'nav-item nav-link') . '" href="'.$item->getLink().'" title="'.$item->getTitle().'">';
312*2b4583abSJames Collins                    if(!$hideIcons) print '<span class="icon">'.inlineSVG($item->getSvg()).'</span>';
313*2b4583abSJames Collins                    if(!$hideText || $dropdown) print '<span>' . $item->getLabel() . '</span>';
314*2b4583abSJames Collins                    print '</a>';
315*2b4583abSJames Collins                }
316*2b4583abSJames Collins            }
317*2b4583abSJames Collins            if($dropdown) print '</div></li>';
318*2b4583abSJames Collins
319*2b4583abSJames Collins            // Site tools
320*2b4583abSJames Collins            $items = (new \dokuwiki\Menu\SiteMenu())->getItems('action ');
321*2b4583abSJames Collins
322*2b4583abSJames Collins            print '<li id="dokuwiki__sitetools" class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . (!$hideIcons ? $this->icon('gear') : '') . (!$hideText ? $lang['site_tools'] : '') . '</a><div class="dropdown-menu dropdown-menu-right">';
323*2b4583abSJames Collins            foreach($items as $item) {
324*2b4583abSJames Collins                print '<a class="' . ($dropdown ? 'dropdown-item' : 'nav-item nav-link') . '" href="'.$item->getLink().'" title="'.$item->getTitle().'">';
325*2b4583abSJames Collins                if(!$hideIcons) print '<span class="icon">'.inlineSVG($item->getSvg()).'</span>';
326*2b4583abSJames Collins                if(!$hideText || $dropdown) print '<span>' . $item->getLabel() . '</span>';
327*2b4583abSJames Collins                print '</a>';
328*2b4583abSJames Collins            }
329*2b4583abSJames Collins            if($dropdown) print '</div></li>';
330*2b4583abSJames Collins        }
331*2b4583abSJames Collins
332*2b4583abSJames Collins        // User tools
333*2b4583abSJames Collins        $items = (new \dokuwiki\Menu\UserMenu())->getItems('action');
334*2b4583abSJames Collins        if(!$guestMode) print '<li id="dokuwiki__usertools" class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . (!$hideIcons ? $this->icon('user') : '') . (!$hideText ? $lang['user_tools'] : '') . '</a><div class="dropdown-menu dropdown-menu-right">';
335*2b4583abSJames Collins        foreach($items as $item) {
336*2b4583abSJames Collins            if(!$guestMode || $item->getType() == 'login') {
337*2b4583abSJames Collins                print '<a class="' . (($dropdown && !$guestMode) ? 'dropdown-item' : 'nav-item nav-link') . '" href="'.$item->getLink().'" title="'.$item->getTitle().'">';
338*2b4583abSJames Collins                if(!$hideIcons) print '<span class="icon">'.inlineSVG($item->getSvg()).'</span>';
339*2b4583abSJames Collins                if(!$hideText || ($dropdown && !$guestMode)) print '<span>' . $item->getLabel() . '</span>';
340*2b4583abSJames Collins                print '</a>';
341*2b4583abSJames Collins            }
342*2b4583abSJames Collins        }
343*2b4583abSJames Collins        if($dropdown && !$guestMode) print '</div></li>';
344*2b4583abSJames Collins
345*2b4583abSJames Collins    }
346*2b4583abSJames Collins
347*2b4583abSJames Collins    /**
348c165b184SJames Collins     * Include Sidebar
349c165b184SJames Collins     *
350c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
351c165b184SJames Collins     *
352c165b184SJames Collins     * @param   string  $type       Sidebar type
353c165b184SJames Collins     * @return  boolean             If sidebar was added
354c165b184SJames Collins     */
355c165b184SJames Collins    public function includeSidebar($type) {
356c165b184SJames Collins        global $conf;
357*2b4583abSJames Collins        global $ID;
358*2b4583abSJames Collins
359*2b4583abSJames Collins        $useACL = true; // Add these as config options?
360*2b4583abSJames Collins        $propagate = true;
361*2b4583abSJames Collins        $checkPropagate = true; // Add these as config options?
362c165b184SJames Collins
363c165b184SJames Collins        switch($type) {
364c165b184SJames Collins            case 'left':
365*2b4583abSJames Collins                if($this->getConf('showSidebar') && page_findnearest($conf['sidebar'], $useACL) != false && p_get_metadata($ID, 'nosidebar', false) == false) {
366*2b4583abSJames Collins                    $sidebar = tpl_includeFile('sidebarheader.html', false);
367*2b4583abSJames Collins
368*2b4583abSJames Collins                    $sidebar .= $this->includeSearch('sidebar-top', false);
369*2b4583abSJames Collins
370*2b4583abSJames Collins                    $confSidebar = tpl_include_page($conf['sidebar'], false, $propagate, $useACL);
371*2b4583abSJames Collins                    if($checkPropagate && $confSidebar == '') {
372*2b4583abSJames Collins                        $confSidebar = tpl_include_page($conf['sidebar'], false, false, $useACL);
373*2b4583abSJames Collins                    }
374*2b4583abSJames Collins                    $sidebar .= $confSidebar;
375*2b4583abSJames Collins
376*2b4583abSJames Collins                    $sidebar .= $this->includeSearch('sidebar-bottom', false);
377*2b4583abSJames Collins                    $sidebar .= tpl_includeFile('sidebarfooter.html', false);
378*2b4583abSJames Collins
379*2b4583abSJames Collins                    if($sidebar != '') {
380*2b4583abSJames Collins                        print '<aside class="col-md-2">' . $sidebar . '</aside>';
381*2b4583abSJames Collins                    }
382c165b184SJames Collins
383c165b184SJames Collins                    return true;
384c165b184SJames Collins                }
385c165b184SJames Collins
386c165b184SJames Collins                return false;
387c165b184SJames Collins        }
388c165b184SJames Collins
389c165b184SJames Collins        return false;
390c165b184SJames Collins    }
391c165b184SJames Collins
392*2b4583abSJames Collins    /**
393*2b4583abSJames Collins     * Include Page Tools
394*2b4583abSJames Collins     *
395*2b4583abSJames Collins     * @author  James Collins <james.collins@outlook.com.au>
396*2b4583abSJames Collins     *
397*2b4583abSJames Collins     * @param   string  $location       Page tools location
398*2b4583abSJames Collins     * @return  boolean             If page tools was added
399*2b4583abSJames Collins     */
400*2b4583abSJames Collins    public function includePageTools($location) {
401*2b4583abSJames Collins        $id = '';
402*2b4583abSJames Collins        $group_class = 'btn-group';
403*2b4583abSJames Collins
404*2b4583abSJames Collins        if((!$this->getConf('hidePageTools') && $location == 'side') || (!$this->getConf('hidePageToolsFooter') && $location == 'footer')) {
405*2b4583abSJames Collins            if($location == 'side') {
406*2b4583abSJames Collins                $id = 'dw__pagetools';
407*2b4583abSJames Collins                $group_class = 'btn-group-vertical';
408*2b4583abSJames Collins            }
409*2b4583abSJames Collins
410*2b4583abSJames Collins            print '<nav id="' . $id . '" class="hidden-print dw__pagetools">';
411*2b4583abSJames Collins                print '<div class="' . $group_class . '">';
412*2b4583abSJames Collins
413*2b4583abSJames Collins                $items = (new \dokuwiki\Menu\PageMenu())->getItems();
414*2b4583abSJames Collins                foreach($items as $item) {
415*2b4583abSJames Collins                    print '<a class="btn btn-sm btn-light" href="'.$item->getLink().'" title="'.$item->getTitle().'">'
416*2b4583abSJames Collins                    .'<span class="icon">'.inlineSVG($item->getSvg()).'</span>'
417*2b4583abSJames Collins                    . '<span class="a11y">'.$item->getLabel().'</span>'
418*2b4583abSJames Collins                    . '</a>';
419*2b4583abSJames Collins                }
420*2b4583abSJames Collins
421*2b4583abSJames Collins                print '</div>';
422*2b4583abSJames Collins            print '</nav>';
423*2b4583abSJames Collins        }
424*2b4583abSJames Collins    }
425*2b4583abSJames Collins
426*2b4583abSJames Collins    /**
427*2b4583abSJames Collins     * Include Search
428*2b4583abSJames Collins     *
429*2b4583abSJames Collins     * @author  James Collins <james.collins@outlook.com.au>
430*2b4583abSJames Collins     *
431*2b4583abSJames Collins     * @param   string  $location   Search location
432*2b4583abSJames Collins     * @return  boolean             If search was added
433*2b4583abSJames Collins     */
434*2b4583abSJames Collins    public function includeSearch($location, $print=true) {
435*2b4583abSJames Collins        global $lang;
436*2b4583abSJames Collins
437*2b4583abSJames Collins        //<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
438*2b4583abSJames Collins        $out = '';
439*2b4583abSJames Collins
440*2b4583abSJames Collins        if($location == $this->getConf('navbarSearchPosition') || ($location == 'footer' && $this->getConf('showSearchInFooter')) || ($location == 'sidebar-top' && $this->getConf('showSearchInSidebar') == 'top') || ($location == 'sidebar-bottom' && $this->getConf('showSearchInSidebar') == 'bottom')) {
441*2b4583abSJames Collins            $out .= '<form action="' . wl($ID) . '" accept-charset="utf-8" class="form-inline search" id="dw__search" method="get" role="search">';
442*2b4583abSJames Collins                $out .= '<div class="input-group"><input id="sqsearch" autocomplete="off" type="search" placeholder="' . $lang['btn_search'] . '" value="' . (($ACT == 'search') ? htmlspecialchars($QUERY) : '') . '" accesskey="f" name="q" class="form-control" title="[F]" style="height:auto"/>';
443*2b4583abSJames Collins                    $out .= '<div class="input-group-append"><button class="btn btn-secondary" type="submit" title="' .  $lang['btn_search'] . '">';
444*2b4583abSJames Collins                        $out .= $this->icon('search'); //$lang['btn_search'];  // TODO show icon if conf says and font awesome installed
445*2b4583abSJames Collins                    $out .= '</button></div></div>';
446*2b4583abSJames Collins                    $out .= '<input type="hidden" name="do" value="search" />';
447*2b4583abSJames Collins            $out .= '</form>';
448*2b4583abSJames Collins        }
449*2b4583abSJames Collins
450*2b4583abSJames Collins        if($print) {
451*2b4583abSJames Collins            print $out;
452*2b4583abSJames Collins            return '';
453*2b4583abSJames Collins        }
454*2b4583abSJames Collins
455*2b4583abSJames Collins        return $out;
456*2b4583abSJames Collins    }
457*2b4583abSJames Collins
458*2b4583abSJames Collins
459*2b4583abSJames Collins    /**
460*2b4583abSJames Collins     * Include Custom menus
461*2b4583abSJames Collins     *
462*2b4583abSJames Collins     * @author  James Collins <james.collins@outlook.com.au>
463*2b4583abSJames Collins     *
464*2b4583abSJames Collins     * @param   string  $location   menu location
465*2b4583abSJames Collins     * @return  boolean             If menu was added
466*2b4583abSJames Collins     */
467*2b4583abSJames Collins    public function includeCustomMenu($location, $addOuter=true) {
468*2b4583abSJames Collins        if(($location == 'navbar' && $this->getConf('showCustomPagesInNavbar')) || ($location == 'footer' && $this->getConf('showCustomPagesInFooter'))) {
469*2b4583abSJames Collins            if($addOuter) {
470*2b4583abSJames Collins                print '<ul class="nav">';
471*2b4583abSJames Collins            }
472*2b4583abSJames Collins
473*2b4583abSJames Collins            $menuList = $this->getConf('navbarCustomPages');
474*2b4583abSJames Collins
475*2b4583abSJames Collins            if($menuList != '') {
476*2b4583abSJames Collins                $menuList = explode(',', $menuList);
477*2b4583abSJames Collins
478*2b4583abSJames Collins                foreach($menuList as $item) {
479*2b4583abSJames Collins                    $i = strpos($item, '|');
480*2b4583abSJames Collins                    if($i !== false) {
481*2b4583abSJames Collins                        $url = $this->getLink(trim(substr($item, 0, $i)));
482*2b4583abSJames Collins                        $title = trim(substr($item, $i + 1));
483*2b4583abSJames Collins
484*2b4583abSJames Collins                        print('<li class="nav-item"><a href="' . $url . '" class="nav-link">' . $title . '</a></li>');
485*2b4583abSJames Collins                    }
486*2b4583abSJames Collins                }
487*2b4583abSJames Collins            }
488*2b4583abSJames Collins
489*2b4583abSJames Collins            if($addOuter) {
490*2b4583abSJames Collins                print '</ul>';
491*2b4583abSJames Collins            }
492*2b4583abSJames Collins        }
493*2b4583abSJames Collins    }
494c165b184SJames Collins
49575adba86SJames Collins    /**
49675adba86SJames Collins     * Print out breadcrumbs
49775adba86SJames Collins     *
49875adba86SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
49975adba86SJames Collins     *
50075adba86SJames Collins     * @param   string  $location   Location of breadcrumbs
50175adba86SJames Collins     */
50275adba86SJames Collins    public function includeBreadcrumbs($location) {
50375adba86SJames Collins        if($location == $this->getConf('breadcrumbsLoc')) {
50447161538SJames Collins            global $conf;
50547161538SJames Collins
50675adba86SJames Collins            print '<div class="mikio-breadcrumbs">';
50775adba86SJames Collins
50847161538SJames Collins            if($conf['breadcrumbs']) {
50975adba86SJames Collins                tpl_breadcrumbs();
51047161538SJames Collins            }
51147161538SJames Collins
51247161538SJames Collins            if($conf['youarehere']) {
51375adba86SJames Collins                tpl_youarehere();
51475adba86SJames Collins            }
51575adba86SJames Collins
51675adba86SJames Collins            print '</div>';
51775adba86SJames Collins        }
51847161538SJames Collins    }
51947161538SJames Collins
52047161538SJames Collins
52175adba86SJames Collins    /**
52275adba86SJames Collins     * Print out hero
52375adba86SJames Collins     *
52475adba86SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
52575adba86SJames Collins     */
52675adba86SJames Collins    public function includeHero() {
52775adba86SJames Collins        global $ACT;
528*2b4583abSJames Collins        global $INFO;
52947161538SJames Collins
530*2b4583abSJames Collins        // file_put_contents('output.txt', print_r($INFO, true));
531*2b4583abSJames Collins
532*2b4583abSJames Collins        if($ACT == 'show') {
53375adba86SJames Collins            if($this->getConf('useHeroTitle')) {
53475adba86SJames Collins                print '<div class="mikio-hero d-flex flex-row">';
53575adba86SJames Collins                    print '<div class="mikio-hero-text flex-grow-1">';
53675adba86SJames Collins                        $this->includeBreadcrumbs('hero');
53775adba86SJames Collins                        print '<h1 id="mikio-hero-title">';
538*2b4583abSJames Collins                            print tpl_pagetitle(null, true).' ';    // No idea why this requires a blank space afterwards to work?
53975adba86SJames Collins                        print '</h1>';
540*2b4583abSJames Collins                        print '<h2 class="mikio-hero-subtext">';
541*2b4583abSJames Collins                            // print $this->heroSubtitle;       // TODO scrape page for hero subtitle
54275adba86SJames Collins                        print '</h2>';
54375adba86SJames Collins                    print '</div>';
54447161538SJames Collins
545*2b4583abSJames Collins
546*2b4583abSJames Collins                    $hero_image = tpl_getMediaFile(array(':' . $INFO['namespace'] . ':hero.png', ':' . $INFO['namespace'] . ':hero.jpg', ':hero.png', ':hero.jpg', ':wiki:hero.png', ':wiki:hero.jpg', 'images/hero.png', 'images/hero.jpg'), false);
54775adba86SJames Collins                    if($hero_image != '') $hero_image = ' style="background-image:url(\''.$hero_image.'\');"';
54847161538SJames Collins
54975adba86SJames Collins                    print '<div class="mikio-hero-image"' . $hero_image . '></div>';
55075adba86SJames Collins                print '</div>';
55147161538SJames Collins            }
55275adba86SJames Collins        }
55375adba86SJames Collins    }
55475adba86SJames Collins
55575adba86SJames Collins
55675adba86SJames Collins    /**
55775adba86SJames Collins     * Print out TOC
55875adba86SJames Collins     *
55975adba86SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
56075adba86SJames Collins     */
56175adba86SJames Collins    public function includeTOC($location) {
56275adba86SJames Collins        if($this->getConf('tocfullheight') && $location === 'full') {
563*2b4583abSJames Collins            $toc = tpl_toc(true);
564*2b4583abSJames Collins
565*2b4583abSJames Collins            if($toc != '') {
56675adba86SJames Collins                print '<div class="mikio-toc mikio-toc-full">';
567*2b4583abSJames Collins                print $toc;
56875adba86SJames Collins                print '</div>';
569*2b4583abSJames Collins            }
57075adba86SJames Collins        } else if(!$this->getConf('tocfullheight') && $location === 'float') {
571*2b4583abSJames Collins            $toc = tpl_toc(true);
572*2b4583abSJames Collins
573*2b4583abSJames Collins            if($toc != '') {
57475adba86SJames Collins                print '<div class="mikio-toc mikio-toc-float">';
575*2b4583abSJames Collins                print $toc;
57675adba86SJames Collins                print '</div>';
57775adba86SJames Collins            }
57875adba86SJames Collins        }
579*2b4583abSJames Collins    }
58075adba86SJames Collins
58147161538SJames Collins
582c165b184SJames Collins    /**
583c165b184SJames Collins     * Parse HTML for bootstrap
584c165b184SJames Collins     *
585c165b184SJames Collins     * @author  James Collins <james.collins@outlook.com.au>
586c165b184SJames Collins     *
587c165b184SJames Collins     * @param   string  $content    HTML content to parse
588c165b184SJames Collins     * @return  string              Parsed HTML for bootstrap
589c165b184SJames Collins     */
59075adba86SJames Collins    public function parseContent($content) {
59147161538SJames Collins        $html = new \simple_html_dom;
592c165b184SJames Collins        $html->load($content, true, false);
593c165b184SJames Collins
594c165b184SJames Collins        # Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB)
595c165b184SJames Collins        if (!$html) {
596c165b184SJames Collins            return $content;
597c165b184SJames Collins        }
598c165b184SJames Collins
59947161538SJames Collins        # Hide page title if hero is enabled
60047161538SJames Collins        if($this->getConf('useHeroTitle')) {
60147161538SJames Collins            $pageTitle = tpl_pagetitle(null, true);
60247161538SJames Collins
60347161538SJames Collins            foreach($html->find('h1,h2,h3,h4') as $elm) {
60447161538SJames Collins                if($elm->innertext == $pageTitle) {
60547161538SJames Collins                    $elm->innertext = '';
60647161538SJames Collins                    break;
60747161538SJames Collins                }
60847161538SJames Collins            }
60947161538SJames Collins        }
610c165b184SJames Collins
611*2b4583abSJames Collins        # Hero subtitle
612*2b4583abSJames Collins        foreach($html->find('p') as $elm) {
613*2b4583abSJames Collins            $i = stripos($elm->innertext, '~~hero-subtitle');
614*2b4583abSJames Collins            if($i !== false) {
615*2b4583abSJames Collins                $j = strpos($elm->innertext, '~~', $i + 2);
616*2b4583abSJames Collins                if($j !== false) {
617*2b4583abSJames Collins                    if($j > $i + 16) {
618*2b4583abSJames Collins                        $subtitle = substr($elm->innertext, $i + 16, $j - $i - 16);
619*2b4583abSJames Collins                        foreach($html->find('.mikio-hero-subtext') as $subtitleElm) {
620*2b4583abSJames Collins                           $subtitleElm->innertext = $subtitle;
621*2b4583abSJames Collins                        }
622*2b4583abSJames Collins                    }
623*2b4583abSJames Collins
624*2b4583abSJames Collins                    $elm->innertext = substr($elm->innertext, $j + 2);
625*2b4583abSJames Collins                    break;
626*2b4583abSJames Collins                }
627*2b4583abSJames Collins            }
628*2b4583abSJames Collins        }
629*2b4583abSJames Collins
630c165b184SJames Collins        # Buttons
631c165b184SJames Collins        foreach ($html->find('.button') as $elm) {
632c165b184SJames Collins            if ($elm->tag == 'form') {
633c165b184SJames Collins                continue;
634c165b184SJames Collins            }
635c165b184SJames Collins            $elm->class .= ' btn';
636c165b184SJames Collins        }
637c165b184SJames Collins
638c165b184SJames Collins        foreach ($html->find('[type=button], [type=submit], [type=reset]') as $elm) {
639*2b4583abSJames Collins            if(stripos($elm->class, 'btn') === false) {
640c165b184SJames Collins                $elm->class .= ' btn btn-outline-secondary';
641c165b184SJames Collins            }
642*2b4583abSJames Collins        }
643c165b184SJames Collins
644c165b184SJames Collins        # Section Edit Button
645c165b184SJames Collins        foreach ($html->find('.btn_secedit [type=submit]') as $elm) {
646c165b184SJames Collins            $elm->class .= ' btn-sm';
647c165b184SJames Collins        }
648c165b184SJames Collins
649c165b184SJames Collins        # Section Edit icons
650c165b184SJames Collins        foreach ($html->find('.secedit.editbutton_section button') as $elm) {
651c165b184SJames Collins            $elm->innertext = '<i class="fa fa-edit" aria-hidden="true"></i> ' . $elm->innertext;
652c165b184SJames Collins        }
653c165b184SJames Collins
654c165b184SJames Collins        $content = $html->save();
655c165b184SJames Collins
656c165b184SJames Collins        $html->clear();
657c165b184SJames Collins        unset($html);
658c165b184SJames Collins
659c165b184SJames Collins        return $content;
660c165b184SJames Collins    }
661*2b4583abSJames Collins
662*2b4583abSJames Collins
663*2b4583abSJames Collins    /*** GET LINK ***/
664*2b4583abSJames Collins    public function getLink($str) {
665*2b4583abSJames Collins        $i = strpos($str, '://');
666*2b4583abSJames Collins        if($i !== false) return $str;
667*2b4583abSJames Collins
668*2b4583abSJames Collins        return wl($str);
669*2b4583abSJames Collins    }
670c165b184SJames Collins}
67147161538SJames Collins
67247161538SJames Collinsglobal $TEMPLATE;
67347161538SJames Collins
67447161538SJames Collins$TEMPLATE = \dokuwiki\template\mikio\Template::getInstance();