1<?php
2/**
3 * Template Functions
4 *
5 * This file provides template specific custom functions that are
6 * not provided by the DokuWiki core.
7 * It is common practice to start each function with an underscore
8 * to make sure it won't interfere with future core functions.
9 */
10
11// must be run from within DokuWiki
12if (!defined('DOKU_INC')) die();
13
14/**
15 * Create link/button to discussion page and back
16 *
17 * @author Anika Henke <anika@selfthinker.org>
18 */
19function _tpl_discussion($discussionPage, $title, $backTitle, $link=0, $wrapper=0) {
20    global $ID;
21
22    $discussPage    = str_replace('@ID@', $ID, $discussionPage);
23    $discussPageRaw = str_replace('@ID@', '', $discussionPage);
24    $isDiscussPage  = strpos($ID, $discussPageRaw) !== false;
25    $backID         = str_replace($discussPageRaw, '', $ID);
26
27    if ($wrapper) echo "<$wrapper>";
28
29    if ($isDiscussPage) {
30        if ($link)
31            tpl_pagelink($backID, $backTitle);
32        else
33            echo html_btn('back2article', $backID, '', array(), 'get', 0, $backTitle);
34    } else {
35        if ($link)
36            tpl_pagelink($discussPage, $title);
37        else
38            echo html_btn('discussion', $discussPage, '', array(), 'get', 0, $title);
39    }
40
41    if ($wrapper) echo "</$wrapper>";
42}
43
44/**
45 * Create link/button to user page
46 *
47 * @author Anika Henke <anika@selfthinker.org>
48 */
49function _tpl_userpage($userPage, $title, $link=0, $wrapper=0) {
50    if (!$_SERVER['REMOTE_USER']) return;
51
52    global $conf;
53    $userPage = str_replace('@USER@', $_SERVER['REMOTE_USER'], $userPage);
54
55    if ($wrapper) echo "<$wrapper>";
56
57    if ($link)
58        tpl_pagelink($userPage, $title);
59    else
60        echo html_btn('userpage', $userPage, '', array(), 'get', 0, $title);
61
62    if ($wrapper) echo "</$wrapper>";
63}
64
65/**
66 * Create link/button to register page
67 * @deprecated DW versions > 2011-02-20 can use the core function tpl_action('register')
68 *
69 * @author Anika Henke <anika@selfthinker.org>
70 */
71function _tpl_register($link=0, $wrapper=0) {
72    global $conf;
73    global $lang;
74    global $ID;
75    $lang_register = !empty($lang['btn_register']) ? $lang['btn_register'] : $lang['register'];
76
77    if ($_SERVER['REMOTE_USER'] || !$conf['useacl'] || !actionOK('register')) return;
78
79    if ($wrapper) echo "<$wrapper>";
80
81    if ($link)
82        tpl_link(wl($ID, 'do=register'), $lang_register, 'class="action register" rel="nofollow"');
83    else
84        echo html_btn('register', $ID, '', array('do'=>'register'), 'get', 0, $lang_register);
85
86    if ($wrapper) echo "</$wrapper>";
87}
88
89/**
90 * Wrapper around custom template actions
91 *
92 * @author Anika Henke <anika@selfthinker.org>
93 */
94function _tpl_action($type, $link=0, $wrapper=0) {
95    switch ($type) {
96        case 'discussion':
97            if (tpl_getConf('discussionPage')) {
98                _tpl_discussion(tpl_getConf('discussionPage'), tpl_getLang('discussion'), tpl_getLang('back_to_article'), $link, $wrapper);
99            }
100            break;
101        case 'userpage':
102            if (tpl_getConf('userPage')) {
103                _tpl_userpage(tpl_getConf('userPage'), tpl_getLang('userpage'), $link, $wrapper);
104            }
105            break;
106        case 'register': // deprecated
107            _tpl_register($link, $wrapper);
108            break;
109    }
110}
111
112
113
114/* fallbacks for things missing in older DokuWiki versions
115********************************************************************/
116
117
118/* if newer settings exist in the core, use them, otherwise fall back to template settings */
119
120if (!isset($conf['tagline'])) {
121    $conf['tagline'] = tpl_getConf('tagline');
122}
123
124if (!isset($conf['sidebar'])) {
125    $conf['sidebar'] = tpl_getConf('sidebarID');
126}
127
128/* these $lang strings are now in the core */
129
130if (!isset($lang['user_tools'])) {
131    $lang['user_tools'] = tpl_getLang('user_tools');
132}
133if (!isset($lang['site_tools'])) {
134    $lang['site_tools'] = tpl_getLang('site_tools');
135}
136if (!isset($lang['page_tools'])) {
137    $lang['page_tools'] = tpl_getLang('page_tools');
138}
139if (!isset($lang['skip_to_content'])) {
140    $lang['skip_to_content'] = tpl_getLang('skip_to_content');
141}
142
143
144/**
145 * copied from core (available since Adora Belle)
146 */
147if (!function_exists('tpl_getMediaFile')) {
148    function tpl_getMediaFile($search, $abs = false, &$imginfo = null) {
149        $img     = '';
150        $file    = '';
151        $ismedia = false;
152        // loop through candidates until a match was found:
153        foreach($search as $img) {
154            if(substr($img, 0, 1) == ':') {
155                $file    = mediaFN($img);
156                $ismedia = true;
157            } else {
158                $file    = tpl_incdir().$img;
159                $ismedia = false;
160            }
161
162            if(file_exists($file)) break;
163        }
164
165        // fetch image data if requested
166        if(!is_null($imginfo)) {
167            $imginfo = getimagesize($file);
168        }
169
170        // build URL
171        if($ismedia) {
172            $url = ml($img, '', true, '', $abs);
173        } else {
174            $url = tpl_basedir().$img;
175            if($abs) $url = DOKU_URL.substr($url, strlen(DOKU_REL));
176        }
177
178        return $url;
179    }
180}
181
182/**
183 * copied from core (available since Angua)
184 */
185if (!function_exists('tpl_favicon')) {
186    function tpl_favicon($types = array('favicon')) {
187
188        $return = '';
189
190        foreach($types as $type) {
191            switch($type) {
192                case 'favicon':
193                    $look = array(':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico');
194                    $return .= '<link rel="shortcut icon" href="'.tpl_getMediaFile($look).'" />'.NL;
195                    break;
196                case 'mobile':
197                    $look = array(':wiki:apple-touch-icon.png', ':apple-touch-icon.png', 'images/apple-touch-icon.png');
198                    $return .= '<link rel="apple-touch-icon" href="'.tpl_getMediaFile($look).'" />'.NL;
199                    break;
200                case 'generic':
201                    // ideal world solution, which doesn't work in any browser yet
202                    $look = array(':wiki:favicon.svg', ':favicon.svg', 'images/favicon.svg');
203                    $return .= '<link rel="icon" href="'.tpl_getMediaFile($look).'" type="image/svg+xml" />'.NL;
204                    break;
205            }
206        }
207
208        return $return;
209    }
210}
211
212/**
213 * copied from core (available since Adora Belle)
214 */
215if (!function_exists('tpl_includeFile')) {
216    function tpl_includeFile($file) {
217        global $config_cascade;
218        foreach(array('protected', 'local', 'default') as $config_group) {
219            if(empty($config_cascade['main'][$config_group])) continue;
220            foreach($config_cascade['main'][$config_group] as $conf_file) {
221                $dir = dirname($conf_file);
222                if(file_exists("$dir/$file")) {
223                    include("$dir/$file");
224                    return;
225                }
226            }
227        }
228
229        // still here? try the template dir
230        $file = tpl_incdir().$file;
231        if(file_exists($file)) {
232            include($file);
233        }
234    }
235}
236
237/**
238 * copied from core (available since Adora Belle)
239 */
240if (!function_exists('tpl_incdir')) {
241    function tpl_incdir() {
242        global $conf;
243        return DOKU_INC.'lib/tpl/'.$conf['template'].'/';
244    }
245}
246
247function _tpl_toc_to_twitter_bootstrap_event_hander_dump_level($data, $header='', $firstlevel=false)
248{
249
250
251    if (count($data) == 0)
252    {
253        return '';
254    }
255
256    if (tpl_getConf('useSideToCChevrons') == 1)
257    {
258        $chevronHTML = '<i class="glyphicon glyphicon-chevron-right"></i> ';
259    } else {
260        $chevronHTML = '';
261    }
262
263    $ret = '';
264    $ret .= '<ul class="nav list-group">';
265    if ($header != '') {
266        $ret .= '<li class="list-group-item nav-header">'.$header.'</li>';
267    }
268    $ret .= '<li class="divider"></li>';
269
270    $first = true;
271    $li_inner = ' class ="active"';
272
273    //Only supports top level links for now.
274    foreach($data as $heading)
275    {
276        $ret .= '<li' . $li_inner . '><a href="#' . $heading['link'] . '">'. $chevronHTML . $heading['title'] . '</a></li>';
277
278        $li_inner = '';
279    }
280
281    $ret .= '<li class="divider"></li>';
282    $ret .= '</ul>';
283
284    return $ret;
285}
286
287function _tpl_toc_to_twitter_bootstrap_event_hander(&$event, $param)
288{
289    global $conf;
290    //This is tied to the specific format of the DokuWiki TOC.
291    echo _tpl_toc_to_twitter_bootstrap_event_hander_dump_level($event->data, $conf['sidebar'], true);
292}
293
294function _tpl_toc_to_twitter_bootstrap()
295{
296    //Force generation of TOC, request that the TOC is returned as HTML, but then ignore the returned string. The hook will instead dump out the TOC.
297    global $EVENT_HANDLER;
298    $EVENT_HANDLER->register_hook('TPL_TOC_RENDER', 'AFTER', NULL, '_tpl_toc_to_twitter_bootstrap_event_hander');
299    tpl_toc(true);
300}
301
302
303//Output various links to user tools wrapped in a user-specified element.
304function _tpl_output_tools_twitter_bootstrap($showTools = true, $element = 'li')
305{
306    if ($showTools) {
307        //Separate whatever was there from these links.
308        echo '<li class="divider-vertical"></li>';
309        tpl_action('recent', 1, 'li');
310        tpl_action('media', 1, 'li');
311        tpl_action('index', 1, 'li');
312
313        echo '<li class="divider-vertical"></li>';
314
315        tpl_action('admin', 1, $element);
316        _tpl_action('userpage', 1, $element);
317        tpl_action('profile', 1, $element);
318        tpl_action('register', 1, $element);
319        tpl_action('login', 1, $element);
320    }
321}
322
323function _tpl_output_page_tools($showTools = true, $element = 'li'){
324    global $lang;
325
326    $textonly = true;
327    $spandivider = '';
328    $elementbegin = "<$element>";
329    $elementend = "</$element>";
330
331    if ($showTools) {
332        echo '<ul class="nav navbar-nav">';
333            //echo '<li>'.$lang['page_tools'].$spandivider;
334
335            $content = tpl_action('edit', $textonly, '', true);
336            if ($content != '') { echo $elementbegin.$content.$spandivider.$elementend; }
337
338            echo $elementbegin;
339            //Notice the use of _tpl_action instead of tpl_action. This doesn't
340            //actully return the string and instead automatically prints it
341            //out.
342            _tpl_action('discussion', $textonly, '', true);
343            echo $spandivider;
344            echo $elementend;
345
346            $content = tpl_action('revisions', $textonly, '', true);
347            if ($content != '') { echo $elementbegin.$content.$spandivider.$elementend; }
348
349            $content = tpl_action('backlink', $textonly, '', true);
350            if ($content != '') { echo $elementbegin.$content.$spandivider.$elementend; }
351
352            $content = tpl_action('subscribe', $textonly, '', true);
353            if ($content != '') { echo $elementbegin.$content.$spandivider.$elementend; }
354
355            $content = tpl_action('revert', $textonly, '', true);
356            if ($content != '') { echo $elementbegin.$content.$spandivider.$elementend; }
357
358            echo $elementbegin;
359            $content = tpl_action('top', $textonly, '', true);
360            echo $content;
361            echo $elementend;
362        echo '</ul>';
363    }
364}
365
366function _tpl_output_search_bar()
367{
368    //Modified from the official tpl_searchform function.
369    global $lang;
370    global $ACT;
371    global $QUERY;
372
373    // don't print the search form if search action has been disabled
374    if(!actionOk('search')) return false;
375
376    print '<form action="'.wl().'" accept-charset="utf-8" class="search" id="dw__search" method="get"><div class="no">';
377    print '<input type="hidden" name="do" value="search" />';
378    print '<input type="text" placeholder="'.$lang['btn_search'].'" ';
379    if($ACT == 'search') print 'value="'.htmlspecialchars($QUERY).'" ';
380    if(!$autocomplete) print 'autocomplete="off" ';
381    print 'id="qsearch__in" accesskey="f" name="id" class="edit" title="[F]" />';
382
383    print '<button type="submit" value="" class="button btn" title="'.$lang['btn_search'].'">';
384    print '<i class="glyphicon glyphicon-search"></i></button>';
385
386    if($ajax) print '<div id="qsearch__out" class="ajax_qsearch JSpopup"></div>';
387    print '</div></form>';
388    return true;
389
390}
391