1<?php 2/** 3 * DokuWiki Plugin nsindex (Syntax Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Oliver Geisen <oliver@rehkopf-geisen.de> 7 */ 8 9// must be run within Dokuwiki 10if (!defined('DOKU_INC')) die(); 11 12class syntax_plugin_nsindex extends DokuWiki_Syntax_Plugin { 13 /** 14 * @return string Syntax mode type 15 */ 16 public function getType() { 17 return 'substition'; 18 } 19 /** 20 * @return string Paragraph type 21 */ 22 public function getPType() { 23 return 'normal'; 24 } 25 /** 26 * @return int Sort order - Low numbers go before high numbers 27 */ 28 public function getSort() { 29 return 200; 30 } 31 32 /** 33 * Connect lookup pattern to lexer. 34 * 35 * @param string $mode Parser mode 36 */ 37 public function connectTo($mode) { 38 $this->Lexer->addSpecialPattern('{{nsindex[^}]*}}',$mode,'plugin_nsindex'); 39 } 40 41 /** 42 * Handle matches of the nsindex syntax 43 * 44 * @param string $match The match of the syntax 45 * @param int $state The state of the handler 46 * @param int $pos The position in the document 47 * @param Doku_Handler $handler The handler 48 * @return array Data for the renderer 49 */ 50 public function handle($match, $state, $pos, Doku_Handler $handler) { 51 $data = $this->_get_defaults(); 52 53 /** 54 * parse options and override defaults 55 */ 56 $match = explode(',',trim(substr($match,9,-2))); 57 foreach ($match as $m) 58 { 59 if (strstr($m, '=')) { 60 list($opt,$val) = explode('=', $m); 61 } else { 62 $opt = $m; 63 $val = true; 64 } 65 if (array_key_exists($m, $data)) 66 { 67 $data[$opt] = $val; 68 } 69 } 70 71 return $data; 72 } 73 74 /** 75 * Render xhtml output or metadata 76 * 77 * @param string $mode Renderer mode (supported modes: xhtml) 78 * @param Doku_Renderer $renderer The renderer 79 * @param array $data The data from the handler() function 80 * @return bool If rendering was successful. 81 */ 82 public function render($mode, Doku_Renderer $renderer, $data) { 83 if($mode != 'xhtml') return false; 84 85 global $conf; 86 87 // Never cache the result to get fresh info 88 $renderer->info['cache'] = false; 89 90 // Do not add section edit buttons unter group headers 91 $oldmaxecl = $conf['maxseclevel']; 92 $conf['maxseclevel'] = 0; 93 94 // To see the TOC, to not use ~~NOTOC~~ 95 if ($renderer->info['toc']) { 96 $oldmaxtoc = $conf['maxtoclevel']; 97 $conf['maxtoclevel'] = 3; 98 } else { 99 $oldmaxtoc = -1; 100 } 101 102 // Build the list 103 $data = $this->_build_index($data, $renderer); 104 105 // Translate text to HTML for DW page 106 $data = p_render('xhtml', p_get_instructions($data), $_dummy); 107 108 // Append to current page 109 $renderer->doc .= '<div id="nsindex">' ; 110 $renderer->doc .= $data; 111 $renderer->doc .= '</div>' ; 112 113 // restore edit level and TOC 114 $conf['maxseclevel'] = $oldmaxecl; 115 if ($oldmaxtoc == -1) { 116 $conf['maxtoclevel'] = $oldmaxtoc; 117 } 118 119 return true; 120 } 121 122 //------------------------------------------------------------------------// 123 124 /** 125 * Default options for nsindex 126 */ 127 private function _get_defaults() { 128 return array( 129 'nons' => false, // exclude start-page of namespaces found 130 'nopages' => false, // exclude all pages found, include only startpage of sub-namespaces 131 'nogroup' => false, // do not add alpha-index headings in list 132 'notemplate' => false, // omitt pages with names like 'template' or '__template' or '_template' 133 'startns' => '.', // where to start lookup (default is current namespace) 134 ); 135 } 136 137 /** 138 * Build the index from namespace scan 139 */ 140 private function _build_index($opts, &$renderer) { 141 global $conf; 142 global $ID; 143 144 // get content of namespace (pages and subdirs) 145 if ( ! $opts['startns'] || $opts['startns'] == '.') { 146 $ns = getNS($ID); # current namespace (default) 147 } else { 148 $ns = $opts['startns']; 149 resolve_pageid(getNS($ID), $ns, $exists); 150 $ns = getNS($ns); 151 } 152 $data = array(); 153 $nsdir = str_replace(':','/',$ns); 154 search($data,$conf['datadir'],'search_index',array(),$nsdir,1); 155 156 // filter and sort the list 157 $sort = array(); 158 foreach ($data as $i=>$item) { 159 160 if (noNS($item['id']) == $conf['start']) { 161 continue; # ignore index-page of current namespace 162 } 163 164 // get full wikipath and heading of page 165 if ($item['type'] == 'd') { 166 if ($opts['nons']) { 167 continue; # ignore namespace 168 } 169 $wikipath = $item['id'].':'.$conf['start']; 170 $data[$i]['id'] = $wikipath; # change wikipath in data 171 if ($conf['useheading']) { 172 $title = p_get_first_heading($wikipath); 173 } else { 174 $title = ''; 175 } 176 if ( ! $title) { 177 $title = noNS(getNS($wikipath)); 178 } 179 } else { # page found 180 if ($opts['nopages']) { 181 continue; # ignore pages 182 } 183 $pn = noNS($item['id']); 184 if(($pn == 'template' || $pn == '_template' || $pn == '__template') && $opts['notemplate']) { 185 continue; # ignore template pages 186 } 187 $wikipath = $item['id']; 188 $title = p_get_first_heading($wikipath); 189 if ( ! $title) { 190 $title = $pn; 191 } 192 } 193 194 // Check for access rights 195 if(auth_quickaclcheck($wikipath) < AUTH_READ) { 196 continue; # no access for this page, omitt from list 197 } 198 199 // build array for later sort 200 $sortkey = cleanID($title); 201 $sort[$i] = $sortkey; 202 203 // add metadata 204 $data[$i]['title'] = $title; 205 $data[$i]['sortkey'] = $sortkey; 206 $data[$i]['sortgroup'] = substr($sortkey,0,1); 207 } 208 209 // sort the indexed pages 210 asort($sort); 211 212 // build pagesource of list 213 $txt = ''; 214 $current_letter = ''; 215 foreach ($sort as $i=>$sortkey) { 216 $title = $data[$i]['title']; 217 218 // show alpha-groups 219 if ( ! $opts['nogroup']) { 220 $first = strtoupper(substr($data[$i]['sortkey'],0,1)); 221 if ($first != $current_letter) { 222 $current_letter = $first; 223 $txt .= '===== '.$current_letter.' ====='."\n"; 224 } 225 } 226 227 $txt .= ' * [['.$data[$i]['id'].']]'."\n"; 228 } 229 230 return $txt; 231 } 232} 233 234// vim:ts=4:sw=4:et: 235