1<?php 2/** 3 * DokuWiki Plugin DocNavigation (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Gerrit Uitslag <klapinklapin@gmail.com> 7 */ 8 9use dokuwiki\Extension\ActionPlugin; 10use dokuwiki\Extension\Event; 11use dokuwiki\Extension\EventHandler; 12 13/** 14 * Add documentation navigation elements around page 15 */ 16class action_plugin_docnavigation extends ActionPlugin 17{ 18 19 /** 20 * Register the events 21 * 22 * @param EventHandler $controller 23 */ 24 public function register(EventHandler $controller) 25 { 26 $controller->register_hook('RENDERER_CONTENT_POSTPROCESS', 'AFTER', $this, 'addtopnavigation'); 27 } 28 29 /** 30 * Add navigation bar to top of content 31 * 32 * @param Event $event 33 */ 34 public function addtopnavigation(Event $event) 35 { 36 global $ACT; 37 38 if ($event->data[0] != 'xhtml' || !in_array($ACT, ['show', 'preview'])) return; 39 40 $event->data[1] = $this->htmlNavigationbar(false) 41 . $event->data[1] 42 . $this->htmlNavigationbar(true); 43 } 44 45 /** 46 * Return html of navigation elements 47 * 48 * @param bool $linktoToC if true, add referer to ToC 49 * @return string 50 */ 51 private function htmlNavigationbar($linktoToC) 52 { 53 global $ID; 54 global $ACT; 55 $data = null; 56 if ($ACT == 'preview') { 57 // the RENDERER_CONTENT_POSTPROCESS event is triggered just after rendering the instruction, 58 // so syntax instance will exists 59 /** @var syntax_plugin_docnavigation_pagenav $pagenav */ 60 $pagenav = plugin_load('syntax', 'docnavigation_pagenav'); 61 if ($pagenav instanceof syntax_plugin_docnavigation_pagenav) { 62 $data = $pagenav->getPageData($ID); 63 } 64 } else { 65 $data = p_get_metadata($ID, 'docnavigation'); 66 } 67 68 $out = ''; 69 if (!empty($data)) { 70 if ($linktoToC) { 71 $out .= '<div class="clearer"></div>'; 72 } 73 74 $out .= '<div class="docnavbar' . ($linktoToC ? ' showtoc' : '') . '"><div class="leftnav">'; 75 if ($data['previous']['link']) { 76 $out .= '← ' . $this->htmlLink($data['previous']); 77 } 78 $out .= ' </div>'; 79 80 if ($linktoToC) { 81 $out .= '<div class="centernav">'; 82 if ($data['toc']['link']) { 83 $out .= $this->htmlLink($data['toc']); 84 } 85 $out .= ' </div>'; 86 } 87 88 $out .= '<div class="rightnav"> '; 89 if ($data['next']['link']) { 90 $out .= $this->htmlLink($data['next']) . ' →'; 91 } 92 $out .= '</div></div>'; 93 } 94 return $out; 95 } 96 97 /** 98 * Build nice url title, if no title given use original link with original not cleaned id 99 * 100 * @param array $link with: 'link' => string full page id, 'title' => null|string, 'rawlink' => string original not cleaned id, 'hash' => string 101 * @return string 102 */ 103 protected function htmlLink($link) { 104 /** @var Doku_Renderer_xhtml $Renderer */ 105 static $Renderer = null; 106 if (is_null($Renderer)) { 107 $Renderer = p_get_renderer('xhtml'); 108 } 109 110 $title = $this->getTitle($link, $Renderer); 111 $id = ':' . $link['link'] . '#' . $link['hash']; 112 return $Renderer->internallink($id, $title, null, true); 113 } 114 115 /** 116 * Build nice url title, if no title given use original link with original not cleaned id 117 * 118 * @param array $link with: 'link' => string full page id, 'title' => null|string, 'rawlink' => string original not cleaned id, 'hash' => string 119 * @param Doku_Renderer_xhtml $Renderer 120 * @return string 121 */ 122 protected function getTitle($link, $Renderer) 123 { 124 if ($link['title'] === null) { 125 $defaulttitle = $Renderer->_simpleTitle($link['rawlink']); 126 return $Renderer->_getLinkTitle(null, $defaulttitle, $isImage, $link['link']); 127 } 128 return $link['title']; 129 } 130} 131