12387fd46SAndreas Gohr<?php 22387fd46SAndreas Gohr 32387fd46SAndreas Gohrnamespace dokuwiki\template\sprintdoc; 42387fd46SAndreas Gohr 52387fd46SAndreas Gohr/** 62387fd46SAndreas Gohr * Class Template 72387fd46SAndreas Gohr * 82387fd46SAndreas Gohr * provides additional logic for the sprintdoc template 92387fd46SAndreas Gohr * 102387fd46SAndreas Gohr * @package dokuwiki\template\sprintdoc 112387fd46SAndreas Gohr */ 122387fd46SAndreas Gohrclass Template { 132387fd46SAndreas Gohr 14c1e0eaa8SAndreas Gohr /** @var array loaded plugins */ 152387fd46SAndreas Gohr protected $plugins = array( 162387fd46SAndreas Gohr 'sqlite' => null, 172387fd46SAndreas Gohr 'tagging' => null, 181f3641a8SMichael Große 'magicmatcher' => null, 19c1e0eaa8SAndreas Gohr 'tplinc' => null, 20c1e0eaa8SAndreas Gohr 'sitemapnavi' => null, 212387fd46SAndreas Gohr ); 222387fd46SAndreas Gohr 23c1e0eaa8SAndreas Gohr /** @var string the type of special navigation to use */ 24c1e0eaa8SAndreas Gohr protected $nav = ''; 25c1e0eaa8SAndreas Gohr 26c1e0eaa8SAndreas Gohr 272387fd46SAndreas Gohr /** 282387fd46SAndreas Gohr * Get the singleton instance 292387fd46SAndreas Gohr * 302387fd46SAndreas Gohr * @return Template 312387fd46SAndreas Gohr */ 322387fd46SAndreas Gohr public static function getInstance() { 332387fd46SAndreas Gohr static $instance = null; 342387fd46SAndreas Gohr if($instance === null) $instance = new Template(); 352387fd46SAndreas Gohr return $instance; 362387fd46SAndreas Gohr } 372387fd46SAndreas Gohr 382387fd46SAndreas Gohr /** 392387fd46SAndreas Gohr * Template constructor. 402387fd46SAndreas Gohr */ 412387fd46SAndreas Gohr protected function __construct() { 422387fd46SAndreas Gohr $this->initializePlugins(); 43c1e0eaa8SAndreas Gohr $this->initNavigationCookie(); 44cad2e674SAndreas Gohr 45cad2e674SAndreas Gohr /** @var \Doku_Event_Handler */ 46cad2e674SAndreas Gohr global $EVENT_HANDLER; 47cad2e674SAndreas Gohr $EVENT_HANDLER->register_hook('PLUGIN_TPLINC_LOCATIONS_SET', 'BEFORE', $this, 'registerIncludes'); 48cad2e674SAndreas Gohr } 49cad2e674SAndreas Gohr 50cad2e674SAndreas Gohr /** 51c1e0eaa8SAndreas Gohr * Load all the plugins we support directly 52c1e0eaa8SAndreas Gohr */ 53c1e0eaa8SAndreas Gohr protected function initializePlugins() { 54c1e0eaa8SAndreas Gohr $this->plugins['sqlite'] = plugin_load('helper', 'sqlite'); 55c1e0eaa8SAndreas Gohr if($this->plugins['sqlite']) { 56c1e0eaa8SAndreas Gohr $this->plugins['tagging'] = plugin_load('helper', 'tagging'); 57c1e0eaa8SAndreas Gohr $this->plugins['magicmatcher'] = plugin_load('syntax', 'magicmatcher_issuelist'); 58c1e0eaa8SAndreas Gohr } 59c1e0eaa8SAndreas Gohr $this->plugins['tplinc'] = plugin_load('helper', 'tplinc'); 60c1e0eaa8SAndreas Gohr $this->plugins['sitemapnavi'] = plugin_load('helper', 'sitemapnavi'); 61c1e0eaa8SAndreas Gohr } 62c1e0eaa8SAndreas Gohr 63c1e0eaa8SAndreas Gohr /** 64cad2e674SAndreas Gohr * Makes include position info available to the tplinc plugin 65cad2e674SAndreas Gohr * 66cad2e674SAndreas Gohr * @param \Doku_Event $event 67cad2e674SAndreas Gohr */ 68cad2e674SAndreas Gohr public function registerIncludes(\Doku_Event $event) { 69cad2e674SAndreas Gohr $event->data['footer'] = 'Footer below the page content'; 70485e7ff4SMichael Große $event->data['sidebarfooter'] = 'Footer below the sidebar'; 71485e7ff4SMichael Große $event->data['sidebarheader'] = 'Header above the sidebar'; 72cad2e674SAndreas Gohr } 73cad2e674SAndreas Gohr 74cad2e674SAndreas Gohr /** 75cad2e674SAndreas Gohr * Get the content to include from the tplinc plugin 76cad2e674SAndreas Gohr * 77cad2e674SAndreas Gohr * prefix and postfix are only added when there actually is any content 78cad2e674SAndreas Gohr * 79cad2e674SAndreas Gohr * @param string $location 80cad2e674SAndreas Gohr * @param string $pre prepend this before the content 81cad2e674SAndreas Gohr * @param string $post append this to the content 82cad2e674SAndreas Gohr * @return string 83cad2e674SAndreas Gohr */ 84cad2e674SAndreas Gohr public function getInclude($location, $pre = '', $post = '') { 85cad2e674SAndreas Gohr if(!$this->plugins['tplinc']) return ''; 86cad2e674SAndreas Gohr $content = $this->plugins['tplinc']->renderIncludes($location); 87cad2e674SAndreas Gohr if($content === '') return ''; 88cad2e674SAndreas Gohr return $pre . $content . $post; 892387fd46SAndreas Gohr } 902387fd46SAndreas Gohr 912387fd46SAndreas Gohr /** 92c1e0eaa8SAndreas Gohr * Sets a cookie to remember the requested special navigation 932387fd46SAndreas Gohr */ 94c1e0eaa8SAndreas Gohr protected function initNavigationCookie() { 95c1e0eaa8SAndreas Gohr if ($this->plugins['sitemapnavi'] === null) return; 96c1e0eaa8SAndreas Gohr global $INPUT; 97c1e0eaa8SAndreas Gohr 98c1e0eaa8SAndreas Gohr $nav = $INPUT->str('nav'); 99c1e0eaa8SAndreas Gohr if($nav) { 100c1e0eaa8SAndreas Gohr set_doku_pref('nav', $nav); 101c1e0eaa8SAndreas Gohr $this->nav = $INPUT->str('nav'); 102c1e0eaa8SAndreas Gohr } else { 103c1e0eaa8SAndreas Gohr $this->nav = get_doku_pref('nav', 'sidebar'); 1042387fd46SAndreas Gohr } 105c1e0eaa8SAndreas Gohr } 106c1e0eaa8SAndreas Gohr 107c1e0eaa8SAndreas Gohr /** 108c1e0eaa8SAndreas Gohr * Return the navigation for the sidebar 109c1e0eaa8SAndreas Gohr * 110c1e0eaa8SAndreas Gohr * Defaults to the standard sidebar mechanism, but supports also the sitemapnavi plugin 111c1e0eaa8SAndreas Gohr * 112c1e0eaa8SAndreas Gohr * @return string 113c1e0eaa8SAndreas Gohr */ 114c1e0eaa8SAndreas Gohr public function getNavigation() { 115c1e0eaa8SAndreas Gohr global $ID; 116c1e0eaa8SAndreas Gohr global $conf; 117c1e0eaa8SAndreas Gohr 118c1e0eaa8SAndreas Gohr // add tabs if multiple navigation types available 119c1e0eaa8SAndreas Gohr $header = ''; 120c1e0eaa8SAndreas Gohr if ($this->plugins['sitemapnavi'] !== null) { 121c1e0eaa8SAndreas Gohr $header = '<ul class="sidebar-tabs">'; 122c1e0eaa8SAndreas Gohr $header .= '<li class="' . ($this->nav === 'sidebar' ? 'active' : '') . '">' . 123c1e0eaa8SAndreas Gohr '<a href="' . wl($ID, ['nav' => 'sidebar']) . '">'.tpl_getLang('nav_sidebar').'</a></li>'; 124c1e0eaa8SAndreas Gohr $header .= '<li class="' . ($this->nav === 'sitemap' ? 'active' : '') . '">' . 125c1e0eaa8SAndreas Gohr '<a href="' . wl($ID, ['nav' => 'sitemap']) . '">'.tpl_getLang('nav_sitemap').'</a></li>'; 126c1e0eaa8SAndreas Gohr $header .= '</ul>'; 127c1e0eaa8SAndreas Gohr } 128c1e0eaa8SAndreas Gohr 129c1e0eaa8SAndreas Gohr // decide what to show 130*046583e2SAndreas Gohr if ($this->nav === 'sitemap') { 131c1e0eaa8SAndreas Gohr // site tree created by sitemapnavi plugin 132c1e0eaa8SAndreas Gohr $nav = '<nav class="nav-sitemapnavi" id="plugin__sitemapnavi">'; 133c1e0eaa8SAndreas Gohr $nav .= $this->plugins['sitemapnavi']->getSiteMap(':'); 134c1e0eaa8SAndreas Gohr $nav .= '</nav>'; 135c1e0eaa8SAndreas Gohr } else { 136c1e0eaa8SAndreas Gohr // main navigation, loaded from standard sidebar, fixed up by javascript 137c1e0eaa8SAndreas Gohr $nav = '<nav class="nav-main">'; 138c1e0eaa8SAndreas Gohr $nav .= tpl_include_page($conf['sidebar'], false, true); 139c1e0eaa8SAndreas Gohr $nav .= '</nav>'; 140c1e0eaa8SAndreas Gohr } 141c1e0eaa8SAndreas Gohr 142c1e0eaa8SAndreas Gohr return $header . $nav; 1432387fd46SAndreas Gohr } 1442387fd46SAndreas Gohr 1452387fd46SAndreas Gohr /** 1462387fd46SAndreas Gohr * Get all the tabs to display 1472387fd46SAndreas Gohr * 1482387fd46SAndreas Gohr * @return array 1492387fd46SAndreas Gohr */ 1502387fd46SAndreas Gohr public function getMetaBoxTabs() { 15167d7dea5SMichael Große global $lang, $INFO; 1522387fd46SAndreas Gohr $tabs = array(); 1532387fd46SAndreas Gohr 1542387fd46SAndreas Gohr $toc = tpl_toc(true); 1552387fd46SAndreas Gohr if($toc) { 1562387fd46SAndreas Gohr $tabs[] = array( 1572387fd46SAndreas Gohr 'id' => 'spr__tab-toc', 1582387fd46SAndreas Gohr 'label' => $lang['toc'], 1592387fd46SAndreas Gohr 'tab' => $toc, 1602387fd46SAndreas Gohr 'count' => null, 1612387fd46SAndreas Gohr ); 1622387fd46SAndreas Gohr } 1632387fd46SAndreas Gohr 1642387fd46SAndreas Gohr if($this->plugins['tagging']) { 1652387fd46SAndreas Gohr $tabs[] = array( 1662387fd46SAndreas Gohr 'id' => 'spr__tab-tags', 1672387fd46SAndreas Gohr 'label' => tpl_getLang('tab_tags'), 1682387fd46SAndreas Gohr 'tab' => $this->plugins['tagging']->tpl_tags(false), 16967d7dea5SMichael Große 'count' => count($this->plugins['tagging']->findItems(array('pid' => $INFO['id']), 'tag')), 1702387fd46SAndreas Gohr ); 1712387fd46SAndreas Gohr } 1722387fd46SAndreas Gohr 1731f3641a8SMichael Große if ($this->plugins['magicmatcher']) { 1741f3641a8SMichael Große $tabs[] = array( 1751f3641a8SMichael Große 'id' => 'spr__tab-issues', 1769cae5e77SMichael Große 'label' => tpl_getLang('tab_issues'), 1771f3641a8SMichael Große 'tab' => $this->plugins['magicmatcher']->getIssueListHTML(), 1781f3641a8SMichael Große 'count' => $this->plugins['magicmatcher']->getCountIssues(), 1791f3641a8SMichael Große ); 1801f3641a8SMichael Große } 1812387fd46SAndreas Gohr 1822387fd46SAndreas Gohr return $tabs; 1832387fd46SAndreas Gohr } 18406cdf148SAndreas Gohr 18506cdf148SAndreas Gohr /** 18606cdf148SAndreas Gohr * Creates an image tag and includes the first found image correctly resized 18706cdf148SAndreas Gohr * 18806cdf148SAndreas Gohr * @param string $tag 18906cdf148SAndreas Gohr * @param array $attributes 19006cdf148SAndreas Gohr * @param int $w 19106cdf148SAndreas Gohr * @param int $h 19206cdf148SAndreas Gohr * @return string 19306cdf148SAndreas Gohr */ 19406cdf148SAndreas Gohr public static function getResizedImgTag($tag, $attributes, $w, $h) { 19506cdf148SAndreas Gohr $attr = ''; 19606cdf148SAndreas Gohr $medias = array(); 19706cdf148SAndreas Gohr 19806cdf148SAndreas Gohr // the attribute having an array defines where the image goes 19906cdf148SAndreas Gohr foreach($attributes as $attribute => $data) { 20006cdf148SAndreas Gohr if(is_array($data)) { 20106cdf148SAndreas Gohr $medias = $data; 20206cdf148SAndreas Gohr $attr = $attribute; 20306cdf148SAndreas Gohr } 20406cdf148SAndreas Gohr } 20506cdf148SAndreas Gohr // if the image attribute could not be found return 20606cdf148SAndreas Gohr if(!$attr || !$medias) return ''; 20706cdf148SAndreas Gohr 20806cdf148SAndreas Gohr // try all medias until an existing one is found 20906cdf148SAndreas Gohr $media = ''; 21006cdf148SAndreas Gohr foreach($medias as $media) { 21106cdf148SAndreas Gohr if(file_exists(mediaFN($media))) break; 21206cdf148SAndreas Gohr $media = ''; 21306cdf148SAndreas Gohr } 21406cdf148SAndreas Gohr if($media === '') return ''; 21506cdf148SAndreas Gohr 21606cdf148SAndreas Gohr // replace the array 21706cdf148SAndreas Gohr $media = ml($media, array('w' => $w, 'h' => $h, 'crop' => 1), true, '&'); 21806cdf148SAndreas Gohr $attributes[$attr] = $media; 21906cdf148SAndreas Gohr 22006cdf148SAndreas Gohr // return the full tag 2219dbc42beSAndreas Gohr return '<' . $tag . ' ' . buildAttributes($attributes) . ' />' . "\n"; 22206cdf148SAndreas Gohr } 2233a6eaa0bSAndreas Gohr 2243a6eaa0bSAndreas Gohr /** 2253a6eaa0bSAndreas Gohr * Embed the main logo 2263a6eaa0bSAndreas Gohr * 2273a6eaa0bSAndreas Gohr * Tries a few different locations 2283a6eaa0bSAndreas Gohr */ 2293a6eaa0bSAndreas Gohr public function mainLogo() { 2303a6eaa0bSAndreas Gohr global $conf; 2313a6eaa0bSAndreas Gohr 232e17d84d6SAndreas Gohr // homepage logo should not link to itself (BITV accessibility requirement) 233e17d84d6SAndreas Gohr $linkit = (strcmp(wl(), $_SERVER['REQUEST_URI']) !== 0); 234e17d84d6SAndreas Gohr if($linkit) { 235e17d84d6SAndreas Gohr $title = $conf['title'] . tpl_getLang('adjunct_linked_logo_text'); 236e17d84d6SAndreas Gohr } else { 237e17d84d6SAndreas Gohr $title = tpl_getLang('adjunct_start_logo_text') . $conf['title']; 238e17d84d6SAndreas Gohr } 239e17d84d6SAndreas Gohr 2403a6eaa0bSAndreas Gohr $desktop = self::getResizedImgTag( 2413a6eaa0bSAndreas Gohr 'img', 2423a6eaa0bSAndreas Gohr array( 2433a6eaa0bSAndreas Gohr 'class' => 'mobile-hide', 244e302d67fSMichael Große 'src' => array('wiki:logo-wide.png', 'wiki:logo.png'), 245e17d84d6SAndreas Gohr 'alt' => $title, 2463a6eaa0bSAndreas Gohr ), 2473a6eaa0bSAndreas Gohr 0, 0 2483a6eaa0bSAndreas Gohr ); 2493a6eaa0bSAndreas Gohr $mobile = self::getResizedImgTag( 2503a6eaa0bSAndreas Gohr 'img', 2513a6eaa0bSAndreas Gohr array( 2523a6eaa0bSAndreas Gohr 'class' => 'mobile-only', 253e302d67fSMichael Große 'src' => array('wiki:logo-32x32.png', 'wiki:favicon.png', 'wiki:logo-square.png', 'wiki:logo.png'), 254e17d84d6SAndreas Gohr 'alt' => $title, 2553a6eaa0bSAndreas Gohr ), 2563a6eaa0bSAndreas Gohr 32, 32 2573a6eaa0bSAndreas Gohr ); 2583a6eaa0bSAndreas Gohr 2593a6eaa0bSAndreas Gohr // homepage logo should not link to itself (BITV accessibility requirement) 260e17d84d6SAndreas Gohr if($linkit) { 2613a6eaa0bSAndreas Gohr tpl_link(wl(), $desktop, 'accesskey="h" title="[H]"'); 2623a6eaa0bSAndreas Gohr tpl_link(wl(), $mobile, 'accesskey="h" title="[H]"'); 263e17d84d6SAndreas Gohr } else { 264e17d84d6SAndreas Gohr echo $desktop; 265e17d84d6SAndreas Gohr echo $mobile; 2663a6eaa0bSAndreas Gohr } 2673a6eaa0bSAndreas Gohr } 26884f94641SAndreas Gohr 26984f94641SAndreas Gohr /** 27084f94641SAndreas Gohr * Add the current mode information to the hierarchical breadcrumbs 27184f94641SAndreas Gohr */ 27284f94641SAndreas Gohr public function breadcrumbSuffix() { 27384f94641SAndreas Gohr global $ACT; 27484f94641SAndreas Gohr global $lang; 27584f94641SAndreas Gohr global $INPUT; 27684f94641SAndreas Gohr global $ID; 27784f94641SAndreas Gohr global $conf; 27884f94641SAndreas Gohr global $IMG; 27984f94641SAndreas Gohr if($ACT == 'show') return; 28084f94641SAndreas Gohr 28184f94641SAndreas Gohr // find an apropriate label for the current mode 28284f94641SAndreas Gohr if($ACT) { 28384f94641SAndreas Gohr $label = tpl_getLang('mode_' . $ACT); 28484f94641SAndreas Gohr if(!$label) { 28584f94641SAndreas Gohr if(isset($lang['btn_' . $ACT])) { 28684f94641SAndreas Gohr $label = $lang['btn_' . $ACT]; 28784f94641SAndreas Gohr } else { 28884f94641SAndreas Gohr $label = $ACT; 28984f94641SAndreas Gohr } 29084f94641SAndreas Gohr } 29184f94641SAndreas Gohr } else { 29284f94641SAndreas Gohr // actually we would need to create a proper namespace breadcrumb path here, 29384f94641SAndreas Gohr // but this is the most simplest thing we can do for now 29484f94641SAndreas Gohr if(defined('DOKU_MEDIADETAIL')) { 29584f94641SAndreas Gohr $label = hsc(noNS($IMG)); 29684f94641SAndreas Gohr } else { 29784f94641SAndreas Gohr return; 29884f94641SAndreas Gohr } 29984f94641SAndreas Gohr } 30084f94641SAndreas Gohr 30184f94641SAndreas Gohr if($ACT == 'admin' && $INPUT->has('page')) { 30284f94641SAndreas Gohr $link = wl($ID, array('do' => 'admin')); 30384f94641SAndreas Gohr echo '<bdi> : <a href="' . $link . '"><strong>' . $label . '</strong></a></bdi>'; 30484f94641SAndreas Gohr 30584f94641SAndreas Gohr /** @var \DokuWiki_Admin_Plugin $plugin */ 30684f94641SAndreas Gohr $plugin = plugin_load('admin', $INPUT->str('page')); 30784f94641SAndreas Gohr if(!$plugin) return; 30884f94641SAndreas Gohr 30984f94641SAndreas Gohr $label = $plugin->getMenuText($conf['lang']); 31084f94641SAndreas Gohr } 31184f94641SAndreas Gohr 31284f94641SAndreas Gohr echo '<bdi><span class="curid"> : <strong>' . $label . '</strong></span></bdi>'; 31384f94641SAndreas Gohr } 3142387fd46SAndreas Gohr} 315