xref: /template/mikio/mikio.php (revision 471615384437d6616f95ab78b3ee5a17e9d657f2)
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();