1<?php 2 3namespace dokuwiki\template\sprintdoc; 4 5/** 6 * Class Template 7 * 8 * provides additional logic for the sprintdoc template 9 * 10 * @package dokuwiki\template\sprintdoc 11 */ 12class Template { 13 14 /** @var array loaded plugins */ 15 protected $plugins = array( 16 'sqlite' => null, 17 'tagging' => null, 18 'magicmatcher' => null, 19 'tplinc' => null, 20 'sitemapnavi' => null, 21 ); 22 23 /** @var string the type of special navigation to use */ 24 protected $nav = ''; 25 26 27 /** 28 * Get the singleton instance 29 * 30 * @return Template 31 */ 32 public static function getInstance() { 33 static $instance = null; 34 if($instance === null) $instance = new Template(); 35 return $instance; 36 } 37 38 /** 39 * Template constructor. 40 */ 41 protected function __construct() { 42 $this->initializePlugins(); 43 $this->initNavigationCookie(); 44 45 /** @var \Doku_Event_Handler */ 46 global $EVENT_HANDLER; 47 $EVENT_HANDLER->register_hook('PLUGIN_TPLINC_LOCATIONS_SET', 'BEFORE', $this, 'registerIncludes'); 48 } 49 50 /** 51 * Load all the plugins we support directly 52 */ 53 protected function initializePlugins() { 54 $this->plugins['sqlite'] = plugin_load('helper', 'sqlite'); 55 if($this->plugins['sqlite']) { 56 $this->plugins['tagging'] = plugin_load('helper', 'tagging'); 57 $this->plugins['magicmatcher'] = plugin_load('syntax', 'magicmatcher_issuelist'); 58 } 59 $this->plugins['tplinc'] = plugin_load('helper', 'tplinc'); 60 $this->plugins['sitemapnavi'] = plugin_load('helper', 'sitemapnavi'); 61 } 62 63 /** 64 * Makes include position info available to the tplinc plugin 65 * 66 * @param \Doku_Event $event 67 */ 68 public function registerIncludes(\Doku_Event $event) { 69 $event->data['footer'] = 'Footer below the page content'; 70 $event->data['sidebarfooter'] = 'Footer below the sidebar'; 71 $event->data['sidebarheader'] = 'Header above the sidebar'; 72 } 73 74 /** 75 * Get the content to include from the tplinc plugin 76 * 77 * prefix and postfix are only added when there actually is any content 78 * 79 * @param string $location 80 * @param string $pre prepend this before the content 81 * @param string $post append this to the content 82 * @return string 83 */ 84 public function getInclude($location, $pre = '', $post = '') { 85 if(!$this->plugins['tplinc']) return ''; 86 $content = $this->plugins['tplinc']->renderIncludes($location); 87 if($content === '') return ''; 88 return $pre . $content . $post; 89 } 90 91 /** 92 * Sets a cookie to remember the requested special navigation 93 */ 94 protected function initNavigationCookie() { 95 if ($this->plugins['sitemapnavi'] === null) return; 96 global $INPUT; 97 98 $nav = $INPUT->str('nav'); 99 if($nav) { 100 set_doku_pref('nav', $nav); 101 $this->nav = $INPUT->str('nav'); 102 } else { 103 $this->nav = get_doku_pref('nav', 'sidebar'); 104 } 105 } 106 107 /** 108 * Return the navigation for the sidebar 109 * 110 * Defaults to the standard sidebar mechanism, but supports also the sitemapnavi plugin 111 * 112 * @return string 113 */ 114 public function getNavigation() { 115 global $ID; 116 global $conf; 117 118 // add tabs if multiple navigation types available 119 $header = ''; 120 if ($this->plugins['sitemapnavi'] !== null) { 121 $header = '<ul class="sidebar-tabs">'; 122 $header .= '<li class="' . ($this->nav === 'sidebar' ? 'active' : '') . '">' . 123 '<a href="' . wl($ID, ['nav' => 'sidebar']) . '">'.tpl_getLang('nav_sidebar').'</a></li>'; 124 $header .= '<li class="' . ($this->nav === 'sitemap' ? 'active' : '') . '">' . 125 '<a href="' . wl($ID, ['nav' => 'sitemap']) . '">'.tpl_getLang('nav_sitemap').'</a></li>'; 126 $header .= '</ul>'; 127 } 128 129 // decide what to show 130 if ($this->nav === 'sitetree') { 131 // site tree created by sitemapnavi plugin 132 $nav = '<nav class="nav-sitemapnavi" id="plugin__sitemapnavi">'; 133 $nav .= $this->plugins['sitemapnavi']->getSiteMap(':'); 134 $nav .= '</nav>'; 135 } else { 136 // main navigation, loaded from standard sidebar, fixed up by javascript 137 $nav = '<nav class="nav-main">'; 138 $nav .= tpl_include_page($conf['sidebar'], false, true); 139 $nav .= '</nav>'; 140 } 141 142 return $header . $nav; 143 } 144 145 /** 146 * Get all the tabs to display 147 * 148 * @return array 149 */ 150 public function getMetaBoxTabs() { 151 global $lang, $INFO; 152 $tabs = array(); 153 154 $toc = tpl_toc(true); 155 if($toc) { 156 $tabs[] = array( 157 'id' => 'spr__tab-toc', 158 'label' => $lang['toc'], 159 'tab' => $toc, 160 'count' => null, 161 ); 162 } 163 164 if($this->plugins['tagging']) { 165 $tabs[] = array( 166 'id' => 'spr__tab-tags', 167 'label' => tpl_getLang('tab_tags'), 168 'tab' => $this->plugins['tagging']->tpl_tags(false), 169 'count' => count($this->plugins['tagging']->findItems(array('pid' => $INFO['id']), 'tag')), 170 ); 171 } 172 173 if ($this->plugins['magicmatcher']) { 174 $tabs[] = array( 175 'id' => 'spr__tab-issues', 176 'label' => tpl_getLang('tab_issues'), 177 'tab' => $this->plugins['magicmatcher']->getIssueListHTML(), 178 'count' => $this->plugins['magicmatcher']->getCountIssues(), 179 ); 180 } 181 182 return $tabs; 183 } 184 185 /** 186 * Creates an image tag and includes the first found image correctly resized 187 * 188 * @param string $tag 189 * @param array $attributes 190 * @param int $w 191 * @param int $h 192 * @return string 193 */ 194 public static function getResizedImgTag($tag, $attributes, $w, $h) { 195 $attr = ''; 196 $medias = array(); 197 198 // the attribute having an array defines where the image goes 199 foreach($attributes as $attribute => $data) { 200 if(is_array($data)) { 201 $medias = $data; 202 $attr = $attribute; 203 } 204 } 205 // if the image attribute could not be found return 206 if(!$attr || !$medias) return ''; 207 208 // try all medias until an existing one is found 209 $media = ''; 210 foreach($medias as $media) { 211 if(file_exists(mediaFN($media))) break; 212 $media = ''; 213 } 214 if($media === '') return ''; 215 216 // replace the array 217 $media = ml($media, array('w' => $w, 'h' => $h, 'crop' => 1), true, '&'); 218 $attributes[$attr] = $media; 219 220 // return the full tag 221 return '<' . $tag . ' ' . buildAttributes($attributes) . ' />' . "\n"; 222 } 223 224 /** 225 * Embed the main logo 226 * 227 * Tries a few different locations 228 */ 229 public function mainLogo() { 230 global $conf; 231 232 // homepage logo should not link to itself (BITV accessibility requirement) 233 $linkit = (strcmp(wl(), $_SERVER['REQUEST_URI']) !== 0); 234 if($linkit) { 235 $title = $conf['title'] . tpl_getLang('adjunct_linked_logo_text'); 236 } else { 237 $title = tpl_getLang('adjunct_start_logo_text') . $conf['title']; 238 } 239 240 $desktop = self::getResizedImgTag( 241 'img', 242 array( 243 'class' => 'mobile-hide', 244 'src' => array('wiki:logo-wide.png', 'wiki:logo.png'), 245 'alt' => $title, 246 ), 247 0, 0 248 ); 249 $mobile = self::getResizedImgTag( 250 'img', 251 array( 252 'class' => 'mobile-only', 253 'src' => array('wiki:logo-32x32.png', 'wiki:favicon.png', 'wiki:logo-square.png', 'wiki:logo.png'), 254 'alt' => $title, 255 ), 256 32, 32 257 ); 258 259 // homepage logo should not link to itself (BITV accessibility requirement) 260 if($linkit) { 261 tpl_link(wl(), $desktop, 'accesskey="h" title="[H]"'); 262 tpl_link(wl(), $mobile, 'accesskey="h" title="[H]"'); 263 } else { 264 echo $desktop; 265 echo $mobile; 266 } 267 } 268 269 /** 270 * Add the current mode information to the hierarchical breadcrumbs 271 */ 272 public function breadcrumbSuffix() { 273 global $ACT; 274 global $lang; 275 global $INPUT; 276 global $ID; 277 global $conf; 278 global $IMG; 279 if($ACT == 'show') return; 280 281 // find an apropriate label for the current mode 282 if($ACT) { 283 $label = tpl_getLang('mode_' . $ACT); 284 if(!$label) { 285 if(isset($lang['btn_' . $ACT])) { 286 $label = $lang['btn_' . $ACT]; 287 } else { 288 $label = $ACT; 289 } 290 } 291 } else { 292 // actually we would need to create a proper namespace breadcrumb path here, 293 // but this is the most simplest thing we can do for now 294 if(defined('DOKU_MEDIADETAIL')) { 295 $label = hsc(noNS($IMG)); 296 } else { 297 return; 298 } 299 } 300 301 if($ACT == 'admin' && $INPUT->has('page')) { 302 $link = wl($ID, array('do' => 'admin')); 303 echo '<bdi> : <a href="' . $link . '"><strong>' . $label . '</strong></a></bdi>'; 304 305 /** @var \DokuWiki_Admin_Plugin $plugin */ 306 $plugin = plugin_load('admin', $INPUT->str('page')); 307 if(!$plugin) return; 308 309 $label = $plugin->getMenuText($conf['lang']); 310 } 311 312 echo '<bdi><span class="curid"> : <strong>' . $label . '</strong></span></bdi>'; 313 } 314} 315