1 |
|
<?php
|
2 |
|
|
3 |
|
namespace dokuwiki\template\bootstrap3;
|
4 |
|
|
5 |
|
/**
|
6 |
|
* DokuWiki Bootstrap3 Template: Template Class
|
7 |
|
*
|
8 |
|
* @link http://dokuwiki.org/template:bootstrap3
|
9 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
10 |
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
11 |
|
*/
|
12 |
|
|
13 |
4
|
class Template
|
14 |
|
{
|
15 |
|
|
16 |
|
private $plugins = array();
|
17 |
|
private $confMetadata = array();
|
18 |
|
private $toolsMenu = array();
|
19 |
|
|
20 |
|
public $tplDir = '';
|
21 |
|
public $baseDir = '';
|
22 |
|
|
23 |
11
|
public function __construct()
|
24 |
|
{
|
25 |
|
|
26 |
|
global $JSINFO;
|
27 |
|
global $INPUT;
|
28 |
|
global $ACT;
|
29 |
|
global $INFO;
|
30 |
|
|
31 |
|
$this->tplDir = tpl_incdir();
|
32 |
|
$this->baseDir = tpl_basedir();
|
33 |
|
|
34 |
|
$this->registerHooks();
|
35 |
|
$this->initPlugins();
|
36 |
|
$this->initToolsMenu();
|
37 |
|
$this->loadConfMetadata();
|
38 |
|
|
39 |
|
// Get the template info (useful for debug)
|
40 |
|
if (isset($INFO['isadmin']) && $INPUT->str('do') && $INPUT->str('do') == 'check') {
|
41 |
|
msg('Template version ' . $this->getVersion(), 1, '', '', MSG_ADMINS_ONLY);
|
42 |
|
}
|
43 |
|
|
44 |
|
// Populate JSINFO object
|
45 |
|
$JSINFO['bootstrap3'] = array(
|
46 |
|
'mode' => $ACT,
|
47 |
|
'toc' => array(),
|
48 |
|
'config' => array(
|
49 |
|
'collapsibleSections' => (int) $this->getConf('collapsibleSections'),
|
50 |
|
'fixedTopNavbar' => (int) $this->getConf('fixedTopNavbar'),
|
51 |
|
'showSemanticPopup' => (int) $this->getConf('showSemanticPopup'),
|
52 |
|
'sidebarOnNavbar' => (int) $this->getConf('sidebarOnNavbar'),
|
53 |
|
'tagsOnTop' => (int) $this->getConf('tagsOnTop'),
|
54 |
|
'tocAffix' => (int) $this->getConf('tocAffix'),
|
55 |
|
'tocCollapseOnScroll' => (int) $this->getConf('tocCollapseOnScroll'),
|
56 |
|
'tocCollapsed' => (int) $this->getConf('tocCollapsed'),
|
57 |
|
'tocLayout' => $this->getConf('tocLayout'),
|
58 |
|
'useAnchorJS' => (int) $this->getConf('useAnchorJS'),
|
59 |
|
'useAlternativeToolbarIcons' => (int) $this->getConf('useAlternativeToolbarIcons'),
|
60 |
|
),
|
61 |
|
);
|
62 |
|
|
63 |
|
if ($ACT == 'admin') {
|
64 |
|
$JSINFO['bootstrap3']['admin'] = hsc($INPUT->str('page'));
|
65 |
|
}
|
66 |
|
|
67 |
|
if (!defined('MAX_FILE_SIZE')) {
|
68 |
|
if ($pagesize = $this->getConf('domParserMaxPageSize')) {
|
69 |
|
define('MAX_FILE_SIZE', $pagesize);
|
70 |
|
}
|
71 |
|
}
|
72 |
|
}
|
73 |
|
|
74 |
|
public function getVersion()
|
75 |
|
{
|
76 |
|
$template_info = confToHash($this->tplDir . 'template.info.txt');
|
77 |
|
$template_version = 'v' . $template_info['date'];
|
78 |
|
|
79 |
|
if (isset($template_info['build'])) {
|
80 |
|
$template_version .= ' (' . $template_info['build'] . ')';
|
81 |
|
}
|
82 |
|
|
83 |
|
return $template_version;
|
84 |
|
}
|
85 |
|
|
86 |
|
private function registerHooks()
|
87 |
|
{
|
88 |
|
/** @var \Doku_Event_Handler */
|
89 |
|
global $EVENT_HANDLER;
|
90 |
|
|
91 |
|
$events_dispatcher = array(
|
92 |
|
'FORM_QUICKSEARCH_OUTPUT' => 'searchHandler',
|
93 |
|
'FORM_SEARCH_OUTPUT' => 'searchHandler',
|
94 |
|
'HTML_DRAFTFORM_OUTPUT' => 'draftFormHandler',
|
95 |
|
'HTML_EDITFORM_OUTPUT' => 'editFormHandler',
|
96 |
|
'HTML_LOGINFORM_OUTPUT' => 'accountFormHandler',
|
97 |
|
'HTML_RESENDPWDFORM_OUTPUT' => 'accountFormHandler',
|
98 |
|
'HTML_PROFILEDELETEFORM_OUTPUT' => 'accountFormHandler',
|
99 |
|
'HTML_RECENTFORM_OUTPUT' => 'revisionsFormHandler',
|
100 |
|
'HTML_REGISTERFORM_OUTPUT' => 'accountFormHandler',
|
101 |
|
'HTML_REVISIONSFORM_OUTPUT' => 'revisionsFormHandler',
|
102 |
|
'HTML_SUBSCRIBEFORM_OUTPUT' => 'accountFormHandler',
|
103 |
|
'HTML_UPDATEPROFILEFORM_OUTPUT' => 'accountFormHandler',
|
104 |
|
'PLUGIN_TAG_LINK' => 'tagPluginHandler',
|
105 |
|
'PLUGIN_TPLINC_LOCATIONS_SET' => 'tplIncPluginHandler',
|
106 |
|
'SEARCH_QUERY_FULLPAGE' => 'searchHandler',
|
107 |
|
'SEARCH_QUERY_PAGELOOKUP' => 'searchHandler',
|
108 |
|
'SEARCH_RESULT_FULLPAGE' => 'searchHandler',
|
109 |
|
'SEARCH_RESULT_PAGELOOKUP' => 'searchHandler',
|
110 |
|
'TPL_CONTENT_DISPLAY' => 'contentHandler',
|
111 |
|
'TPL_METAHEADER_OUTPUT' => 'metaheadersHandler',
|
112 |
|
|
113 |
|
);
|
114 |
|
|
115 |
|
foreach ($events_dispatcher as $event => $method) {
|
116 |
|
$EVENT_HANDLER->register_hook($event, 'BEFORE', $this, $method);
|
117 |
|
}
|
118 |
|
}
|
119 |
|
|
120 |
1
|
public function accountFormHandler(\Doku_Event $event)
|
121 |
|
{
|
122 |
|
foreach ($event->data->_content as $key => $item) {
|
123 |
|
if (is_array($item) && isset($item['_elem'])) {
|
124 |
|
$title_icon = 'account';
|
125 |
|
$button_class = 'btn btn-success';
|
126 |
|
$button_icon = 'arrow-right';
|
127 |
|
|
128 |
|
switch ($event->name) {
|
129 |
|
case 'HTML_LOGINFORM_OUTPUT':
|
130 |
|
$title_icon = 'account';
|
131 |
|
$button_icon = 'lock';
|
132 |
|
break;
|
133 |
|
case 'HTML_UPDATEPROFILEFORM_OUTPUT':
|
134 |
|
$title_icon = 'account-card-details-outline';
|
135 |
|
break;
|
136 |
|
case 'HTML_PROFILEDELETEFORM_OUTPUT':
|
137 |
|
$title_icon = 'account-remove';
|
138 |
|
$button_class = 'btn btn-danger';
|
139 |
|
break;
|
140 |
|
case 'HTML_REGISTERFORM_OUTPUT':
|
141 |
|
$title_icon = 'account-plus';
|
142 |
|
break;
|
143 |
|
case 'HTML_SUBSCRIBEFORM_OUTPUT':
|
144 |
|
$title_icon = null;
|
145 |
|
break;
|
146 |
|
case 'HTML_RESENDPWDFORM_OUTPUT':
|
147 |
|
$title_icon = 'lock-reset';
|
148 |
|
break;
|
149 |
|
}
|
150 |
|
|
151 |
|
// Legend
|
152 |
|
if ($item['_elem'] == 'openfieldset') {
|
153 |
|
$event->data->_content[$key]['_legend'] = (($title_icon) ? iconify("mdi:$title_icon") : '') . ' ' . $event->data->_content[$key]['_legend'];
|
154 |
|
}
|
155 |
|
|
156 |
|
// Save button
|
157 |
|
if (isset($item['type']) && $item['type'] == 'submit') {
|
158 |
|
$event->data->_content[$key]['class'] = " $button_class";
|
159 |
|
$event->data->_content[$key]['value'] = (($button_icon) ? iconify("mdi:$button_icon") : '') . ' ' . $event->data->_content[$key]['value'];
|
160 |
|
}
|
161 |
|
}
|
162 |
|
}
|
163 |
|
}
|
164 |
|
|
165 |
|
/**
|
166 |
|
* Handle HTML_DRAFTFORM_OUTPUT event
|
167 |
|
*
|
168 |
|
* @param \Doku_Event $event Event handler
|
169 |
|
*
|
170 |
|
* @return void
|
171 |
|
**/
|
172 |
|
public function draftFormHandler(\Doku_Event $event)
|
173 |
|
{
|
174 |
|
foreach ($event->data->_content as $key => $item) {
|
175 |
|
if (is_array($item) && isset($item['_elem'])) {
|
176 |
|
if ($item['_action'] == 'draftdel') {
|
177 |
|
$event->data->_content[$key]['class'] = ' btn btn-danger';
|
178 |
|
$event->data->_content[$key]['value'] = iconify('mdi:close') . ' ' . $event->data->_content[$key]['value'];
|
179 |
|
}
|
180 |
|
|
181 |
|
if ($item['_action'] == 'recover') {
|
182 |
|
$event->data->_content[$key]['value'] = iconify('mdi:refresh') . ' ' . $event->data->_content[$key]['value'];
|
183 |
|
}
|
184 |
|
|
185 |
|
if ($item['_action'] == 'show') {
|
186 |
|
$event->data->_content[$key]['value'] = iconify('mdi:arrow-left') . ' ' . $event->data->_content[$key]['value'];
|
187 |
|
}
|
188 |
|
}
|
189 |
|
}
|
190 |
|
}
|
191 |
|
|
192 |
|
/**
|
193 |
|
* Handle HTML_EDITFORM_OUTPUT and HTML_DRAFTFORM_OUTPUT event
|
194 |
|
*
|
195 |
|
* @param \Doku_Event $event Event handler
|
196 |
|
*
|
197 |
|
* @return void
|
198 |
|
**/
|
199 |
|
public function editFormHandler(\Doku_Event $event)
|
200 |
|
{
|
201 |
|
foreach ($event->data->_content as $key => $item) {
|
202 |
|
if (is_array($item) && isset($item['_elem'])) {
|
203 |
|
// Save button
|
204 |
|
if ($item['_action'] == 'save') {
|
205 |
|
$event->data->_content[$key]['class'] = ' btn btn-success';
|
206 |
|
$event->data->_content[$key]['value'] = iconify('mdi:content-save') . ' ' . $event->data->_content[$key]['value'];
|
207 |
|
}
|
208 |
|
|
209 |
|
// Preview and Show buttons
|
210 |
|
if ($item['_action'] == 'preview' || $item['_action'] == 'show') {
|
211 |
|
$event->data->_content[$key]['value'] = iconify('mdi:file-document-outline') . ' ' . $event->data->_content[$key]['value'];
|
212 |
|
}
|
213 |
|
|
214 |
|
// Cancel button
|
215 |
|
if ($item['_action'] == 'cancel') {
|
216 |
|
$event->data->_content[$key]['value'] = iconify('mdi:arrow-left') . ' ' . $event->data->_content[$key]['value'];
|
217 |
|
}
|
218 |
|
}
|
219 |
|
}
|
220 |
|
}
|
221 |
|
|
222 |
|
/**
|
223 |
|
* Handle HTML_REVISIONSFORM_OUTPUT and HTML_RECENTFORM_OUTPUT events
|
224 |
|
*
|
225 |
|
* @param \Doku_Event $event Event handler
|
226 |
|
*
|
227 |
|
* @return void
|
228 |
|
**/
|
229 |
1
|
public function revisionsFormHandler(\Doku_Event $event)
|
230 |
|
{
|
231 |
|
foreach ($event->data->_content as $key => $item) {
|
232 |
|
// Revision form
|
233 |
|
if (is_array($item) && isset($item['_elem'])) {
|
234 |
|
if ($item['_elem'] == 'opentag' && $item['_tag'] == 'span' && strstr($item['class'], 'sizechange')) {
|
235 |
|
if (strstr($item['class'], 'positive')) {
|
236 |
|
$event->data->_content[$key]['class'] .= ' label label-success';
|
237 |
|
}
|
238 |
|
|
239 |
|
if (strstr($item['class'], 'negative')) {
|
240 |
|
$event->data->_content[$key]['class'] .= ' label label-danger';
|
241 |
|
}
|
242 |
|
}
|
243 |
|
|
244 |
|
// Recent form
|
245 |
|
if ($item['_elem'] == 'opentag' && $item['_tag'] == 'li' && strstr($item['class'], 'minor')) {
|
246 |
|
$event->data->_content[$key]['class'] .= ' text-muted';
|
247 |
|
}
|
248 |
|
}
|
249 |
|
}
|
250 |
|
}
|
251 |
|
|
252 |
|
public function contentHandler(\Doku_Event $event)
|
253 |
|
{
|
254 |
|
$event->data = $this->normalizeContent($event->data);
|
255 |
|
}
|
256 |
|
|
257 |
|
public function searchHandler(\Doku_Event $event)
|
258 |
|
{
|
259 |
|
//dbg(print_r($event, 1));
|
260 |
|
|
261 |
|
if ($event->name == 'SEARCH_RESULT_PAGELOOKUP') {
|
262 |
|
array_unshift($event->data['listItemContent'], iconify('mdi:file-document-outline', array('title' => hsc($event->data['page']))) . ' ');
|
263 |
|
}
|
264 |
|
|
265 |
|
if ($event->name == 'SEARCH_RESULT_FULLPAGE') {
|
266 |
|
$event->data['resultBody']['meta'] = str_replace(
|
267 |
|
array('<span class="lastmod">', '<span class="hits">'),
|
268 |
|
array('<span class="lastmod">' . iconify('mdi:calendar') . ' ', '<span class="hits"' . iconify('mdi:poll') . ' '),
|
269 |
|
'<small>' . $event->data['resultBody']['meta'] . '</small>'
|
270 |
|
);
|
271 |
|
}
|
272 |
|
}
|
273 |
|
|
274 |
|
/**
|
275 |
|
* Load the template assets (Bootstrap, AnchorJS, etc)
|
276 |
|
*
|
277 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
278 |
|
* @todo Move the specific-padding size of Bootswatch template in template.less
|
279 |
|
*
|
280 |
|
* @param \Doku_Event $event
|
281 |
|
*/
|
282 |
1
|
public function metaheadersHandler(\Doku_Event $event)
|
283 |
|
{
|
284 |
|
|
285 |
|
global $ACT;
|
286 |
1
|
global $INPUT;
|
287 |
|
|
288 |
|
$fixed_top_navbar = $this->getConf('fixedTopNavbar');
|
289 |
|
|
290 |
|
if ($google_analitycs = $this->getGoogleAnalitycs()) {
|
291 |
|
$event->data['script'][] = array(
|
292 |
|
'type' => 'text/javascript',
|
293 |
|
'_data' => $google_analitycs,
|
294 |
|
);
|
295 |
|
}
|
296 |
|
|
297 |
|
// Apply some FIX
|
298 |
|
if ($ACT || defined('DOKU_MEDIADETAIL')) {
|
299 |
|
// Default Padding
|
300 |
|
$navbar_padding = 20;
|
301 |
|
|
302 |
|
if ($fixed_top_navbar) {
|
303 |
|
$navbar_height = $this->getNavbarHeight();
|
304 |
|
$navbar_padding += $navbar_height;
|
305 |
|
}
|
306 |
|
|
307 |
|
$styles = array();
|
308 |
|
|
309 |
|
// TODO implement in css.php dispatcher
|
310 |
|
|
311 |
|
$styles[] = "body { margin-top: {$navbar_padding}px; }";
|
312 |
|
$styles[] = ' #dw__toc.affix { top: ' . ($navbar_padding - 10) . 'px; position: fixed !important; }';
|
313 |
|
|
314 |
|
if ($this->getConf('tocCollapseSubSections')) {
|
315 |
|
$styles[] = ' #dw__toc .nav .nav .nav { display: none; }';
|
316 |
|
}
|
317 |
|
|
318 |
|
$event->data['style'][] = array(
|
319 |
|
'type' => 'text/css',
|
320 |
|
'_data' => '@media screen { ' . implode(" ", $styles) . ' }',
|
321 |
|
);
|
322 |
|
}
|
323 |
|
}
|
324 |
|
|
325 |
|
public function tagPluginHandler(\Doku_Event $event)
|
326 |
|
{
|
327 |
|
$event->data['class'] .= ' tag label label-default mx-1';
|
328 |
|
$event->data['title'] = iconify('mdi:tag-text-outline') . ' ' . $event->data['title'];
|
329 |
|
}
|
330 |
|
|
331 |
|
public function tplIncPluginHandler(\Doku_Event $event)
|
332 |
|
{
|
333 |
|
$event->data['header'] = 'Header of page below the navbar (header)';
|
334 |
|
$event->data['topheader'] = 'Top Header of page (topheader)';
|
335 |
|
$event->data['pagefooter'] = 'Footer below the page content (pagefooter)';
|
336 |
|
$event->data['pageheader'] = 'Header above the page content (pageheader)';
|
337 |
|
$event->data['sidebarfooter'] = 'Footer below the sidebar (sidebarfooter)';
|
338 |
|
$event->data['sidebarheader'] = 'Header above the sidebar (sidebarheader)';
|
339 |
|
$event->data['rightsidebarfooter'] = 'Footer below the right-sidebar (rightsidebarfooter)';
|
340 |
|
$event->data['rightsidebarheader'] = 'Header above the right-sidebar (rightsidebarheader)';
|
341 |
|
}
|
342 |
|
|
343 |
|
private function initPlugins()
|
344 |
|
{
|
345 |
|
$this->plugins['tplinc'] = plugin_load('helper', 'tplinc');
|
346 |
|
$this->plugins['tag'] = plugin_load('helper', 'tag');
|
347 |
|
$this->plugins['userhomepage'] = plugin_load('helper', 'userhomepage');
|
348 |
|
$this->plugins['translation'] = plugin_load('helper', 'translation');
|
349 |
|
$this->plugins['pagelist'] = plugin_load('helper', 'pagelist');
|
350 |
|
}
|
351 |
|
|
352 |
|
public function getPlugin($plugin)
|
353 |
|
{
|
354 |
|
if (plugin_isdisabled($plugin)) {
|
355 |
|
return false;
|
356 |
|
}
|
357 |
|
|
358 |
|
if (!isset($this->plugins[$plugin])) {
|
359 |
|
return false;
|
360 |
|
}
|
361 |
|
|
362 |
|
return $this->plugins[$plugin];
|
363 |
|
}
|
364 |
|
|
365 |
|
/**
|
366 |
|
* Get the singleton instance
|
367 |
|
*
|
368 |
|
* @return Template
|
369 |
|
*/
|
370 |
|
public static function getInstance()
|
371 |
|
{
|
372 |
|
static $instance = null;
|
373 |
|
|
374 |
|
if ($instance === null) {
|
375 |
|
$instance = new self;
|
376 |
|
}
|
377 |
|
|
378 |
|
return $instance;
|
379 |
|
}
|
380 |
|
|
381 |
|
/**
|
382 |
|
* Get the content to include from the tplinc plugin
|
383 |
|
*
|
384 |
|
* prefix and postfix are only added when there actually is any content
|
385 |
|
*
|
386 |
|
* @param string $location
|
387 |
|
* @return string
|
388 |
|
*/
|
389 |
2
|
public function includePage($location, $return = false)
|
390 |
|
{
|
391 |
|
|
392 |
|
$content = '';
|
393 |
|
|
394 |
|
if ($plugin = $this->getPlugin('tplinc')) {
|
395 |
|
$content = $plugin->renderIncludes($location);
|
396 |
|
}
|
397 |
|
|
398 |
|
if ($content === '') {
|
399 |
|
$content = tpl_include_page($location, 0, 1, $this->getConf('useACL'));
|
400 |
|
}
|
401 |
|
|
402 |
|
if ($content === '') {
|
403 |
|
return '';
|
404 |
|
}
|
405 |
|
|
406 |
|
$content = $this->normalizeContent($content);
|
407 |
|
|
408 |
|
if ($return) {
|
409 |
|
return $content;
|
410 |
|
}
|
411 |
|
|
412 |
|
echo $content;
|
413 |
|
return '';
|
414 |
|
}
|
415 |
|
|
416 |
|
/**
|
417 |
|
* Get the template configuration metadata
|
418 |
|
*
|
419 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
420 |
|
*
|
421 |
|
* @param string $key
|
422 |
|
* @return array|string
|
423 |
|
*/
|
424 |
|
public function getConfMetadata($key = null)
|
425 |
|
{
|
426 |
|
if ($key && isset($this->confMetadata[$key])) {
|
427 |
|
return $this->confMetadata[$key];
|
428 |
|
}
|
429 |
|
|
430 |
|
return null;
|
431 |
|
}
|
432 |
|
|
433 |
|
private function loadConfMetadata()
|
434 |
|
{
|
435 |
|
$meta = array();
|
436 |
|
$file = $this->tplDir . 'conf/metadata.php';
|
437 |
|
|
438 |
|
include $file;
|
439 |
|
|
440 |
|
$this->confMetadata = $meta;
|
441 |
|
}
|
442 |
|
|
443 |
|
/**
|
444 |
|
* Simple wrapper for tpl_getConf
|
445 |
|
*
|
446 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
447 |
|
*
|
448 |
|
* @param string $key
|
449 |
|
* @param mixed $default value
|
450 |
|
* @return mixed
|
451 |
|
*/
|
452 |
6
|
public function getConf($key, $default = false)
|
453 |
|
{
|
454 |
1
|
global $ACT, $INFO, $ID, $conf;
|
455 |
|
|
456 |
|
$value = tpl_getConf($key, $default);
|
457 |
|
|
458 |
|
switch ($key) {
|
459 |
|
case 'useAvatar':
|
460 |
|
|
461 |
|
if ($value == 'off') {
|
462 |
|
return false;
|
463 |
|
}
|
464 |
|
|
465 |
|
return $value;
|
466 |
|
|
467 |
|
case 'bootstrapTheme':
|
468 |
|
|
469 |
|
@list($theme, $bootswatch) = $this->getThemeForNamespace();
|
470 |
|
if ($theme) {
|
471 |
|
return $theme;
|
472 |
|
}
|
473 |
|
|
474 |
|
return $value;
|
475 |
|
|
476 |
|
case 'bootswatchTheme':
|
477 |
|
|
478 |
|
@list($theme, $bootswatch) = $this->getThemeForNamespace();
|
479 |
|
if ($bootswatch) {
|
480 |
|
return $bootswatch;
|
481 |
|
}
|
482 |
|
|
483 |
|
return $value;
|
484 |
|
|
485 |
|
case 'showTools':
|
486 |
|
case 'showSearchForm':
|
487 |
|
case 'showPageTools':
|
488 |
|
case 'showEditBtn':
|
489 |
|
case 'showAddNewPage':
|
490 |
|
|
491 |
|
return $value !== 'never' && ($value == 'always' || !empty($_SERVER['REMOTE_USER']));
|
492 |
|
|
493 |
|
case 'showAdminMenu':
|
494 |
|
|
495 |
|
return $value && ($INFO['isadmin'] || $INFO['ismanager']);
|
496 |
|
|
497 |
|
case 'hideLoginLink':
|
498 |
|
case 'showLoginOnFooter':
|
499 |
|
|
500 |
|
return ($value && !isset($_SERVER['REMOTE_USER']));
|
501 |
|
|
502 |
|
case 'showCookieLawBanner':
|
503 |
|
|
504 |
|
return $value && page_findnearest(tpl_getConf('cookieLawBannerPage'), $this->getConf('useACL')) && ($ACT == 'show');
|
505 |
|
|
506 |
|
case 'showSidebar':
|
507 |
|
|
508 |
|
if ($ACT !== 'show') {
|
509 |
|
return false;
|
510 |
|
}
|
511 |
|
|
512 |
|
if ($this->getConf('showLandingPage')) {
|
513 |
|
return false;
|
514 |
|
}
|
515 |
|
|
516 |
|
return page_findnearest($conf['sidebar'], $this->getConf('useACL'));
|
517 |
|
|
518 |
|
case 'showRightSidebar':
|
519 |
|
|
520 |
|
if ($ACT !== 'show') {
|
521 |
|
return false;
|
522 |
|
}
|
523 |
|
|
524 |
|
if ($this->getConf('sidebarPosition') == 'right') {
|
525 |
|
return false;
|
526 |
|
}
|
527 |
|
|
528 |
|
return page_findnearest(tpl_getConf('rightSidebar'), $this->getConf('useACL'));
|
529 |
|
|
530 |
|
case 'showLandingPage':
|
531 |
|
|
532 |
|
return ($value && (bool) preg_match_all($this->getConf('landingPages'), $ID));
|
533 |
|
|
534 |
|
case 'pageOnPanel':
|
535 |
|
|
536 |
|
if ($this->getConf('showLandingPage')) {
|
537 |
|
return false;
|
538 |
|
}
|
539 |
|
|
540 |
|
return $value;
|
541 |
|
|
542 |
|
case 'showThemeSwitcher':
|
543 |
|
|
544 |
|
return $value && ($this->getConf('bootstrapTheme') == 'bootswatch');
|
545 |
|
|
546 |
|
case 'tocCollapseSubSections':
|
547 |
|
|
548 |
|
if (!$this->getConf('tocAffix')) {
|
549 |
|
return false;
|
550 |
|
}
|
551 |
|
|
552 |
|
return $value;
|
553 |
|
|
554 |
|
case 'schemaOrgType':
|
555 |
|
|
556 |
|
if ($semantic = plugin_load('helper', 'semantic')) {
|
557 |
|
if (method_exists($semantic, 'getSchemaOrgType')) {
|
558 |
|
return $semantic->getSchemaOrgType();
|
559 |
|
}
|
560 |
|
}
|
561 |
|
|
562 |
|
return $value;
|
563 |
|
|
564 |
|
case 'tocCollapseOnScroll':
|
565 |
|
|
566 |
|
if ($this->getConf('tocLayout') !== 'default') {
|
567 |
|
return false;
|
568 |
|
}
|
569 |
|
|
570 |
|
return $value;
|
571 |
|
}
|
572 |
|
|
573 |
|
$metadata = $this->getConfMetadata($key);
|
574 |
|
|
575 |
|
if (isset($metadata[0])) {
|
576 |
|
switch ($metadata[0]) {
|
577 |
|
case 'regex':
|
578 |
|
return '/' . $value . '/';
|
579 |
|
case 'multicheckbox':
|
580 |
|
return explode(',', $value);
|
581 |
|
}
|
582 |
|
}
|
583 |
|
|
584 |
|
return $value;
|
585 |
|
}
|
586 |
|
|
587 |
|
/**
|
588 |
|
* Return the Bootswatch.com theme lists defined in metadata.php
|
589 |
|
*
|
590 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
591 |
|
*
|
592 |
|
* @return array
|
593 |
|
*/
|
594 |
|
public function getBootswatchThemeList()
|
595 |
|
{
|
596 |
|
$bootswatch_themes = $this->getConfMetadata('bootswatchTheme');
|
597 |
|
return $bootswatch_themes['_choices'];
|
598 |
|
}
|
599 |
|
|
600 |
|
/**
|
601 |
|
* Get a Gravatar, Libravatar, Office365/EWS URL or local ":user" DokuWiki namespace
|
602 |
|
*
|
603 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
604 |
|
*
|
605 |
|
* @param string $username User ID
|
606 |
|
* @param string $email The email address
|
607 |
|
* @param string $size Size in pixels, defaults to 80px [ 1 - 2048 ]
|
608 |
|
* @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
|
609 |
|
* @param string $r Maximum rating (inclusive) [ g | pg | r | x ]
|
610 |
|
*
|
611 |
|
* @return string
|
612 |
|
*/
|
613 |
3
|
public function getAvatar($username, $email, $size = 80, $d = 'mm', $r = 'g')
|
614 |
|
{
|
615 |
|
global $INFO;
|
616 |
|
|
617 |
|
$avatar_url = '';
|
618 |
|
$avatar_provider = $this->getConf('useAvatar');
|
619 |
|
|
620 |
|
if (!$avatar_provider) {
|
621 |
|
return false;
|
622 |
|
}
|
623 |
|
|
624 |
|
if ($avatar_provider == 'local') {
|
625 |
|
|
626 |
|
$interwiki = getInterwiki();
|
627 |
|
$user_url = str_replace('{NAME}', $username, $interwiki['user']);
|
628 |
|
$logo_size = array();
|
629 |
|
$logo = tpl_getMediaFile(array("$user_url.png", "$user_url.jpg", 'images/avatar.png'), false, $logo_size);
|
630 |
|
|
631 |
|
return $logo;
|
632 |
|
}
|
633 |
|
|
634 |
|
if ($avatar_provider == 'activedirectory') {
|
635 |
|
$logo = "data:image/jpeg;base64," . base64_encode($INFO['userinfo']['thumbnailphoto']);
|
636 |
|
|
637 |
|
return $logo;
|
638 |
|
}
|
639 |
|
|
640 |
|
$email = strtolower(trim($email));
|
641 |
|
|
642 |
|
if ($avatar_provider == 'office365') {
|
643 |
|
$office365_url = rtrim($this->getConf('office365URL'), '/');
|
644 |
|
$avatar_url = $office365_url . '/owa/service.svc/s/GetPersonaPhoto?email=' . $email . '&size=HR' . $size . 'x' . $size;
|
645 |
|
}
|
646 |
|
|
647 |
|
if ($avatar_provider == 'gravatar' || $avatar_provider == 'libavatar') {
|
648 |
|
$gravatar_url = rtrim($this->getConf('gravatarURL'), '/') . '/';
|
649 |
|
$libavatar_url = rtrim($this->getConf('libavatarURL'), '/') . '/';
|
650 |
|
|
651 |
|
switch ($avatar_provider) {
|
652 |
|
case 'gravatar':
|
653 |
|
$avatar_url = $gravatar_url;
|
654 |
|
break;
|
655 |
|
case 'libavatar':
|
656 |
|
$avatar_url = $libavatar_url;
|
657 |
|
break;
|
658 |
|
}
|
659 |
|
|
660 |
|
$avatar_url .= md5($email);
|
661 |
|
$avatar_url .= "?s=$size&d=$d&r=$r";
|
662 |
|
}
|
663 |
|
|
664 |
|
if ($avatar_url) {
|
665 |
|
$media_link = ml("$avatar_url&.jpg", array('cache' => 'recache', 'w' => $size, 'h' => $size));
|
666 |
|
return $media_link;
|
667 |
|
}
|
668 |
|
|
669 |
|
return false;
|
670 |
|
}
|
671 |
|
|
672 |
|
/**
|
673 |
|
* Return template classes
|
674 |
|
*
|
675 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
676 |
|
* @see tpl_classes();
|
677 |
|
*
|
678 |
|
* @return string
|
679 |
|
**/
|
680 |
|
public function getClasses()
|
681 |
|
{
|
682 |
|
$page_on_panel = $this->getConf('pageOnPanel');
|
683 |
|
$bootstrap_theme = $this->getConf('bootstrapTheme');
|
684 |
|
$bootswatch_theme = $this->getBootswatchTheme();
|
685 |
|
|
686 |
|
$classes = array();
|
687 |
|
$classes[] = (($bootstrap_theme == 'bootswatch') ? $bootswatch_theme : $bootstrap_theme);
|
688 |
|
$classes[] = trim(tpl_classes());
|
689 |
|
|
690 |
|
if ($page_on_panel) {
|
691 |
|
$classes[] = 'dw-page-on-panel';
|
692 |
|
}
|
693 |
|
|
694 |
|
if (!$this->getConf('tableFullWidth')) {
|
695 |
|
$classes[] = 'dw-table-width';
|
696 |
|
}
|
697 |
|
|
698 |
|
if ($this->isFluidNavbar()) {
|
699 |
|
$classes[] = 'dw-fluid-container';
|
700 |
|
}
|
701 |
|
|
702 |
|
return implode(' ', $classes);
|
703 |
|
}
|
704 |
|
|
705 |
|
/**
|
706 |
|
* Return the current Bootswatch theme
|
707 |
|
*
|
708 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
709 |
|
*
|
710 |
|
* @return string
|
711 |
|
*/
|
712 |
|
public function getBootswatchTheme()
|
713 |
|
{
|
714 |
1
|
global $INPUT;
|
715 |
|
|
716 |
|
$bootswatch_theme = $this->getConf('bootswatchTheme');
|
717 |
|
|
718 |
|
if ($this->getConf('showThemeSwitcher')) {
|
719 |
|
if (get_doku_pref('bootswatchTheme', null) !== null && get_doku_pref('bootswatchTheme', null) !== '') {
|
720 |
|
$bootswatch_theme = get_doku_pref('bootswatchTheme', null);
|
721 |
|
}
|
722 |
|
}
|
723 |
|
return $bootswatch_theme;
|
724 |
|
}
|
725 |
|
|
726 |
|
/**
|
727 |
|
* Return only the available Bootswatch.com themes
|
728 |
|
*
|
729 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
730 |
|
*
|
731 |
|
* @return array
|
732 |
|
*/
|
733 |
|
public function getAvailableBootswatchThemes()
|
734 |
|
{
|
735 |
|
return array_diff($this->getBootswatchThemeList(), $this->getConf('hideInThemeSwitcher'));
|
736 |
|
}
|
737 |
|
|
738 |
|
/**
|
739 |
|
* Print some info about the current page
|
740 |
|
*
|
741 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
742 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
743 |
|
*
|
744 |
|
* @param bool $ret return content instead of printing it
|
745 |
|
* @return bool|string
|
746 |
|
*/
|
747 |
3
|
public function getPageInfo($ret = false)
|
748 |
|
{
|
749 |
|
global $conf;
|
750 |
|
global $lang;
|
751 |
|
global $INFO;
|
752 |
1
|
global $ID;
|
753 |
|
|
754 |
|
// return if we are not allowed to view the page
|
755 |
|
if (!auth_quickaclcheck($ID)) {
|
756 |
|
return false;
|
757 |
|
}
|
758 |
|
|
759 |
|
// prepare date and path
|
760 |
1
|
$fn = $INFO['filepath'];
|
761 |
|
|
762 |
|
if (!$conf['fullpath']) {
|
763 |
|
if ($INFO['rev']) {
|
764 |
|
$fn = str_replace(fullpath($conf['olddir']) . '/', '', $fn);
|
765 |
1
|
} else {
|
766 |
|
$fn = str_replace(fullpath($conf['datadir']) . '/', '', $fn);
|
767 |
|
}
|
768 |
|
}
|
769 |
|
|
770 |
|
$date_format = $this->getConf('pageInfoDateFormat');
|
771 |
|
$page_info = $this->getConf('pageInfo');
|
772 |
|
|
773 |
|
$fn = utf8_decodeFN($fn);
|
774 |
|
$date = (($date_format == 'dformat')
|
775 |
|
? dformat($INFO['lastmod'])
|
776 |
|
: datetime_h($INFO['lastmod']));
|
777 |
|
|
778 |
|
// print it
|
779 |
|
if ($INFO['exists']) {
|
780 |
|
$fn_full = $fn;
|
781 |
|
|
782 |
|
if (!in_array('extension', $page_info)) {
|
783 |
|
$fn = str_replace(array('.txt.gz', '.txt'), '', $fn);
|
784 |
|
}
|
785 |
|
|
786 |
|
$out = '<ul class="list-inline">';
|
787 |
|
|
788 |
|
if (in_array('filename', $page_info)) {
|
789 |
|
$out .= '<li>' . iconify('mdi:file-document-outline', array('class' => 'text-muted')) . ' <span title="' . $fn_full . '">' . $fn . '</span></li>';
|
790 |
|
}
|
791 |
|
|
792 |
|
if (in_array('date', $page_info)) {
|
793 |
|
$out .= '<li>' . iconify('mdi:calendar', array('class' => 'text-muted')) . ' ' . $lang['lastmod'] . ' <span title="' . dformat($INFO['lastmod']) . '">' . $date . '</span></li>';
|
794 |
|
}
|
795 |
|
|
796 |
|
if (in_array('editor', $page_info)) {
|
797 |
|
if (isset($INFO['editor'])) {
|
798 |
|
$user = editorinfo($INFO['editor']);
|
799 |
|
|
800 |
|
if ($this->getConf('useAvatar')) {
|
801 |
|
global $auth;
|
802 |
|
$user_data = $auth->getUserData($INFO['editor']);
|
803 |
|
|
804 |
|
$avatar_img = $this->getAvatar($INFO['editor'], $user_data['mail'], 16);
|
805 |
|
$user_img = '<img src="' . $avatar_img . '" alt="" width="16" height="16" class="img-rounded" /> ';
|
806 |
|
$user = str_replace(array('iw_user', 'interwiki'), '', $user);
|
807 |
|
$user = $user_img . "<bdi>$user<bdi>";
|
808 |
|
}
|
809 |
|
|
810 |
|
$out .= '<li class="text-muted">' . $lang['by'] . ' <bdi>' . $user . '</bdi></li>';
|
811 |
1
|
} else {
|
812 |
|
$out .= '<li>(' . $lang['external_edit'] . ')</li>';
|
813 |
|
}
|
814 |
|
}
|
815 |
|
|
816 |
|
if ($INFO['locked'] && in_array('locked', $page_info)) {
|
817 |
|
$out .= '<li>' . iconify('mdi:lock', array('class' => 'text-muted')) . ' ' . $lang['lockedby'] . ' ' . editorinfo($INFO['locked']) . '</li>';
|
818 |
|
}
|
819 |
|
|
820 |
|
$out .= '</ul>';
|
821 |
|
|
822 |
|
if ($ret) {
|
823 |
|
return $out;
|
824 |
1
|
} else {
|
825 |
|
echo $out;
|
826 |
|
return true;
|
827 |
|
}
|
828 |
|
}
|
829 |
|
|
830 |
|
return false;
|
831 |
|
}
|
832 |
|
|
833 |
|
/**
|
834 |
|
* Prints the global message array in Bootstrap style
|
835 |
|
*
|
836 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
837 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
838 |
|
*
|
839 |
|
* @see html_msgarea()
|
840 |
|
*/
|
841 |
3
|
public function getMessageArea()
|
842 |
|
{
|
843 |
|
|
844 |
|
global $MSG, $MSG_shown;
|
845 |
|
|
846 |
|
/** @var array $MSG */
|
847 |
|
// store if the global $MSG has already been shown and thus HTML output has been started
|
848 |
|
$MSG_shown = true;
|
849 |
|
|
850 |
|
// Check if translation is outdate
|
851 |
|
if ($this->getConf('showTranslation') && $translation = $this->getPlugin('translation')) {
|
852 |
1
|
global $ID;
|
853 |
|
|
854 |
|
if ($translation->istranslatable($ID)) {
|
855 |
|
$translation->checkage();
|
856 |
|
}
|
857 |
|
}
|
858 |
|
|
859 |
|
if (!isset($MSG)) {
|
860 |
|
return;
|
861 |
|
}
|
862 |
|
|
863 |
|
$shown = array();
|
864 |
|
|
865 |
|
foreach ($MSG as $msg) {
|
866 |
|
$hash = md5($msg['msg']);
|
867 |
|
if (isset($shown[$hash])) {
|
868 |
|
continue;
|
869 |
|
}
|
870 |
|
// skip double messages
|
871 |
|
|
872 |
|
if (info_msg_allowed($msg)) {
|
873 |
|
switch ($msg['lvl']) {
|
874 |
|
case 'info':
|
875 |
|
$level = 'info';
|
876 |
|
$icon = 'mdi:information';
|
877 |
|
break;
|
878 |
|
|
879 |
|
case 'error':
|
880 |
|
$level = 'danger';
|
881 |
|
$icon = 'mdi:alert-octagon';
|
882 |
|
break;
|
883 |
|
|
884 |
|
case 'notify':
|
885 |
|
$level = 'warning';
|
886 |
|
$icon = 'mdi:alert';
|
887 |
|
break;
|
888 |
|
|
889 |
|
case 'success':
|
890 |
|
$level = 'success';
|
891 |
|
$icon = 'mdi:check-circle';
|
892 |
|
break;
|
893 |
|
}
|
894 |
|
|
895 |
|
print '<div class="alert alert-' . $level . '">';
|
896 |
|
print iconify($icon, array('class' => 'mr-2'));
|
897 |
|
print $msg['msg'];
|
898 |
|
print '</div>';
|
899 |
|
}
|
900 |
|
|
901 |
|
$shown[$hash] = 1;
|
902 |
|
}
|
903 |
|
|
904 |
|
unset($GLOBALS['MSG']);
|
905 |
|
}
|
906 |
|
|
907 |
|
/**
|
908 |
|
* Get the license (link or image)
|
909 |
|
*
|
910 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
911 |
|
*
|
912 |
|
* @param string $type ("link" or "image")
|
913 |
|
* @param integer $size of image
|
914 |
|
* @param bool $return or print
|
915 |
|
* @return string
|
916 |
|
*/
|
917 |
1
|
public function getLicense($type = 'link', $size = 24, $return = false)
|
918 |
|
{
|
919 |
|
|
920 |
|
global $conf, $license, $lang;
|
921 |
|
|
922 |
|
$target = $conf['target']['extern'];
|
923 |
|
$lic = $license[$conf['license']];
|
924 |
|
$output = '';
|
925 |
|
|
926 |
|
if (!$lic) {
|
927 |
|
return '';
|
928 |
|
}
|
929 |
|
|
930 |
|
if ($type == 'link') {
|
931 |
|
$output .= $lang['license'] . '<br/>';
|
932 |
|
}
|
933 |
|
|
934 |
|
$license_url = $lic['url'];
|
935 |
|
$license_name = $lic['name'];
|
936 |
|
|
937 |
|
$output .= '<a href="' . $license_url . '" title="' . $license_name . '" target="' . $target . '" itemscope itemtype="http://schema.org/CreativeWork" itemprop="license" rel="license" class="license">';
|
938 |
|
|
939 |
|
if ($type == 'image') {
|
940 |
|
foreach (explode('-', $conf['license']) as $license_img) {
|
941 |
|
if ($license_img == 'publicdomain') {
|
942 |
|
$license_img = 'pd';
|
943 |
|
}
|
944 |
|
|
945 |
|
$output .= '<img src="' . tpl_basedir() . "images/license/$license_img.png" . '" width="' . $size . '" height="' . $size . '" alt="' . $license_img . '" /> ';
|
946 |
|
}
|
947 |
1
|
} else {
|
948 |
|
$output .= $lic['name'];
|
949 |
|
}
|
950 |
|
|
951 |
|
$output .= '</a>';
|
952 |
|
|
953 |
|
if ($return) {
|
954 |
|
return $output;
|
955 |
|
}
|
956 |
|
|
957 |
|
echo $output;
|
958 |
|
return '';
|
959 |
|
}
|
960 |
|
|
961 |
|
/**
|
962 |
|
* Add Google Analytics
|
963 |
|
*
|
964 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
965 |
|
*
|
966 |
|
* @return string
|
967 |
|
*/
|
968 |
4
|
public function getGoogleAnalitycs()
|
969 |
|
{
|
970 |
|
global $INFO;
|
971 |
1
|
global $ID;
|
972 |
|
|
973 |
|
if (!$this->getConf('useGoogleAnalytics')) {
|
974 |
|
return false;
|
975 |
|
}
|
976 |
|
|
977 |
|
if (!$google_analitycs_id = $this->getConf('googleAnalyticsTrackID')) {
|
978 |
|
return false;
|
979 |
|
}
|
980 |
|
|
981 |
|
if ($this->getConf('googleAnalyticsNoTrackAdmin') && $INFO['isadmin']) {
|
982 |
|
return false;
|
983 |
|
}
|
984 |
|
|
985 |
|
if ($this->getConf('googleAnalyticsNoTrackUsers') && isset($_SERVER['REMOTE_USER'])) {
|
986 |
|
return false;
|
987 |
|
}
|
988 |
|
|
989 |
|
if (tpl_getConf('googleAnalyticsNoTrackPages')) {
|
990 |
|
if (preg_match_all($this->getConf('googleAnalyticsNoTrackPages'), $ID)) {
|
991 |
|
return false;
|
992 |
|
}
|
993 |
|
}
|
994 |
|
|
995 |
|
$out = DOKU_LF;
|
996 |
|
$out .= '// Google Analytics' . DOKU_LF;
|
997 |
|
$out .= "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
998 |
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
999 |
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
1000 |
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');" . DOKU_LF;
|
1001 |
|
|
1002 |
|
$out .= 'ga("create", "' . $google_analitycs_id . '", "auto");' . DOKU_LF;
|
1003 |
|
$out .= 'ga("send", "pageview");' . DOKU_LF;
|
1004 |
|
|
1005 |
|
if ($this->getConf('googleAnalyticsAnonymizeIP')) {
|
1006 |
|
$out .= 'ga("set", "anonymizeIp", true);' . DOKU_LF;
|
1007 |
|
}
|
1008 |
|
|
1009 |
|
if ($this->getConf('googleAnalyticsTrackActions')) {
|
1010 |
|
$out .= 'ga("send", "event", "DokuWiki", JSINFO.bootstrap3.mode);' . DOKU_LF;
|
1011 |
|
}
|
1012 |
|
|
1013 |
|
$out .= '// End Google Analytics' . DOKU_LF;
|
1014 |
|
|
1015 |
|
return $out;
|
1016 |
|
}
|
1017 |
|
|
1018 |
|
/**
|
1019 |
|
* Return the user home-page link
|
1020 |
|
*
|
1021 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1022 |
|
*
|
1023 |
|
* @return string
|
1024 |
|
*/
|
1025 |
|
public function getUserHomePageLink()
|
1026 |
|
{
|
1027 |
|
return wl($this->getUserHomePageID());
|
1028 |
|
}
|
1029 |
|
|
1030 |
|
/**
|
1031 |
|
* Return the user home-page ID
|
1032 |
|
*
|
1033 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1034 |
|
*
|
1035 |
|
* @return string
|
1036 |
|
*/
|
1037 |
1
|
public function getUserHomePageID()
|
1038 |
|
{
|
1039 |
|
$interwiki = getInterwiki();
|
1040 |
|
$page_id = str_replace('{NAME}', $_SERVER['REMOTE_USER'], $interwiki['user']);
|
1041 |
|
|
1042 |
|
return cleanID($page_id);
|
1043 |
|
}
|
1044 |
|
|
1045 |
|
/**
|
1046 |
|
* Print the breadcrumbs trace with Bootstrap style
|
1047 |
|
*
|
1048 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
1049 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1050 |
|
*
|
1051 |
|
* @return bool
|
1052 |
|
*/
|
1053 |
1
|
public function getBreadcrumbs()
|
1054 |
|
{
|
1055 |
|
global $lang;
|
1056 |
|
global $conf;
|
1057 |
|
|
1058 |
|
//check if enabled
|
1059 |
|
if (!$conf['breadcrumbs']) {
|
1060 |
|
return false;
|
1061 |
|
}
|
1062 |
|
|
1063 |
|
$crumbs = breadcrumbs(); //setup crumb trace
|
1064 |
|
|
1065 |
|
//render crumbs, highlight the last one
|
1066 |
|
print '<ol class="breadcrumb">';
|
1067 |
|
print '<li>' . rtrim($lang['breadcrumb'], ':') . '</li>';
|
1068 |
|
|
1069 |
|
$last = count($crumbs);
|
1070 |
1
|
$i = 0;
|
1071 |
|
|
1072 |
|
foreach ($crumbs as $id => $name) {
|
1073 |
|
$i++;
|
1074 |
|
|
1075 |
|
print($i == $last) ? '<li class="active">' : '<li>';
|
1076 |
|
tpl_link(wl($id), hsc($name), 'title="' . $id . '"');
|
1077 |
|
print '</li>';
|
1078 |
|
|
1079 |
|
if ($i == $last) {
|
1080 |
|
print '</ol>';
|
1081 |
|
}
|
1082 |
|
}
|
1083 |
|
|
1084 |
|
return true;
|
1085 |
|
}
|
1086 |
|
|
1087 |
|
/**
|
1088 |
|
* Hierarchical breadcrumbs with Bootstrap style
|
1089 |
|
*
|
1090 |
|
* This code was suggested as replacement for the usual breadcrumbs.
|
1091 |
|
* It only makes sense with a deep site structure.
|
1092 |
|
*
|
1093 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
1094 |
|
* @author Nigel McNie <oracle.shinoda@gmail.com>
|
1095 |
|
* @author Sean Coates <sean@caedmon.net>
|
1096 |
|
* @author <fredrik@averpil.com>
|
1097 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1098 |
|
* @todo May behave strangely in RTL languages
|
1099 |
|
*
|
1100 |
|
* @return bool
|
1101 |
|
*/
|
1102 |
1
|
public function getYouAreHere()
|
1103 |
|
{
|
1104 |
|
global $conf;
|
1105 |
1
|
global $ID;
|
1106 |
|
global $lang;
|
1107 |
|
|
1108 |
|
// check if enabled
|
1109 |
|
if (!$conf['youarehere']) {
|
1110 |
|
return false;
|
1111 |
|
}
|
1112 |
|
|
1113 |
|
$parts = explode(':', $ID);
|
1114 |
|
$count = count($parts);
|
1115 |
|
|
1116 |
|
echo '<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">';
|
1117 |
|
echo '<li>' . rtrim($lang['youarehere'], ':') . '</li>';
|
1118 |
|
|
1119 |
|
// always print the startpage
|
1120 |
|
echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">';
|
1121 |
|
|
1122 |
|
tpl_link(wl($conf['start']),
|
1123 |
|
'<span itemprop="name">' . iconify('mdi:home') . '<span class="sr-only">Home</span></span>',
|
1124 |
|
' itemprop="item" title="' . $conf['start'] . '"'
|
1125 |
|
);
|
1126 |
|
|
1127 |
|
echo '<meta itemprop="position" content="1" />';
|
1128 |
|
echo '</li>';
|
1129 |
|
|
1130 |
|
$position = 1;
|
1131 |
|
|
1132 |
|
// print intermediate namespace links
|
1133 |
|
$part = '';
|
1134 |
|
|
1135 |
|
for ($i = 0; $i < $count - 1; $i++) {
|
1136 |
|
$part .= $parts[$i] . ':';
|
1137 |
|
$page = $part;
|
1138 |
|
|
1139 |
|
if ($page == $conf['start']) {
|
1140 |
|
continue;
|
1141 |
|
}
|
1142 |
|
// Skip startpage
|
1143 |
|
|
1144 |
|
$position++;
|
1145 |
|
|
1146 |
|
// output
|
1147 |
|
echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">';
|
1148 |
|
|
1149 |
|
$link = html_wikilink($page);
|
1150 |
|
$link = str_replace(array('<span class="curid">', '</span>'), '', $link);
|
1151 |
|
$link = str_replace('<a', '<a itemprop="item" ', $link);
|
1152 |
|
$link = preg_replace('/data-wiki-id="(.+?)"/', '', $link);
|
1153 |
|
$link = str_replace('<a', '<span itemprop="name"><a', $link);
|
1154 |
|
$link = str_replace('</a>', '</a></span>', $link);
|
1155 |
|
|
1156 |
|
echo $link;
|
1157 |
|
echo '<meta itemprop="position" content="' . $position . '" />';
|
1158 |
|
echo '</li>';
|
1159 |
|
}
|
1160 |
|
|
1161 |
|
// print current page, skipping start page, skipping for namespace index
|
1162 |
|
$exists = false;
|
1163 |
|
resolve_pageid('', $page, $exists);
|
1164 |
|
|
1165 |
|
if (isset($page) && $page == $part . $parts[$i]) {
|
1166 |
|
echo '</ol>';
|
1167 |
|
return true;
|
1168 |
|
}
|
1169 |
|
|
1170 |
|
$page = $part . $parts[$i];
|
1171 |
|
|
1172 |
|
if ($page == $conf['start']) {
|
1173 |
|
echo '</ol>';
|
1174 |
|
return true;
|
1175 |
|
}
|
1176 |
|
|
1177 |
|
echo '<li class="active" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">';
|
1178 |
|
|
1179 |
|
$link = str_replace(array('<span class="curid">', '</span>'), '', html_wikilink($page));
|
1180 |
|
$link = str_replace('<a ', '<a itemprop="item" ', $link);
|
1181 |
|
$link = str_replace('<a', '<span itemprop="name"><a', $link);
|
1182 |
|
$link = str_replace('</a>', '</a></span>', $link);
|
1183 |
|
$link = preg_replace('/data-wiki-id="(.+?)"/', '', $link);
|
1184 |
|
|
1185 |
|
echo $link;
|
1186 |
|
echo '<meta itemprop="position" content="' . ++$position . '" />';
|
1187 |
|
echo '</li>';
|
1188 |
|
echo '</ol>';
|
1189 |
|
|
1190 |
|
return true;
|
1191 |
|
}
|
1192 |
|
|
1193 |
|
/**
|
1194 |
|
* Display the page title (and previous namespace page title) on browser titlebar
|
1195 |
|
*
|
1196 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1197 |
|
* @return string
|
1198 |
|
*/
|
1199 |
1
|
public function getBrowserPageTitle()
|
1200 |
|
{
|
1201 |
1
|
global $conf, $ACT, $ID;
|
1202 |
|
|
1203 |
|
if ($this->getConf('browserTitleShowNS') && $ACT == 'show') {
|
1204 |
|
$ns_page = '';
|
1205 |
|
$ns_parts = explode(':', $ID);
|
1206 |
|
$ns_pages = array();
|
1207 |
|
$ns_titles = array();
|
1208 |
|
$ns_separator = sprintf(' %s ', $this->getConf('browserTitleCharSepNS'));
|
1209 |
|
|
1210 |
|
if (useHeading('navigation')) {
|
1211 |
|
if (count($ns_parts) > 1) {
|
1212 |
|
foreach ($ns_parts as $ns_part) {
|
1213 |
|
$ns_page .= "$ns_part:";
|
1214 |
|
$ns_pages[] = $ns_page;
|
1215 |
|
}
|
1216 |
|
|
1217 |
|
$ns_pages = array_unique($ns_pages);
|
1218 |
|
|
1219 |
|
foreach ($ns_pages as $ns_page) {
|
1220 |
|
$exists = false;
|
1221 |
|
resolve_pageid(getNS($ns_page), $ns_page, $exists);
|
1222 |
|
|
1223 |
1
|
$ns_page_title_heading = hsc(p_get_first_heading($ns_page));
|
1224 |
1
|
$ns_page_title_page = noNSorNS($ns_page);
|
1225 |
|
$ns_page_title = ($exists) ? $ns_page_title_heading : null;
|
1226 |
|
|
1227 |
|
if ($ns_page_title !== $conf['start']) {
|
1228 |
|
$ns_titles[] = $ns_page_title;
|
1229 |
|
}
|
1230 |
|
}
|
1231 |
|
}
|
1232 |
|
|
1233 |
|
resolve_pageid(getNS($ID), $ID, $exists);
|
1234 |
|
|
1235 |
|
if ($exists) {
|
1236 |
|
$ns_titles[] = tpl_pagetitle($ID, true);
|
1237 |
1
|
} else {
|
1238 |
|
$ns_titles[] = noNS($ID);
|
1239 |
|
}
|
1240 |
|
|
1241 |
|
$ns_titles = array_filter(array_unique($ns_titles));
|
1242 |
1
|
} else {
|
1243 |
|
$ns_titles = $ns_parts;
|
1244 |
|
}
|
1245 |
|
|
1246 |
|
if ($this->getConf('browserTitleOrderNS') == 'normal') {
|
1247 |
|
$ns_titles = array_reverse($ns_titles);
|
1248 |
|
}
|
1249 |
|
|
1250 |
|
$browser_title = implode($ns_separator, $ns_titles);
|
1251 |
1
|
} else {
|
1252 |
|
$browser_title = tpl_pagetitle($ID, true);
|
1253 |
|
}
|
1254 |
|
|
1255 |
|
return str_replace(
|
1256 |
|
array('@WIKI@', '@TITLE@'),
|
1257 |
|
array(strip_tags($conf['title']), $browser_title),
|
1258 |
|
$this->getConf('browserTitle')
|
1259 |
|
);
|
1260 |
|
}
|
1261 |
|
|
1262 |
|
/**
|
1263 |
|
* Return the theme for current namespace
|
1264 |
|
*
|
1265 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1266 |
|
* @return string
|
1267 |
|
*/
|
1268 |
|
public function getThemeForNamespace()
|
1269 |
|
{
|
1270 |
|
global $ID;
|
1271 |
|
|
1272 |
|
$themes_filename = DOKU_CONF . 'bootstrap3.themes.conf';
|
1273 |
|
|
1274 |
|
if (!$this->getConf('themeByNamespace')) {
|
1275 |
|
return array();
|
1276 |
|
}
|
1277 |
|
|
1278 |
|
if (!file_exists($themes_filename)) {
|
1279 |
|
return array();
|
1280 |
|
}
|
1281 |
|
|
1282 |
|
$config = confToHash($themes_filename);
|
1283 |
|
krsort($config);
|
1284 |
|
|
1285 |
|
foreach ($config as $page => $theme) {
|
1286 |
|
if (preg_match("/^$page/", "$ID")) {
|
1287 |
|
list($bootstrap, $bootswatch) = explode('/', $theme);
|
1288 |
|
|
1289 |
|
if ($bootstrap && in_array($bootstrap, array('default', 'optional', 'custom'))) {
|
1290 |
|
return array($bootstrap, $bootswatch);
|
1291 |
|
}
|
1292 |
|
|
1293 |
|
if ($bootstrap == 'bootswatch' && in_array($bootswatch, $this->getBootswatchThemeList())) {
|
1294 |
|
return array($bootstrap, $bootswatch);
|
1295 |
|
}
|
1296 |
|
}
|
1297 |
|
}
|
1298 |
|
|
1299 |
|
return array();
|
1300 |
|
}
|
1301 |
|
|
1302 |
|
/**
|
1303 |
|
* Make a Bootstrap3 Nav
|
1304 |
|
*
|
1305 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1306 |
|
*
|
1307 |
|
* @param string $html
|
1308 |
|
* @param string $type (= pills, tabs, navbar)
|
1309 |
|
* @param boolean $staked
|
1310 |
|
* @param string $optional_class
|
1311 |
|
* @return string
|
1312 |
|
*/
|
1313 |
2
|
public function toBootstrapNav($html, $type = '', $stacked = false, $optional_class = '')
|
1314 |
|
{
|
1315 |
|
$classes = array();
|
1316 |
|
|
1317 |
|
$classes[] = 'nav';
|
1318 |
|
$classes[] = $optional_class;
|
1319 |
|
|
1320 |
|
switch ($type) {
|
1321 |
|
case 'navbar':
|
1322 |
|
case 'navbar-nav':
|
1323 |
|
$classes[] = 'navbar-nav';
|
1324 |
|
break;
|
1325 |
|
case 'pills':
|
1326 |
|
case 'tabs':
|
1327 |
|
$classes[] = "nav-$type";
|
1328 |
|
break;
|
1329 |
|
}
|
1330 |
|
|
1331 |
|
if ($stacked) {
|
1332 |
|
$classes[] = 'nav-stacked';
|
1333 |
|
}
|
1334 |
|
|
1335 |
|
$class = implode(' ', $classes);
|
1336 |
|
|
1337 |
|
$output = str_replace(
|
1338 |
|
array('<ul class="', '<ul>'),
|
1339 |
|
array("<ul class=\"$class ", "<ul class=\"$class\">"),
|
1340 |
|
$html
|
1341 |
|
);
|
1342 |
|
|
1343 |
|
$output = $this->normalizeList($output);
|
1344 |
|
|
1345 |
|
return $output;
|
1346 |
|
}
|
1347 |
|
|
1348 |
|
/**
|
1349 |
|
* Normalize the DokuWiki list items
|
1350 |
|
*
|
1351 |
|
* @todo use Simple DOM HTML library
|
1352 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1353 |
|
* @todo use Simple DOM HTML
|
1354 |
|
* @todo FIX SimpleNavi curid
|
1355 |
|
*
|
1356 |
|
* @param string $html
|
1357 |
|
* @return string
|
1358 |
|
*/
|
1359 |
|
public function normalizeList($list)
|
1360 |
|
{
|
1361 |
|
|
1362 |
1
|
global $ID;
|
1363 |
|
|
1364 |
|
$list = preg_replace_callback('/data-wiki-id="(.+?)"/', array($this, '_replaceWikiCurrentIdCallback'), $list);
|
1365 |
|
|
1366 |
|
$html = new \simple_html_dom;
|
1367 |
|
$html->load($list, true, false);
|
1368 |
|
|
1369 |
|
# Create data-curid HTML5 attribute and unwrap span.curid for pre-Hogfather release
|
1370 |
|
foreach ($html->find('span.curid') as $elm) {
|
1371 |
|
$elm->firstChild()->setAttribute('data-wiki-curid', 'true');
|
1372 |
|
$elm->outertext = str_replace(array('<span class="curid">', '</span>'), '', $elm->outertext);
|
1373 |
|
}
|
1374 |
|
|
1375 |
|
# Unwrap div.li element
|
1376 |
|
foreach ($html->find('div.li') as $elm) {
|
1377 |
|
$elm->outertext = str_replace(array('<div class="li">', '</div>'), '', $elm->outertext);
|
1378 |
|
}
|
1379 |
|
|
1380 |
|
$list = $html->save();
|
1381 |
|
$html->clear();
|
1382 |
|
unset($html);
|
1383 |
|
|
1384 |
|
$html = new \simple_html_dom;
|
1385 |
|
$html->load($list, true, false);
|
1386 |
|
|
1387 |
|
foreach ($html->find('li') as $elm) {
|
1388 |
|
if ($elm->find('a[data-wiki-curid]')) {
|
1389 |
|
$elm->class .= ' active';
|
1390 |
|
}
|
1391 |
|
}
|
1392 |
|
|
1393 |
|
$list = $html->save();
|
1394 |
|
$html->clear();
|
1395 |
|
unset($html);
|
1396 |
|
|
1397 |
|
# TODO optimize
|
1398 |
|
$list = preg_replace('/<i (.+?)><\/i> <a (.+?)>(.+?)<\/a>/', '<a $2><i $1></i> $3</a>', $list);
|
1399 |
|
$list = preg_replace('/<span (.+?)><\/span> <a (.+?)>(.+?)<\/a>/', '<a $2><span $1></span> $3</a>', $list);
|
1400 |
|
|
1401 |
|
return $list;
|
1402 |
|
}
|
1403 |
|
|
1404 |
|
/**
|
1405 |
|
* Remove data-wiki-id HTML5 attribute
|
1406 |
|
*
|
1407 |
|
* @todo Remove this in future
|
1408 |
|
* @since Hogfather
|
1409 |
|
*
|
1410 |
|
* @param array $matches
|
1411 |
|
*
|
1412 |
|
* @return string
|
1413 |
|
*/
|
1414 |
2
|
private function _replaceWikiCurrentIdCallback($matches)
|
1415 |
|
{
|
1416 |
|
|
1417 |
|
global $ID;
|
1418 |
|
|
1419 |
|
if ($ID == $matches[1]) {
|
1420 |
|
return 'data-wiki-curid="true"';
|
1421 |
|
}
|
1422 |
|
|
1423 |
|
return '';
|
1424 |
|
|
1425 |
|
}
|
1426 |
|
|
1427 |
|
/**
|
1428 |
|
* Return a Bootstrap NavBar and or drop-down menu
|
1429 |
|
*
|
1430 |
|
* @todo use Simple DOM HTML library
|
1431 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1432 |
|
*
|
1433 |
|
* @return string
|
1434 |
|
*/
|
1435 |
1
|
public function getNavbar()
|
1436 |
|
{
|
1437 |
|
if ($this->getConf('showNavbar') === 'logged' && !$_SERVER['REMOTE_USER']) {
|
1438 |
|
return false;
|
1439 |
|
}
|
1440 |
|
|
1441 |
1
|
global $ID;
|
1442 |
|
global $conf;
|
1443 |
|
|
1444 |
|
$navbar = $this->toBootstrapNav(tpl_include_page('navbar', 0, 1, $this->getConf('useACL')), 'navbar');
|
1445 |
|
|
1446 |
|
$navbar = str_replace('urlextern', '', $navbar);
|
1447 |
|
|
1448 |
|
$navbar = preg_replace('/<li class="level([0-9]) node"> (.*)/',
|
1449 |
|
'<li class="level$1 node dropdown"><a href="#" class="dropdown-toggle" data-target="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">$2 <span class="caret"></span></a>', $navbar);
|
1450 |
|
|
1451 |
|
$navbar = preg_replace('/<li class="level([0-9]) node active"> (.*)/',
|
1452 |
|
'<li class="level$1 node active dropdown"><a href="#" class="dropdown-toggle" data-target="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">$2 <span class="caret"></span></a>', $navbar);
|
1453 |
|
|
1454 |
|
# FIX for Purplenumbers renderer plugin
|
1455 |
|
# TODO use Simple DOM HTML or improve the regex!
|
1456 |
|
if ($conf['renderer_xhtml'] == 'purplenumbers') {
|
1457 |
|
$navbar = preg_replace('/<li class="level1"> (.*)/',
|
1458 |
|
'<li class="level1 dropdown"><a href="#" class="dropdown-toggle" data-target="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">$1 <span class="caret"></span></a>', $navbar);
|
1459 |
|
}
|
1460 |
|
|
1461 |
|
$navbar = preg_replace('/<ul class="(.*)">\n<li class="level2(.*)">/',
|
1462 |
|
'<ul class="dropdown-menu" role="menu">' . PHP_EOL . '<li class="level2$2">', $navbar);
|
1463 |
|
|
1464 |
|
return $navbar;
|
1465 |
|
}
|
1466 |
|
|
1467 |
|
/**
|
1468 |
|
* Manipulate Sidebar page to add Bootstrap3 styling
|
1469 |
|
*
|
1470 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1471 |
|
*
|
1472 |
|
* @param string $sidebar
|
1473 |
|
* @param boolean $return
|
1474 |
|
* @return string
|
1475 |
|
*/
|
1476 |
1
|
public function normalizeSidebar($sidebar, $return = false)
|
1477 |
|
{
|
1478 |
|
$out = $this->toBootstrapNav($sidebar, 'pills', true);
|
1479 |
|
$out = $this->normalizeContent($out);
|
1480 |
|
|
1481 |
|
$html = new \simple_html_dom;
|
1482 |
|
$html->load($out, true, false);
|
1483 |
|
|
1484 |
|
# TODO 'page-header' will be removed in the next release of Bootstrap
|
1485 |
|
foreach ($html->find('h1, h2, h3, h4, h5, h6') as $elm) {
|
1486 |
|
|
1487 |
|
# Skip panel title on sidebar
|
1488 |
|
if (preg_match('/panel-title/', $elm->class)) {
|
1489 |
|
continue;
|
1490 |
|
}
|
1491 |
|
|
1492 |
|
$elm->class .= ' page-header';
|
1493 |
|
}
|
1494 |
|
|
1495 |
|
$out = $html->save();
|
1496 |
|
$html->clear();
|
1497 |
|
unset($html);
|
1498 |
|
|
1499 |
|
if ($return) {
|
1500 |
|
return $out;
|
1501 |
|
}
|
1502 |
|
|
1503 |
|
echo $out;
|
1504 |
|
}
|
1505 |
|
|
1506 |
|
/**
|
1507 |
|
* Return a drop-down page
|
1508 |
|
*
|
1509 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1510 |
|
*
|
1511 |
|
* @param string $page name
|
1512 |
|
* @return string
|
1513 |
|
*/
|
1514 |
|
public function getDropDownPage($page)
|
1515 |
|
{
|
1516 |
|
|
1517 |
|
$page = page_findnearest($page, $this->getConf('useACL'));
|
1518 |
|
|
1519 |
|
if (!$page) {
|
1520 |
|
return;
|
1521 |
|
}
|
1522 |
|
|
1523 |
|
$output = $this->normalizeContent($this->toBootstrapNav(tpl_include_page($page, 0, 1, $this->getConf('useACL')), 'pills', true));
|
1524 |
|
$dropdown = '<ul class="nav navbar-nav dw__dropdown_page">' .
|
1525 |
|
'<li class="dropdown dropdown-large">' .
|
1526 |
|
'<a href="#" class="dropdown-toggle" data-toggle="dropdown" title="">' .
|
1527 |
|
p_get_first_heading($page) .
|
1528 |
|
' <span class="caret"></span></a>' .
|
1529 |
|
'<ul class="dropdown-menu dropdown-menu-large" role="menu">' .
|
1530 |
|
'<li><div class="container small">' .
|
1531 |
|
$output .
|
1532 |
|
'</div></li></ul></li></ul>';
|
1533 |
|
|
1534 |
|
return $dropdown;
|
1535 |
|
}
|
1536 |
|
|
1537 |
|
/**
|
1538 |
|
* Include left or right sidebar
|
1539 |
|
*
|
1540 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1541 |
|
*
|
1542 |
|
* @param string $type left or right sidebar
|
1543 |
|
* @return boolean
|
1544 |
|
*/
|
1545 |
|
public function includeSidebar($type)
|
1546 |
|
{
|
1547 |
|
global $conf;
|
1548 |
|
|
1549 |
|
$left_sidebar = $conf['sidebar'];
|
1550 |
|
$right_sidebar = $this->getConf('rightSidebar');
|
1551 |
|
$left_sidebar_grid = $this->getConf('leftSidebarGrid');
|
1552 |
|
$right_sidebar_grid = $this->getConf('rightSidebarGrid');
|
1553 |
|
|
1554 |
|
if (!$this->getConf('showSidebar')) {
|
1555 |
|
return false;
|
1556 |
|
}
|
1557 |
|
|
1558 |
|
switch ($type) {
|
1559 |
|
case 'left':
|
1560 |
|
|
1561 |
|
if ($this->getConf('sidebarPosition') == 'left') {
|
1562 |
|
$this->sidebarWrapper($left_sidebar, 'dokuwiki__aside', $left_sidebar_grid, 'sidebarheader', 'sidebarfooter');
|
1563 |
|
}
|
1564 |
|
|
1565 |
|
return true;
|
1566 |
|
|
1567 |
|
case 'right':
|
1568 |
|
|
1569 |
|
if ($this->getConf('sidebarPosition') == 'right') {
|
1570 |
|
$this->sidebarWrapper($left_sidebar, 'dokuwiki__aside', $left_sidebar_grid, 'sidebarheader', 'sidebarfooter');
|
1571 |
|
}
|
1572 |
|
|
1573 |
|
if ($this->getConf('showRightSidebar')
|
1574 |
|
&& $this->getConf('sidebarPosition') == 'left') {
|
1575 |
|
$this->sidebarWrapper($right_sidebar, 'dokuwiki__rightaside', $right_sidebar_grid, 'rightsidebarheader', 'rightsidebarfooter');
|
1576 |
|
}
|
1577 |
|
|
1578 |
|
return true;
|
1579 |
|
}
|
1580 |
|
|
1581 |
|
return false;
|
1582 |
|
}
|
1583 |
|
|
1584 |
|
/**
|
1585 |
|
* Wrapper for left or right sidebar
|
1586 |
|
*
|
1587 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1588 |
|
*
|
1589 |
|
* @param string $sidebar_page
|
1590 |
|
* @param string $sidebar_id
|
1591 |
|
* @param string $sidebar_header
|
1592 |
|
* @param string $sidebar_footer
|
1593 |
|
*/
|
1594 |
10
|
private function sidebarWrapper($sidebar_page, $sidebar_id, $sidebar_class, $sidebar_header, $sidebar_footer)
|
1595 |
|
{
|
1596 |
1
|
global $lang;
|
1597 |
1
|
global $TPL;
|
1598 |
|
|
1599 |
|
@require $this->tplDir . 'tpl/sidebar.php';
|
1600 |
|
}
|
1601 |
|
|
1602 |
|
/**
|
1603 |
|
* Add Bootstrap classes in a DokuWiki content
|
1604 |
|
*
|
1605 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
1606 |
|
*
|
1607 |
|
* @param string $content from tpl_content() or from tpl_include_page()
|
1608 |
|
* @return string with Bootstrap styles
|
1609 |
|
*/
|
1610 |
7
|
public function normalizeContent($content)
|
1611 |
|
{
|
1612 |
|
global $ACT;
|
1613 |
|
global $INPUT;
|
1614 |
|
global $INFO;
|
1615 |
|
|
1616 |
|
# FIX :-\ smile
|
1617 |
|
$content = str_replace(array('alt=":-\"', "alt=':-\'"), 'alt=":-\"', $content);
|
1618 |
|
|
1619 |
|
# Workaround for ToDo Plugin
|
1620 |
|
$content = str_replace('checked="checked"', ' checked="checked"', $content);
|
1621 |
|
|
1622 |
|
# Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB)
|
1623 |
|
if (strlen($content) > MAX_FILE_SIZE) {
|
1624 |
|
return $content;
|
1625 |
|
}
|
1626 |
|
|
1627 |
|
# Import HTML string
|
1628 |
|
$html = new \simple_html_dom;
|
1629 |
|
$html->load($content, true, false);
|
1630 |
|
|
1631 |
|
# Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB)
|
1632 |
|
if (!$html) {
|
1633 |
|
return $content;
|
1634 |
|
}
|
1635 |
|
|
1636 |
|
# Move Current Page ID to <a> element and create data-curid HTML5 attribute (pre-Hogfather release)
|
1637 |
|
foreach ($html->find('.curid') as $elm) {
|
1638 |
|
foreach ($elm->find('a') as $link) {
|
1639 |
|
$link->class .= ' curid';
|
1640 |
|
$link->attr[' data-curid'] = 'true'; # FIX attribute
|
1641 |
|
}
|
1642 |
|
}
|
1643 |
|
|
1644 |
|
# Unwrap span.curid elements
|
1645 |
|
foreach ($html->find('span.curid') as $elm) {
|
1646 |
|
$elm->outertext = str_replace(array('<span class="curid">', '</span>'), '', $elm->outertext);
|
1647 |
|
}
|
1648 |
|
|
1649 |
|
# Footnotes
|
1650 |
|
foreach ($html->find('.footnotes') as $elm) {
|
1651 |
|
$elm->outertext = '<hr/>' . $elm->outertext;
|
1652 |
|
}
|
1653 |
|
|
1654 |
|
# Accessibility (a11y)
|
1655 |
|
foreach ($html->find('.a11y') as $elm) {
|
1656 |
|
if (preg_match('/picker/', $elm->class)) {
|
1657 |
|
continue;
|
1658 |
|
}
|
1659 |
|
$elm->class .= ' sr-only';
|
1660 |
|
}
|
1661 |
|
|
1662 |
|
# Fix list overlap in media images
|
1663 |
|
foreach ($html->find('ul, ol') as $elm) {
|
1664 |
|
if (preg_match('/(nav|dropdown-menu)/', $elm->class)) {
|
1665 |
|
continue;
|
1666 |
|
}
|
1667 |
|
$elm->class .= ' fix-media-list-overlap';
|
1668 |
|
}
|
1669 |
|
|
1670 |
|
# Buttons
|
1671 |
|
foreach ($html->find('.button') as $elm) {
|
1672 |
|
if ($elm->tag == 'form') {
|
1673 |
|
continue;
|
1674 |
|
}
|
1675 |
|
$elm->class .= ' btn';
|
1676 |
|
}
|
1677 |
|
|
1678 |
|
foreach ($html->find('[type=button], [type=submit], [type=reset]') as $elm) {
|
1679 |
|
$elm->class .= ' btn btn-default';
|
1680 |
|
}
|
1681 |
|
|
1682 |
|
# Section Edit Button
|
1683 |
|
foreach ($html->find('.btn_secedit [type=submit]') as $elm) {
|
1684 |
|
$elm->class .= ' btn btn-xs btn-default';
|
1685 |
|
}
|
1686 |
|
|
1687 |
|
# Section Edit icons
|
1688 |
|
foreach ($html->find('.secedit.editbutton_section button') as $elm) {
|
1689 |
|
$elm->innertext = iconify('mdi:pencil') . ' ' . $elm->innertext;
|
1690 |
|
}
|
1691 |
|
|
1692 |
|
foreach ($html->find('.secedit.editbutton_table button') as $elm) {
|
1693 |
|
$elm->innertext = iconify('mdi:table') . ' ' . $elm->innertext;
|
1694 |
|
}
|
1695 |
|
|
1696 |
|
# Tabs
|
1697 |
|
foreach ($html->find('.tabs') as $elm) {
|
1698 |
|
$elm->class = 'nav nav-tabs';
|
1699 |
|
}
|
1700 |
|
|
1701 |
|
# Tabs (active)
|
1702 |
|
foreach ($html->find('.nav-tabs strong') as $elm) {
|
1703 |
|
$elm->outertext = '<a href="#">' . $elm->innertext . "</a>";
|
1704 |
|
$parent = $elm->parent()->class .= ' active';
|
1705 |
|
}
|
1706 |
|
|
1707 |
|
# Page Heading (h1-h2)
|
1708 |
|
# TODO this class will be removed in Bootstrap >= 4.0 version
|
1709 |
|
foreach ($html->find('h1,h2,h3') as $elm) {
|
1710 |
|
$elm->class .= ' page-header pb-3 mb-4 mt-5'; # TODO replace page-header with border-bottom in BS4
|
1711 |
|
}
|
1712 |
|
|
1713 |
|
# Media Images
|
1714 |
|
foreach ($html->find('img[class^=media]') as $elm) {
|
1715 |
|
$elm->class .= ' img-responsive';
|
1716 |
|
}
|
1717 |
|
|
1718 |
|
# Checkbox
|
1719 |
|
foreach ($html->find('input[type=checkbox]') as $elm) {
|
1720 |
|
$elm->class .= ' checkbox-inline';
|
1721 |
|
}
|
1722 |
|
|
1723 |
|
# Radio button
|
1724 |
|
foreach ($html->find('input[type=radio]') as $elm) {
|
1725 |
|
$elm->class .= ' radio-inline';
|
1726 |
|
}
|
1727 |
|
|
1728 |
|
# Label
|
1729 |
|
foreach ($html->find('label') as $elm) {
|
1730 |
|
$elm->class .= ' control-label';
|
1731 |
|
}
|
1732 |
|
|
1733 |
|
# Form controls
|
1734 |
|
foreach ($html->find('input, select, textarea') as $elm) {
|
1735 |
|
if (in_array($elm->type, array('submit', 'reset', 'button', 'hidden', 'image', 'checkbox', 'radio'))) {
|
1736 |
|
continue;
|
1737 |
|
}
|
1738 |
|
$elm->class .= ' form-control';
|
1739 |
|
}
|
1740 |
|
|
1741 |
|
# Forms
|
1742 |
|
# TODO main form
|
1743 |
|
foreach ($html->find('form') as $elm) {
|
1744 |
|
if (preg_match('/form-horizontal/', $elm->class)) {
|
1745 |
|
continue;
|
1746 |
|
}
|
1747 |
|
$elm->class .= ' form-inline';
|
1748 |
|
}
|
1749 |
|
|
1750 |
|
# Alerts
|
1751 |
|
foreach ($html->find('div.info, div.error, div.success, div.notify') as $elm) {
|
1752 |
|
switch ($elm->class) {
|
1753 |
|
case 'info':
|
1754 |
|
$elm->class = 'alert alert-info';
|
1755 |
|
$elm->innertext = iconify('mdi:information') . ' ' . $elm->innertext;
|
1756 |
|
break;
|
1757 |
|
|
1758 |
|
case 'error':
|
1759 |
|
$elm->class = 'alert alert-danger';
|
1760 |
|
$elm->innertext = iconify('mdi:alert-octagon') . ' ' . $elm->innertext;
|
1761 |
|
break;
|
1762 |
|
|
1763 |
|
case 'success':
|
1764 |
|
$elm->class = 'alert alert-success';
|
1765 |
|
$elm->innertext = iconify('mdi:check-circle') . ' ' . $elm->innertext;
|
1766 |
|
break;
|
1767 |
|
|
1768 |
|
case 'notify':
|
1769 |
|
case 'msg notify':
|
1770 |
|
$elm->class = 'alert alert-warning';
|
1771 |
|
$elm->innertext = iconify('mdi:alert') . ' ' . $elm->innertext;
|
1772 |
|
break;
|
1773 |
|
}
|
1774 |
|
}
|
1775 |
|
|
1776 |
|
# Tables
|
1777 |
|
|
1778 |
|
$table_classes = 'table';
|
1779 |
|
|
1780 |
|
foreach ($this->getConf('tableStyle') as $class) {
|
1781 |
|
if ($class == 'responsive') {
|
1782 |
|
foreach ($html->find('div.table') as $elm) {
|
1783 |
|
$elm->class = 'table-responsive';
|
1784 |
|
}
|
1785 |
1
|
} else {
|
1786 |
|
$table_classes .= " table-$class";
|
1787 |
|
}
|
1788 |
|
}
|
1789 |
|
|
1790 |
|
foreach ($html->find('table.inline,table.import_failures') as $elm) {
|
1791 |
|
$elm->class .= " $table_classes";
|
1792 |
|
}
|
1793 |
|
|
1794 |
|
foreach ($html->find('div.table') as $elm) {
|
1795 |
|
$elm->class = trim(str_replace('table', '', $elm->class));
|
1796 |
|
}
|
1797 |
|
|
1798 |
|
# Tag and Pagelist (table)
|
1799 |
|
|
1800 |
|
if ($this->getPlugin('tag') || $this->getPlugin('pagelist')) {
|
1801 |
|
foreach ($html->find('table.ul') as $elm) {
|
1802 |
|
$elm->class .= " $table_classes";
|
1803 |
|
}
|
1804 |
|
}
|
1805 |
|
|
1806 |
|
$content = $html->save();
|
1807 |
|
|
1808 |
|
$html->clear();
|
1809 |
|
unset($html);
|
1810 |
|
|
1811 |
|
# ----- Actions -----
|
1812 |
|
|
1813 |
|
# Search
|
1814 |
|
|
1815 |
|
if ($ACT == 'search') {
|
1816 |
|
# Import HTML string
|
1817 |
|
$html = new \simple_html_dom;
|
1818 |
|
$html->load($content, true, false);
|
1819 |
|
|
1820 |
|
foreach ($html->find('fieldset.search-form button[type="submit"]') as $elm) {
|
1821 |
|
$elm->class .= ' btn-primary';
|
1822 |
|
$elm->innertext = iconify('mdi:magnify', array('class' => 'mr-2')) . $elm->innertext;
|
1823 |
|
}
|
1824 |
|
|
1825 |
|
$content = $html->save();
|
1826 |
|
|
1827 |
|
$html->clear();
|
1828 |
|
unset($html);
|
1829 |
|
}
|
1830 |
|
|
1831 |
|
# Index / Sitemap
|
1832 |
|
|
1833 |
|
if ($ACT == 'index') {
|
1834 |
|
# Import HTML string
|
1835 |
|
$html = new \simple_html_dom;
|
1836 |
|
$html->load($content, true, false);
|
1837 |
|
|
1838 |
|
foreach ($html->find('.idx_dir') as $idx => $elm) {
|
1839 |
|
$parent = $elm->parent()->parent();
|
1840 |
|
|
1841 |
|
if (preg_match('/open/', $parent->class)) {
|
1842 |
|
$elm->innertext = iconify('mdi:folder-open', array('class' => 'text-primary mr-2')) . $elm->innertext;
|
1843 |
|
}
|
1844 |
|
|
1845 |
|
if (preg_match('/closed/', $parent->class)) {
|
1846 |
|
$elm->innertext = iconify('mdi:folder', array('class' => 'text-primary mr-2')) . $elm->innertext;
|
1847 |
|
}
|
1848 |
|
}
|
1849 |
|
|
1850 |
|
foreach ($html->find('.idx .wikilink1') as $elm) {
|
1851 |
|
$elm->innertext = iconify('mdi:file-document-outline', array('class' => 'text-muted mr-2')) . $elm->innertext;
|
1852 |
|
}
|
1853 |
|
|
1854 |
|
$content = $html->save();
|
1855 |
|
|
1856 |
|
$html->clear();
|
1857 |
|
unset($html);
|
1858 |
|
}
|
1859 |
|
|
1860 |
|
# Admin Pages
|
1861 |
|
|
1862 |
|
if ($ACT == 'admin') {
|
1863 |
|
# Import HTML string
|
1864 |
|
$html = new \simple_html_dom;
|
1865 |
|
$html->load($content, true, false);
|
1866 |
|
|
1867 |
|
// Set specific icon in Admin Page
|
1868 |
|
if ($INPUT->str('page')) {
|
1869 |
|
if ($admin_pagetitle = $html->find('h1.page-header', 0)) {
|
1870 |
|
$admin_pagetitle->class .= ' ' . hsc($INPUT->str('page'));
|
1871 |
|
}
|
1872 |
|
}
|
1873 |
|
|
1874 |
|
# ACL
|
1875 |
|
|
1876 |
|
if ($INPUT->str('page') == 'acl') {
|
1877 |
|
foreach ($html->find('[name*=cmd[update]]') as $elm) {
|
1878 |
|
$elm->class .= ' btn-success';
|
1879 |
|
if ($elm->tag == 'button') {
|
1880 |
|
$elm->innertext = iconify('mdi:content-save') . ' ' . $elm->innertext;
|
1881 |
|
}
|
1882 |
|
}
|
1883 |
|
}
|
1884 |
|
|
1885 |
|
# Popularity
|
1886 |
|
|
1887 |
|
if ($INPUT->str('page') == 'popularity') {
|
1888 |
|
foreach ($html->find('[type=submit]') as $elm) {
|
1889 |
|
$elm->class .= ' btn-primary';
|
1890 |
|
|
1891 |
|
if ($elm->tag == 'button') {
|
1892 |
|
$elm->innertext = iconify('mdi:arrow-right') . ' ' . $elm->innertext;
|
1893 |
|
}
|
1894 |
|
}
|
1895 |
|
}
|
1896 |
|
|
1897 |
|
# Revert Manager
|
1898 |
|
|
1899 |
|
if ($INPUT->str('page') == 'revert') {
|
1900 |
|
foreach ($html->find('[type=submit]') as $idx => $elm) {
|
1901 |
|
if ($idx == 0) {
|
1902 |
|
$elm->class .= ' btn-primary';
|
1903 |
|
if ($elm->tag == 'button') {
|
1904 |
|
$elm->innertext = iconify('mdi:magnify') . ' ' . $elm->innertext;
|
1905 |
|
}
|
1906 |
|
}
|
1907 |
|
|
1908 |
|
if ($idx == 1) {
|
1909 |
|
$elm->class .= ' btn-success';
|
1910 |
|
if ($elm->tag == 'button') {
|
1911 |
|
$elm->innertext = iconify('mdi:refresh') . ' ' . $elm->innertext;
|
1912 |
|
}
|
1913 |
|
}
|
1914 |
|
}
|
1915 |
|
}
|
1916 |
|
|
1917 |
|
# Config
|
1918 |
|
|
1919 |
|
if ($INPUT->str('page') == 'config') {
|
1920 |
|
foreach ($html->find('[type=submit]') as $elm) {
|
1921 |
|
$elm->class .= ' btn-success';
|
1922 |
|
if ($elm->tag == 'button') {
|
1923 |
|
$elm->innertext = iconify('mdi:content-save') . ' ' . $elm->innertext;
|
1924 |
|
}
|
1925 |
|
}
|
1926 |
|
|
1927 |
|
foreach ($html->find('#config__manager') as $cm_elm) {
|
1928 |
|
$save_button = '';
|
1929 |
|
|
1930 |
|
foreach ($cm_elm->find('p') as $elm) {
|
1931 |
|
$save_button = '<div class="pull-right">' . $elm->outertext . '</div>';
|
1932 |
|
$elm->outertext = '</div>' . $elm->outertext;
|
1933 |
|
}
|
1934 |
|
|
1935 |
|
foreach ($cm_elm->find('fieldset') as $elm) {
|
1936 |
|
$elm->innertext .= $save_button;
|
1937 |
|
}
|
1938 |
|
}
|
1939 |
|
}
|
1940 |
|
|
1941 |
|
# User Manager
|
1942 |
|
|
1943 |
|
if ($INPUT->str('page') == 'usermanager') {
|
1944 |
|
foreach ($html->find('.notes') as $elm) {
|
1945 |
|
$elm->class = str_replace('notes', '', $elm->class);
|
1946 |
|
}
|
1947 |
|
|
1948 |
|
foreach ($html->find('h2') as $idx => $elm) {
|
1949 |
|
switch ($idx) {
|
1950 |
|
case 0:
|
1951 |
|
$elm->innertext = iconify('mdi:account-multiple') . ' ' . $elm->innertext;
|
1952 |
|
break;
|
1953 |
|
case 1:
|
1954 |
|
$elm->innertext = iconify('mdi:account-plus') . ' ' . $elm->innertext;
|
1955 |
|
break;
|
1956 |
|
case 2:
|
1957 |
|
$elm->innertext = iconify('mdi:account-edit') . ' ' . $elm->innertext;
|
1958 |
|
break;
|
1959 |
|
}
|
1960 |
|
}
|
1961 |
|
|
1962 |
|
foreach ($html->find('.import_users h2') as $elm) {
|
1963 |
|
$elm->innertext = iconify('mdi:account-multiple-plus') . ' ' . $elm->innertext;
|
1964 |
|
}
|
1965 |
|
|
1966 |
|
foreach ($html->find('button[name*=fn[delete]]') as $elm) {
|
1967 |
|
$elm->class .= ' btn btn-danger';
|
1968 |
|
$elm->innertext = iconify('mdi:account-minus') . ' ' . $elm->innertext;
|
1969 |
|
}
|
1970 |
|
|
1971 |
|
foreach ($html->find('button[name*=fn[add]]') as $elm) {
|
1972 |
|
$elm->class .= ' btn btn-success';
|
1973 |
|
$elm->innertext = iconify('mdi:plus') . ' ' . $elm->innertext;
|
1974 |
|
}
|
1975 |
|
|
1976 |
|
foreach ($html->find('button[name*=fn[modify]]') as $elm) {
|
1977 |
|
$elm->class .= ' btn btn-success';
|
1978 |
|
$elm->innertext = iconify('mdi:content-save') . ' ' . $elm->innertext;
|
1979 |
|
}
|
1980 |
|
|
1981 |
|
foreach ($html->find('button[name*=fn[import]]') as $elm) {
|
1982 |
|
$elm->class .= ' btn btn-primary';
|
1983 |
|
$elm->innertext = iconify('mdi:upload') . ' ' . $elm->innertext;
|
1984 |
|
}
|
1985 |
|
|
1986 |
|
foreach ($html->find('button[name*=fn[export]]') as $elm) {
|
1987 |
|
$elm->class .= ' btn btn-primary';
|
1988 |
|
$elm->innertext = iconify('mdi:download') . ' ' . $elm->innertext;
|
1989 |
|
}
|
1990 |
|
|
1991 |
|
foreach ($html->find('button[name*=fn[start]]') as $elm) {
|
1992 |
|
$elm->class .= ' btn btn-default';
|
1993 |
|
$elm->innertext = iconify('mdi:chevron-double-left') . ' ' . $elm->innertext;
|
1994 |
|
}
|
1995 |
|
|
1996 |
|
foreach ($html->find('button[name*=fn[prev]]') as $elm) {
|
1997 |
|
$elm->class .= ' btn btn-default';
|
1998 |
|
$elm->innertext = iconify('mdi:chevron-left') . ' ' . $elm->innertext;
|
1999 |
|
}
|
2000 |
|
|
2001 |
|
foreach ($html->find('button[name*=fn[next]]') as $elm) {
|
2002 |
|
$elm->class .= ' btn btn-default';
|
2003 |
|
$elm->innertext = iconify('mdi:chevron-right') . ' ' . $elm->innertext;
|
2004 |
|
}
|
2005 |
|
|
2006 |
|
foreach ($html->find('button[name*=fn[last]]') as $elm) {
|
2007 |
|
$elm->class .= ' btn btn-default';
|
2008 |
|
$elm->innertext = iconify('mdi:chevron-double-right') . ' ' . $elm->innertext;
|
2009 |
|
}
|
2010 |
|
}
|
2011 |
|
|
2012 |
|
# Extension Manager
|
2013 |
|
|
2014 |
|
if ($INPUT->str('page') == 'extension') {
|
2015 |
|
foreach ($html->find('.actions') as $elm) {
|
2016 |
|
$elm->class .= ' pl-4 btn-group btn-group-xs';
|
2017 |
|
}
|
2018 |
|
|
2019 |
|
foreach ($html->find('.actions .uninstall') as $elm) {
|
2020 |
|
$elm->class .= ' btn-danger';
|
2021 |
|
$elm->innertext = iconify('mdi:delete') . ' ' . $elm->innertext;
|
2022 |
|
}
|
2023 |
|
|
2024 |
|
foreach ($html->find('.actions .enable') as $elm) {
|
2025 |
|
$elm->class .= ' btn-success';
|
2026 |
|
$elm->innertext = iconify('mdi:check') . ' ' . $elm->innertext;
|
2027 |
|
}
|
2028 |
|
|
2029 |
|
foreach ($html->find('.actions .disable') as $elm) {
|
2030 |
|
$elm->class .= ' btn-warning';
|
2031 |
|
$elm->innertext = iconify('mdi:block-helper') . ' ' . $elm->innertext;
|
2032 |
|
}
|
2033 |
|
|
2034 |
|
foreach ($html->find('.actions .install, .actions .update, .actions .reinstall') as $elm) {
|
2035 |
|
$elm->class .= ' btn-primary';
|
2036 |
|
$elm->innertext = iconify('mdi:download') . ' ' . $elm->innertext;
|
2037 |
|
}
|
2038 |
|
|
2039 |
|
foreach ($html->find('form.install [type=submit]') as $elm) {
|
2040 |
|
$elm->class .= ' btn btn-success';
|
2041 |
|
$elm->innertext = iconify('mdi:download') . ' ' . $elm->innertext;
|
2042 |
|
}
|
2043 |
|
|
2044 |
|
foreach ($html->find('form.search [type=submit]') as $elm) {
|
2045 |
|
$elm->class .= ' btn btn-primary';
|
2046 |
|
$elm->innertext = iconify('mdi:cloud-search') . ' ' . $elm->innertext;
|
2047 |
|
}
|
2048 |
|
|
2049 |
|
foreach ($html->find('.permerror') as $elm) {
|
2050 |
|
$elm->class .= ' pull-left';
|
2051 |
|
}
|
2052 |
|
}
|
2053 |
|
|
2054 |
|
# Admin page
|
2055 |
|
if ($INPUT->str('page') == null) {
|
2056 |
|
foreach ($html->find('ul.admin_tasks, ul.admin_plugins') as $admin_task) {
|
2057 |
|
$admin_task->class .= ' list-group';
|
2058 |
|
|
2059 |
|
foreach ($admin_task->find('a') as $item) {
|
2060 |
|
$item->class .= ' list-group-item';
|
2061 |
|
$item->style = 'max-height: 50px'; # TODO remove
|
2062 |
|
}
|
2063 |
|
|
2064 |
|
foreach ($admin_task->find('.icon') as $item) {
|
2065 |
|
if ($item->innertext) {
|
2066 |
|
continue;
|
2067 |
|
}
|
2068 |
|
|
2069 |
|
$item->innertext = iconify('mdi:puzzle', array('class' => 'text-success'));
|
2070 |
|
}
|
2071 |
|
}
|
2072 |
|
|
2073 |
|
foreach ($html->find('h2') as $elm) {
|
2074 |
|
$elm->innertext = iconify('mdi:puzzle', array('class' => 'text-success')) . ' ' . $elm->innertext;
|
2075 |
|
}
|
2076 |
|
|
2077 |
|
foreach ($html->find('ul.admin_plugins') as $admin_plugins) {
|
2078 |
|
$admin_plugins->class .= ' col-sm-4';
|
2079 |
|
foreach ($admin_plugins->find('li') as $idx => $item) {
|
2080 |
|
if ($idx > 0 && $idx % 5 == 0) {
|
2081 |
|
$item->outertext = '</ul><ul class="' . $admin_plugins->class . '">' . $item->outertext;
|
2082 |
|
}
|
2083 |
|
}
|
2084 |
|
}
|
2085 |
|
|
2086 |
|
# DokuWiki logo
|
2087 |
|
if ($admin_version = $html->getElementById('admin__version')) {
|
2088 |
|
$admin_version->innertext = '<div class="dokuwiki__version"><img src="' . DOKU_BASE . 'lib/tpl/dokuwiki/images/logo.png" class="p-2" alt="" width="32" height="32" /> ' . $admin_version->innertext . '</div>';
|
2089 |
|
|
2090 |
|
$template_version = $this->getVersion();
|
2091 |
|
|
2092 |
|
$admin_version->innertext .= '<div class="template__version"><img src="' . tpl_basedir() . 'images/bootstrap.png" class="p-2" height="32" width="32" alt="" />Template ' . $template_version . '</div>';
|
2093 |
|
}
|
2094 |
|
}
|
2095 |
|
|
2096 |
|
$content = $html->save();
|
2097 |
|
|
2098 |
|
$html->clear();
|
2099 |
|
unset($html);
|
2100 |
|
|
2101 |
|
# Configuration Manager Template Sections
|
2102 |
|
if ($INPUT->str('page') == 'config') {
|
2103 |
|
# Import HTML string
|
2104 |
|
$html = new \simple_html_dom;
|
2105 |
|
$html->load($content, true, false);
|
2106 |
|
|
2107 |
|
foreach ($html->find('fieldset[id^="plugin__"]') as $elm) {
|
2108 |
|
|
2109 |
|
/** @var array $matches */
|
2110 |
|
preg_match('/plugin_+(\w+[^_])_+plugin_settings_name/', $elm->id, $matches);
|
2111 |
|
|
2112 |
|
$plugin_name = $matches[1];
|
2113 |
|
|
2114 |
|
if ($extension = plugin_load('helper', 'extension_extension')) {
|
2115 |
|
if ($extension->setExtension($plugin_name)) {
|
2116 |
|
foreach ($elm->find('legend') as $legend) {
|
2117 |
|
$legend->innertext = iconify('mdi:puzzle', array('class' => 'text-success')) . ' ' . $legend->innertext . ' <br/><h6>' . $extension->getDescription() . ' <a class="urlextern" href="' . $extension->getURL() . '" target="_blank">Docs</a></h6>';
|
2118 |
|
}
|
2119 |
|
}
|
2120 |
1
|
} else {
|
ElseExpression The method normalizeContent uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them.
( kritika/PHPMD)
Filter like this
|
2121 |
|
foreach ($elm->find('legend') as $legend) {
|
2122 |
|
$legend->innertext = iconify('mdi:puzzle', array('class' => 'text-success')) . ' ' . $legend->innertext;
|
2123 |
|
}
|
2124 |
|
}
|
2125 |
|
}
|
2126 |
|
|
2127 |
|
$dokuwiki_configs = array(
|
2128 |
|
'#_basic' => 'mdi:settings',
|
2129 |
|
'#_display' => 'mdi:monitor',
|
2130 |
|
'#_authentication' => 'mdi:shield-account',
|
2131 |
|
'#_anti_spam' => 'mdi:block-helper',
|
2132 |
|
'#_editing' => 'mdi:pencil',
|
2133 |
|
'#_links' => 'mdi:link-variant',
|
2134 |
|
'#_media' => 'mdi:folder-image',
|
2135 |
|
'#_notifications' => 'mdi:email',
|
2136 |
|
'#_syndication' => 'mdi:rss',
|
2137 |
|
'#_advanced' => 'mdi:palette-advanced',
|
2138 |
|
'#_network' => 'mdi:network',
|
2139 |
|
);
|
2140 |
|
|
2141 |
|
foreach ($dokuwiki_configs as $selector => $icon) {
|
2142 |
|
foreach ($html->find("$selector legend") as $elm) {
|
2143 |
|
$elm->innertext = iconify($icon) . ' ' . $elm->innertext;
|
2144 |
|
}
|
2145 |
|
}
|
2146 |
|
|
2147 |
|
$content = $html->save();
|
2148 |
|
|
2149 |
|
$html->clear();
|
2150 |
|
unset($html);
|
2151 |
|
|
2152 |
|
$admin_sections = array(
|
2153 |
|
// Section Insert Before Icon
|
2154 |
|
'theme' => array('bootstrapTheme', 'mdi:palette'),
|
2155 |
|
'sidebar' => array('sidebarPosition', 'mdi:page-layout-sidebar-left'),
|
2156 |
|
'navbar' => array('inverseNavbar', 'mdi:page-layout-header'),
|
2157 |
|
'semantic' => array('semantic', 'mdi:share-variant'),
|
2158 |
|
'layout' => array('fluidContainer', 'mdi:monitor'),
|
2159 |
|
'toc' => array('tocAffix', 'mdi:view-list'),
|
2160 |
|
'discussion' => array('showDiscussion', 'mdi:comment-text-multiple'),
|
2161 |
|
'avatar' => array('useAvatar', 'mdi:account'),
|
2162 |
|
'cookie_law' => array('showCookieLawBanner', 'mdi:scale-balance'),
|
2163 |
|
'google_analytics' => array('useGoogleAnalytics', 'mdi:google'),
|
2164 |
|
'browser_title' => array('browserTitle', 'mdi:format-title'),
|
2165 |
|
'page' => array('showPageInfo', 'mdi:file'),
|
2166 |
|
);
|
2167 |
|
|
2168 |
|
foreach ($admin_sections as $section => $items) {
|
2169 |
|
$search = $items[0];
|
2170 |
|
$icon = $items[1];
|
2171 |
|
|
2172 |
|
$content = preg_replace(
|
2173 |
|
'/<span class="outkey">(tpl»bootstrap3»' . $search . ')<\/span>/',
|
2174 |
|
'<h3 id="bootstrap3__' . $section . '" class="mt-5">' . iconify($icon) . ' ' . tpl_getLang("config_$section") . '</h3></td><td></td></tr><tr><td class="label"><span class="outkey">$1</span>',
|
2175 |
|
$content
|
2176 |
|
);
|
2177 |
|
}
|
2178 |
|
}
|
2179 |
|
}
|
2180 |
|
|
2181 |
|
# Difference and Draft
|
2182 |
|
|
2183 |
|
if ($ACT == 'diff' || $ACT == 'draft') {
|
2184 |
|
# Import HTML string
|
2185 |
|
$html = new \simple_html_dom;
|
2186 |
|
$html->load($content, true, false);
|
2187 |
|
|
2188 |
|
foreach ($html->find('.diff-lineheader') as $elm) {
|
2189 |
|
$elm->style = 'opacity: 0.5';
|
2190 |
|
$elm->class .= ' text-center px-3';
|
2191 |
|
|
2192 |
|
if ($elm->innertext == '+') {
|
2193 |
|
$elm->class .= ' bg-success';
|
2194 |
|
}
|
2195 |
|
if ($elm->innertext == '-') {
|
2196 |
|
$elm->class .= ' bg-danger';
|
2197 |
|
}
|
2198 |
|
}
|
2199 |
|
|
2200 |
|
foreach ($html->find('.diff_sidebyside .diff-deletedline, .diff_sidebyside .diff-addedline') as $elm) {
|
2201 |
|
$elm->class .= ' w-50';
|
2202 |
|
}
|
2203 |
|
|
2204 |
|
foreach ($html->find('.diff-deletedline') as $elm) {
|
2205 |
|
$elm->class .= ' bg-danger';
|
2206 |
|
}
|
2207 |
|
|
2208 |
|
foreach ($html->find('.diff-addedline') as $elm) {
|
2209 |
|
$elm->class .= ' bg-success';
|
2210 |
|
}
|
2211 |
|
|
2212 |
|
foreach ($html->find('.diffprevrev') as $elm) {
|
2213 |
|
$elm->class .= ' btn btn-default';
|
2214 |
|
$elm->innertext = iconify('mdi:chevron-left') . ' ' . $elm->innertext;
|
2215 |
|
}
|
2216 |
|
|
2217 |
|
foreach ($html->find('.diffnextrev') as $elm) {
|
2218 |
|
$elm->class .= ' btn btn-default';
|
2219 |
|
$elm->innertext = iconify('mdi:chevron-right') . ' ' . $elm->innertext;
|
2220 |
|
}
|
2221 |
|
|
2222 |
|
foreach ($html->find('.diffbothprevrev') as $elm) {
|
2223 |
|
$elm->class .= ' btn btn-default';
|
2224 |
|
$elm->innertext = iconify('mdi:chevron-double-left') . ' ' . $elm->innertext;
|
2225 |
|
}
|
2226 |
|
|
2227 |
|
foreach ($html->find('.minor') as $elm) {
|
2228 |
|
$elm->class .= ' text-muted';
|
2229 |
|
}
|
2230 |
|
|
2231 |
|
$content = $html->save();
|
2232 |
|
|
2233 |
|
$html->clear();
|
2234 |
|
unset($html);
|
2235 |
|
}
|
2236 |
|
|
2237 |
|
# Add icons for Extensions, Actions, etc.
|
2238 |
|
|
2239 |
|
$svg_icon = null;
|
2240 |
|
$iconify_icon = null;
|
2241 |
|
$iconify_attrs = array('class' => 'mr-2');
|
2242 |
|
|
2243 |
|
if (!$INFO['exists'] && $ACT == 'show') {
|
2244 |
|
$iconify_icon = 'mdi:alert';
|
2245 |
|
$iconify_attrs['style'] = 'color:orange';
|
2246 |
|
}
|
2247 |
|
|
2248 |
|
$menu_class = "\\dokuwiki\\Menu\\Item\\$ACT";
|
2249 |
|
|
2250 |
|
if (class_exists($menu_class, false)) {
|
2251 |
|
$menu_item = new $menu_class;
|
2252 |
|
$svg_icon = $menu_item->getSvg();
|
2253 |
|
}
|
2254 |
|
|
2255 |
|
switch ($ACT) {
|
2256 |
|
case 'admin':
|
2257 |
|
|
2258 |
|
if (($plugin = plugin_load('admin', $INPUT->str('page'))) !== null) {
|
2259 |
|
if (method_exists($plugin, 'getMenuIcon')) {
|
2260 |
|
$svg_icon = $plugin->getMenuIcon();
|
2261 |
|
|
2262 |
|
if (!file_exists($svg_icon)) {
|
2263 |
|
$iconify_icon = 'mdi:puzzle';
|
2264 |
|
$svg_icon = null;
|
2265 |
|
}
|
2266 |
1
|
} else {
|
2267 |
|
$iconify_icon = 'mdi:puzzle';
|
2268 |
|
$svg_icon = null;
|
2269 |
|
}
|
2270 |
|
}
|
2271 |
|
|
2272 |
|
break;
|
2273 |
|
|
2274 |
|
case 'resendpwd':
|
2275 |
|
$iconify_icon = 'mdi:lock-reset';
|
2276 |
|
break;
|
2277 |
|
|
2278 |
|
case 'denied':
|
2279 |
|
$iconify_icon = 'mdi:block-helper';
|
2280 |
|
$iconify_attrs['style'] = 'color:red';
|
2281 |
|
break;
|
2282 |
|
|
2283 |
|
case 'search':
|
2284 |
|
$iconify_icon = 'mdi:search-web';
|
2285 |
|
break;
|
2286 |
|
|
2287 |
|
case 'preview':
|
2288 |
|
$iconify_icon = 'mdi:file-eye';
|
2289 |
|
break;
|
2290 |
|
|
2291 |
|
case 'diff':
|
2292 |
|
$iconify_icon = 'mdi:file-compare';
|
2293 |
|
break;
|
2294 |
|
|
2295 |
|
case 'showtag':
|
2296 |
|
$iconify_icon = 'mdi:tag-multiple';
|
2297 |
|
break;
|
2298 |
|
|
2299 |
|
case 'draft':
|
2300 |
|
$iconify_icon = 'mdi:android-studio';
|
2301 |
|
break;
|
2302 |
|
|
2303 |
|
}
|
2304 |
|
|
2305 |
|
if ($svg_icon) {
|
2306 |
|
$svg_attrs = array('class' => 'iconify mr-2');
|
2307 |
|
|
2308 |
|
if ($ACT == 'admin' && $INPUT->str('page') == 'extension') {
|
2309 |
|
$svg_attrs['style'] = 'fill: green;';
|
2310 |
|
}
|
2311 |
|
|
2312 |
1
|
$svg = SVG::icon($svg_icon, null, '1em', $svg_attrs);
|
2313 |
|
|
2314 |
|
# Import HTML string
|
2315 |
|
$html = new \simple_html_dom;
|
2316 |
|
$html->load($content, true, false);
|
2317 |
|
|
2318 |
|
foreach ($html->find('h1') as $elm) {
|
2319 |
|
$elm->innertext = $svg . ' ' . $elm->innertext;
|
2320 |
|
break;
|
2321 |
|
}
|
2322 |
|
|
2323 |
|
$content = $html->save();
|
2324 |
|
|
2325 |
|
$html->clear();
|
2326 |
|
unset($html);
|
2327 |
|
}
|
2328 |
|
|
2329 |
|
if ($iconify_icon) {
|
2330 |
|
# Import HTML string
|
2331 |
|
$html = new \simple_html_dom;
|
2332 |
|
$html->load($content, true, false);
|
2333 |
|
|
2334 |
|
foreach ($html->find('h1') as $elm) {
|
2335 |
|
$elm->innertext = iconify($iconify_icon, $iconify_attrs) . $elm->innertext;
|
2336 |
|
break;
|
2337 |
|
}
|
2338 |
|
|
2339 |
|
$content = $html->save();
|
2340 |
|
|
2341 |
|
$html->clear();
|
2342 |
|
unset($html);
|
2343 |
|
}
|
2344 |
|
|
2345 |
|
return $content;
|
2346 |
|
}
|
2347 |
|
|
2348 |
|
/**
|
2349 |
|
* Detect the fluid navbar flag
|
2350 |
|
*
|
2351 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
2352 |
|
* @return boolean
|
2353 |
|
*/
|
2354 |
|
public function isFluidNavbar()
|
2355 |
|
{
|
2356 |
|
$fluid_container = $this->getConf('fluidContainer');
|
2357 |
|
$fixed_top_nabvar = $this->getConf('fixedTopNavbar');
|
2358 |
|
|
2359 |
|
return ($fluid_container || ($fluid_container && !$fixed_top_nabvar) || (!$fluid_container && !$fixed_top_nabvar));
|
2360 |
|
}
|
2361 |
|
|
2362 |
|
/**
|
2363 |
|
* Calculate automatically the grid size for main container
|
2364 |
|
*
|
2365 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
2366 |
|
*
|
2367 |
|
* @return string
|
2368 |
|
*/
|
2369 |
|
public function getContainerGrid()
|
2370 |
|
{
|
2371 |
|
global $ID;
|
2372 |
|
|
2373 |
|
$result = '';
|
2374 |
|
|
2375 |
|
$grids = array(
|
2376 |
|
'sm' => array('left' => 0, 'right' => 0),
|
2377 |
|
'md' => array('left' => 0, 'right' => 0),
|
2378 |
|
);
|
2379 |
|
|
2380 |
|
$show_right_sidebar = $this->getConf('showRightSidebar');
|
2381 |
|
$show_left_sidebar = $this->getConf('showSidebar');
|
2382 |
1
|
$fluid_container = $this->getConf('fluidContainer');
|
2383 |
|
|
2384 |
|
if ($this->getConf('showLandingPage') && (bool) preg_match($this->getConf('landingPages'), $ID)) {
|
2385 |
|
$show_left_sidebar = false;
|
2386 |
|
}
|
2387 |
|
|
2388 |
|
if ($show_left_sidebar) {
|
2389 |
|
foreach (explode(' ', $this->getConf('leftSidebarGrid')) as $grid) {
|
2390 |
|
list($col, $media, $size) = explode('-', $grid);
|
2391 |
|
$grids[$media]['left'] = (int) $size;
|
2392 |
|
}
|
2393 |
|
}
|
2394 |
|
|
2395 |
|
if ($show_right_sidebar) {
|
2396 |
|
foreach (explode(' ', $this->getConf('rightSidebarGrid')) as $grid) {
|
2397 |
|
list($col, $media, $size) = explode('-', $grid);
|
2398 |
|
$grids[$media]['right'] = (int) $size;
|
2399 |
|
}
|
2400 |
|
}
|
2401 |
|
|
2402 |
|
foreach ($grids as $media => $position) {
|
2403 |
|
$left = $position['left'];
|
2404 |
|
$right = $position['right'];
|
2405 |
|
$result .= sprintf('col-%s-%s ', $media, (12 - $left - $right));
|
2406 |
|
}
|
2407 |
|
|
2408 |
|
return $result;
|
2409 |
|
}
|
2410 |
|
|
2411 |
|
/**
|
2412 |
|
* Places the TOC where the function is called
|
2413 |
|
*
|
2414 |
|
* If you use this you most probably want to call tpl_content with
|
2415 |
|
* a false argument
|
2416 |
|
*
|
2417 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
2418 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
2419 |
|
*
|
2420 |
|
* @param bool $return Should the TOC be returned instead to be printed?
|
2421 |
|
* @return string
|
2422 |
|
*/
|
2423 |
3
|
public function getTOC($return = false)
|
2424 |
|
{
|
2425 |
|
global $TOC;
|
2426 |
|
global $ACT;
|
2427 |
|
global $ID;
|
2428 |
|
global $REV;
|
2429 |
|
global $INFO;
|
2430 |
|
global $conf;
|
2431 |
|
global $INPUT;
|
2432 |
|
|
2433 |
|
$toc = array();
|
2434 |
|
|
2435 |
|
if (is_array($TOC)) {
|
2436 |
|
// if a TOC was prepared in global scope, always use it
|
2437 |
|
$toc = $TOC;
|
2438 |
|
} elseif (($ACT == 'show' || substr($ACT, 0, 6) == 'export') && !$REV && $INFO['exists']) {
|
2439 |
|
// get TOC from metadata, render if neccessary
|
2440 |
|
$meta = p_get_metadata($ID, '', METADATA_RENDER_USING_CACHE);
|
2441 |
|
if (isset($meta['internal']['toc'])) {
|
2442 |
|
$tocok = $meta['internal']['toc'];
|
2443 |
|
} else {
|
2444 |
|
$tocok = true;
|
2445 |
|
}
|
2446 |
|
$toc = isset($meta['description']['tableofcontents']) ? $meta['description']['tableofcontents'] : null;
|
2447 |
|
if (!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']) {
|
2448 |
|
$toc = array();
|
2449 |
|
}
|
2450 |
|
} elseif ($ACT == 'admin') {
|
2451 |
|
// try to load admin plugin TOC
|
2452 |
|
/** @var $plugin DokuWiki_Admin_Plugin */
|
2453 |
|
if ($plugin = plugin_getRequestAdminPlugin()) {
|
2454 |
|
$toc = $plugin->getTOC();
|
2455 |
|
$TOC = $toc; // avoid later rebuild
|
2456 |
|
}
|
2457 |
|
}
|
2458 |
|
|
2459 |
|
$toc_check = end($toc);
|
2460 |
|
$toc_undefined = null;
|
2461 |
|
|
2462 |
|
if (!preg_match('/bootstrap/', $toc_check['link'])) {
|
2463 |
|
$toc_undefined = array_pop($toc);
|
2464 |
|
}
|
2465 |
|
|
2466 |
|
|
2467 |
|
trigger_event('TPL_TOC_RENDER', $toc, null, false);
|
2468 |
|
|
2469 |
|
if ($ACT == 'admin' && $INPUT->str('page') == 'config') {
|
2470 |
|
$bootstrap3_sections = array(
|
2471 |
|
'theme', 'sidebar', 'navbar', 'semantic', 'layout', 'toc',
|
2472 |
|
'discussion', 'avatar', 'cookie_law', 'google_analytics',
|
2473 |
|
'browser_title', 'page',
|
2474 |
|
);
|
2475 |
|
|
2476 |
|
foreach ($bootstrap3_sections as $id) {
|
2477 |
|
$toc[] = array(
|
2478 |
|
'link' => "#bootstrap3__$id",
|
2479 |
|
'title' => tpl_getLang("config_$id"),
|
2480 |
|
'type' => 'ul',
|
2481 |
|
'level' => 3,
|
2482 |
|
);
|
2483 |
|
}
|
2484 |
|
}
|
2485 |
|
|
2486 |
|
if ($toc_undefined) {
|
2487 |
|
$toc[] = $toc_undefined;
|
2488 |
|
}
|
2489 |
|
|
2490 |
|
$html = $this->renderTOC($toc);
|
2491 |
|
|
2492 |
|
if ($return) {
|
2493 |
|
return $html;
|
2494 |
|
}
|
2495 |
|
|
2496 |
|
echo $html;
|
2497 |
|
return '';
|
2498 |
|
}
|
2499 |
|
|
2500 |
|
/**
|
2501 |
|
* Return the TOC rendered to XHTML with Bootstrap3 style
|
2502 |
|
*
|
2503 |
|
* @author Andreas Gohr <andi@splitbrain.org>
|
2504 |
|
* @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
2505 |
|
*
|
2506 |
|
* @param array $toc
|
2507 |
|
* @return string html
|
2508 |
|
*/
|
2509 |
|
private function renderTOC($toc)
|
2510 |
|
{
|
2511 |
|
if (!count($toc)) {
|
2512 |
|
return '';
|
2513 |
|
}
|
2514 |
|
|
2515 |
|
global $lang;
|
2516 |
|
|
2517 |
|
$json_toc = array();
|
2518 |
|
|
2519 |
|
foreach ($toc as $item) {
|
2520 |
|
$json_toc[] = array(
|
2521 |
|
'link' => (isset($item['link']) ? $item['link'] : '#' . $item['hid']),
|
2522 |
|
'title' => $item['title'],
|
2523 |
|
'level' => $item['level'],
|
2524 |
|
);
|
2525 |
|
}
|
2526 |
|
|
2527 |
|
$out = '';
|
2528 |
|
$out .= '<script>JSINFO.bootstrap3.toc = ' . json_encode($json_toc) . ';</script>' . DOKU_LF;
|
2529 |
|
|
2530 |
|
if ($this->getConf('tocLayout') !== 'navbar') {
|
2531 |
|
$out .= '<!-- TOC START -->' . DOKU_LF;
|
2532 |
|
$out .= '<div class="dw-toc hidden-print">' . DOKU_LF;
|
2533 |
|
$out .= '<nav id="dw__toc" role="navigation" class="toc-panel panel panel-default small">' . DOKU_LF;
|
2534 |
|
$out .= '<h6 data-toggle="collapse" data-target="#dw__toc .toc-body" title="' . $lang['toc'] . '" class="panel-heading toc-title">' . iconify('mdi:view-list') . ' ';
|
2535 |
|
$out .= '<span>' . $lang['toc'] . '</span>';
|
2536 |
|
$out .= ' <i class="caret"></i></h6>' . DOKU_LF;
|
2537 |
|
$out .= '<div class="panel-body toc-body collapse ' . (!$this->getConf('tocCollapsed') ? 'in' : '') . '">' . DOKU_LF;
|
2538 |
|
$out .= $this->normalizeList(html_buildlist($toc, 'nav toc', 'html_list_toc', 'html_li_default', true)) . DOKU_LF;
|
2539 |
|
$out .= '</div>' . DOKU_LF;
|
2540 |
|
$out .= '</nav>' . DOKU_LF;
|
2541 |
|
$out .= '</div>' . DOKU_LF;
|
2542 |
|
$out .= '<!-- TOC END -->' . DOKU_LF;
|
2543 |
|
}
|
2544 |
|
|
2545 |
|
return $out;
|
2546 |
|
}
|
2547 |
|
|
2548 |
|
private function initToolsMenu()
|
2549 |
|
{
|
2550 |
|
global $ACT;
|
2551 |
|
|
2552 |
|
$tools_menus = array(
|
2553 |
|
'user' => array('icon' => 'mdi:account', 'object' => new \dokuwiki\Menu\UserMenu),
|
2554 |
|
'site' => array('icon' => 'mdi:toolbox', 'object' => new \dokuwiki\Menu\SiteMenu),
|
2555 |
|
'page' => array('icon' => 'mdi:file-document-outline', 'object' => new \dokuwiki\template\bootstrap3\Menu\PageMenu),
|
2556 |
|
);
|
2557 |
|
|
2558 |
|
if (defined('DOKU_MEDIADETAIL')) {
|
2559 |
|
$tools_menus['page'] = array('icon' => 'mdi:image', 'object' => new \dokuwiki\template\bootstrap3\Menu\DetailMenu);
|
2560 |
|
}
|
2561 |
|
|
2562 |
|
foreach ($tools_menus as $tool => $data) {
|
2563 |
|
foreach ($data['object']->getItems() as $item) {
|
2564 |
|
$attr = buildAttributes($item->getLinkAttributes());
|
2565 |
|
$active = 'action';
|
2566 |
|
|
2567 |
|
if ($ACT == $item->getType() || ($ACT == 'revisions' && $item->getType() == 'revs') || ($ACT == 'diff' && $item->getType() == 'revs')) {
|
2568 |
|
$active .= ' active';
|
2569 |
|
}
|
2570 |
|
|
2571 |
|
if ($item->getType() == 'shareon') {
|
2572 |
|
$active .= ' dropdown';
|
2573 |
|
}
|
2574 |
|
|
2575 |
|
$html = '<li class="' . $active . '">';
|
2576 |
|
$html .= "<a $attr>";
|
2577 |
|
$html .= \inlineSVG($item->getSvg());
|
2578 |
|
$html .= '<span>' . hsc($item->getLabel()) . '</span>';
|
2579 |
|
$html .= "</a>";
|
2580 |
|
|
2581 |
|
if ($item->getType() == 'shareon') {
|
2582 |
|
$html .= $item->getDropDownMenu();
|
2583 |
|
}
|
2584 |
|
|
2585 |
|
$html .= '</li>';
|
2586 |
|
|
2587 |
|
$tools_menus[$tool]['menu'][$item->getType()]['object'] = $item;
|
2588 |
|
$tools_menus[$tool]['menu'][$item->getType()]['html'] = $html;
|
2589 |
|
}
|
2590 |
|
}
|
2591 |
|
|
2592 |
|
$this->toolsMenu = $tools_menus;
|
2593 |
|
}
|
2594 |
|
|
2595 |
|
public function getToolsMenu()
|
2596 |
|
{
|
2597 |
|
return $this->toolsMenu;
|
2598 |
|
}
|
2599 |
|
|
2600 |
|
public function getToolMenu($tool)
|
2601 |
|
{
|
2602 |
|
return $this->toolsMenu[$tool];
|
2603 |
|
}
|
2604 |
|
|
2605 |
|
public function getToolMenuItem($tool, $item)
|
2606 |
|
{
|
2607 |
|
if (isset($this->toolsMenu[$tool]) && isset($this->toolsMenu[$tool]['menu'][$item])) {
|
2608 |
|
return $this->toolsMenu[$tool]['menu'][$item]['object'];
|
2609 |
|
}
|
2610 |
|
return null;
|
2611 |
|
}
|
2612 |
|
|
2613 |
|
public function getToolMenuItemLink($tool, $item)
|
2614 |
|
{
|
2615 |
|
if (isset($this->toolsMenu[$tool]) && isset($this->toolsMenu[$tool]['menu'][$item])) {
|
2616 |
|
return $this->toolsMenu[$tool]['menu'][$item]['html'];
|
2617 |
|
}
|
2618 |
|
return null;
|
2619 |
|
}
|
2620 |
|
|
2621 |
|
public function getNavbarHeight()
|
2622 |
|
{
|
2623 |
|
switch ($this->getBootswatchTheme()) {
|
2624 |
|
case 'simplex':
|
2625 |
|
case 'superhero':
|
2626 |
|
return 40;
|
2627 |
|
|
2628 |
|
case 'yeti':
|
2629 |
|
return 45;
|
2630 |
|
|
2631 |
|
case 'cerulean':
|
2632 |
|
case 'cosmo':
|
2633 |
|
case 'custom':
|
2634 |
|
case 'cyborg':
|
2635 |
|
case 'lumen':
|
2636 |
|
case 'slate':
|
2637 |
|
case 'spacelab':
|
2638 |
|
case 'solar':
|
2639 |
|
case 'united':
|
2640 |
|
return 50;
|
2641 |
|
|
2642 |
|
case 'darkly':
|
2643 |
|
case 'flatly':
|
2644 |
|
case 'journal':
|
2645 |
|
case 'sandstone':
|
2646 |
|
return 60;
|
2647 |
|
|
2648 |
|
case 'paper':
|
2649 |
|
return 64;
|
2650 |
|
|
2651 |
|
case 'readable':
|
2652 |
|
return 65;
|
2653 |
|
|
2654 |
|
default:
|
2655 |
|
return 50;
|
2656 |
|
}
|
2657 |
|
}
|
2658 |
|
}
|