This is an old revision of the document!
Table of Contents
plugin:pageindex
Compatible with DokuWiki
No compatibility info given!
The missing download url means that this extension cannot be installed via the Extension Manager. Please see Publishing a Plugin on dokuwiki.org. Recommended are public repository hosts like GitHub, GitLab or Bitbucket.
This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.
Usage
You can use one of two tag styles:
- ~~PAGEINDEX=section:namespace~~ ← Lists the specified namespace.
- ~~PAGEINDEX~~ ← Lists the current namespace.
I found that on the http://www.puzzlers.org website, we have sections which get lots of pages over a short time and cross-referencing was a chore since some users aren't as wiki-oriented as others. Now I just add a tag to each page and they automatically update over time.
The list will not include the current page, either, to reduce confusion.
Installation
Put the following code into lib/plugins/pageindex/syntax.php in your DokuWiki site. Then you can add the tags above into any page you want a namespace index.
The Code
Version 1.2
- syntax.php
<?php /** * Plugin page index: index table for pages in a name space * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Kite <Kite@puzzlers.org> * @based_on "externallink" plugin by Otto Vainio <plugins@valjakko.net> */ if(!defined('DOKU_INC')) { define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); } if(!defined('DOKU_PLUGIN')) { define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); } require_once(DOKU_PLUGIN.'syntax.php'); require_once(DOKU_INC.'inc/search.php'); function search_list_index(&$data,$base,$file,$type,$lvl,$opts){ global $ID; //we do nothing with directories if($type == 'd') return false; if(preg_match('#\.txt$#',$file)){ //check ACL $id = pathID($file); if(auth_quickaclcheck($id) < AUTH_READ){ return false; } if($opts['ns'].":$id" <> $ID) { $data[] = array( 'id' => $opts['ns'].":$id", 'type' => $type, 'level' => $lvl ); } } return false; } /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_pageindex extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo(){ return array( 'author' => 'Kite', 'email' => 'kite@puzzlers.org', 'date' => '2009-02-01', 'name' => 'Page Index', 'desc' => 'Presents an index list of files in the current namespace', 'url' => 'http://www.dokuwiki.org/wiki:plugins', ); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } // Just before build in links function getSort(){ return 299; } /** * What about paragraphs? */ function getPType(){ return 'block'; } function connectTo($mode) { $this->Lexer->addSpecialPattern('~~PAGEINDEX[^~]*~~',$mode,'plugin_pageindex'); //$this->Lexer->addSpecialPattern('~~PAGEINDEX~~',$mode,'plugin_pageindex'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = preg_replace("%~~PAGEINDEX(=(.*))?~~%", "\\2", $match); //echo "\n\t<!-- syntax_plugin_pageindex.handle() found >> $match << -->\n"; return $match; } /** * Create output */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ $text=$this->_pageindex($renderer, $data); $renderer->doc .= $text; return true; } return false; } function _pageindex(&$renderer, $data) { global $conf; global $ID; //$renderer->doc .= "\n\n<!-- syntax_plugin_pageindex._pageindex(\$renderer, \"$data\") -->\n"; $parameters = split(';', $data); $ns = cleanID(getNS("$parameters[0]:dummy")); #fixme use appropriate function if(empty($ns)){ $ns = dirname(str_replace(':',DIRECTORY_SEPARATOR,$ID)); // 2007/12/30 Kite - use localized constant if($ns == '.') $ns =''; } //$ns = utf8_encodeFN(str_replace(':',DIRECTORY_SEPARATOR,$ns)); // 2007/12/30 Kite - use localized constant //$ns = utf8_encodeFN($ns); $search_data = array(); // Oct 3, 2006 renamed $data to $search_data for clarity $dir = $conf['datadir']. DIRECTORY_SEPARATOR .str_replace(':',DIRECTORY_SEPARATOR,$ns); // 2007/12/30 Kite - use localized constant $ns = str_replace(DIRECTORY_SEPARATOR,':',$ns); $renderer->doc .= "\n<!-- \$dir = $dir \$ns = $ns -->\n"; search($search_data, // results == renamed $data to $search_data $dir, // folder root 'search_list_index', // handler array('ns' => $ns)); // options // Remove the items not wanted in the list if(is_array($parameters)) { $skipitems = array_slice($parameters, 1); foreach($search_data as $item) { $found = false; // Add ns if user didn't foreach($skipitems as $skip) { $skip = strpos($skip,":") ? $skip : "$ns:$skip"; if($item['id'] == $skip) { $found = true; break; } } if(!$found) { // Pass this one through $checked[] = $item; } else { //$renderer->doc .= "<!-- rejected entry ".$item['id']." -->\n"; } } } if(count($checked)) { // use the filtered data rather than $search_data /* Option to use an HTML List */ $renderer->doc .= html_buildlist($checked, 'idx', 'html_list_index', 'html_li_index'); /* Option to use the PageList plugin */ /* $pages = $checked; $pagelist =& plugin_load('helper', 'pagelist'); if (!$pagelist) return false; // failed to load plugin $pagelist->startList(); foreach ($pages as $page){ $pagelist->addPage($page); } $renderer->doc .= $pagelist->finishList(); */ } else { $renderer->doc .= "\n\t<p>There are no documents to show.</p>\n"; } } // _pageindex() } // syntax_plugin_pageindex
Version 1
<?php /** * Plugin page index: index table for pages in a name space * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Kite <Kite@puzzlers.org> * @based_on "externallink" plugin by Otto Vainio <plugins@valjakko.net> */ if(!defined('DOKU_INC')) { define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); } if(!defined('DOKU_PLUGIN')) { define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); } require_once(DOKU_PLUGIN.'syntax.php'); require_once(DOKU_INC.'inc/search.php'); function search_list_index(&$data,$base,$file,$type,$lvl,$opts){ global $ID; //we do nothing with directories if($type == 'd') return false; if(preg_match('#\.txt$#',$file)){ //check ACL $id = pathID($file); if(auth_quickaclcheck($id) < AUTH_READ){ return false; } if($opts['ns'].":$id" <> $ID) { $data[] = array( 'id' => $opts['ns'].":$id", 'type' => $type, 'level' => $lvl ); } } return false; } /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_pageindex extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo(){ return array( 'author' => 'Kite', 'email' => 'kite@puzzlers.org', 'date' => '2006-08-01', 'name' => 'Page Index', 'desc' => 'Presents an index list of files in the current namespace', 'url' => 'http://www.dokuwiki.org/wiki:plugins', ); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } // Just before build in links function getSort(){ return 299; } /** * What about paragraphs? */ function getPType(){ return 'block'; } function connectTo($mode) { $this->Lexer->addSpecialPattern('~~PAGEINDEX[^~]*~~',$mode,'plugin_pageindex'); //$this->Lexer->addSpecialPattern('~~PAGEINDEX~~',$mode,'plugin_pageindex'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = preg_replace("%~~PAGEINDEX(=(.*))?~~%", "\\2", $match); //echo "\n\t<!-- syntax_plugin_pageindex.handle() found >> $match << -->\n"; return $match; } /** * Create output */ function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ $text=$this->_pageindex($renderer, $data); $renderer->doc .= $text; return true; } return false; } function _pageindex(&$renderer, $data) { global $conf; global $ID; //$renderer->doc .= "\n\n<!-- syntax_plugin_pageindex._pageindex(\$renderer, \"$data\") -->\n"; // New Oct 3, 2006 -- begin $parameters = split(';', $data); // New Oct 3, 2006 -- end $ns = cleanID(getNS("$data:dummy")); #fixme use appropriate function if(empty($ns)){ $ns = dirname(str_replace(':',DIRECTORY_SEPARATOR,$ID)); // 2007/12/30 Kite - use localized constant if($ns == '.') $ns =''; } //$ns = utf8_encodeFN(str_replace(':',DIRECTORY_SEPARATOR,$ns)); // 2007/12/30 Kite - use localized constant //$ns = utf8_encodeFN($ns); $search_data = array(); // Oct 3, 2006 renamed $data to $search_data for clarity $dir = $conf['datadir']. DIRECTORY_SEPARATOR .str_replace(':',DIRECTORY_SEPARATOR,$ns); // 2007/12/30 Kite - use localized constant $ns = str_replace(DIRECTORY_SEPARATOR,':',$ns); $renderer->doc .= "\n<!-- \$dir = $dir \$ns = $ns -->\n"; search($search_data, // results == renamed $data to $search_data $dir, // folder root 'search_list_index', // handler array('ns' => $ns)); // options // New Oct 3, 2006 -- begin // Remove the items not wanted in the list if(is_array($parameters)) { $skipitems = array_slice($parameters, 1); foreach($search_data as $item) { $found = false; foreach($skipitems as $skip) { // Suggested fix: ensures the current namespace $skip = strpos($skip,":") ? $skip : "$ns:$skip"; // Add ns if user didn't if($item['id'] == $skip) { $found = true; break; } } if(!$found) { // Pass this one through $checked[] = $item; } else { //$renderer->doc .= "<!-- rejected entry ".$item['id']." -->\n"; } } } if(count($checked)) { // use the filtered data rather than $search_data $renderer->doc .= html_buildlist($checked, 'idx', 'html_list_index', 'html_li_index'); } else { $renderer->doc .= "\n\t<p>There are no documents to show.</p>\n"; } // New Oct 3, 2006 -- end // if(count($search_data)) { // renamed $data to $search_data // $renderer->doc .= html_buildlist($search_data, // 'idx', // 'html_list_index', // 'html_li_index'); // } else { // $renderer->doc .= "\n\t<p>There are no documents to show.</p>\n"; // } //$renderer->doc .= "\n<!-- leaving syntax_plugin_pageindex._pageindex() -->\n"; } // _pageindex() } // syntax_plugin_pageindex
Updates
Oct 3, 2006
I added a bit of code into the “meat” function that performs a neat bit for me. I want to use a syntax of “show me everything except one or two. That is, I have a default “start” or “index” page that has no real content except a ~~pageindex~~ macro. I want to show all the pages except that start page from other pages. Now I can use: ~~pageindex=namespace;except1;except2~~ to get all the pages in namespace other than except1 or except2.
kite [at] puzzlers [dot] org
Dec 30, 2007
I changed references to '/' to DIRECTORY_SEPARATOR per the 'possible bug' comment below.
kite [at] puzzlers [dot] org
Discussion
Listing of subNamespace
I need also a listing of the namespace under the current namespace. How i have to modify the code? Can you show me an example. Thanks, Johann.
*** syntax.php 2006/12/16 19:27:01 1.1 --- syntax.php 2006/12/16 19:37:06 *************** *** 21,27 **** function search_list_index(&$data,$base,$file,$type,$lvl,$opts){ global $ID; //we do nothing with directories ! if($type == 'd') return false; if(preg_match('#\.txt$#',$file)){ //check ACL $id = pathID($file); --- 21,35 ---- function search_list_index(&$data,$base,$file,$type,$lvl,$opts){ global $ID; //we do nothing with directories ! if($type == 'd') { ! $id = pathID($file); ! if($opts['ns'].":$id" <> $ID) { ! $data[] = array( ! 'id' => $opts['ns'].":$id", ! 'type' => $type, ! 'level' => $lvl ); ! } ! } if(preg_match('#\.txt$#',$file)){ //check ACL $id = pathID($file);
Possible bug?
Thanks for the plugin, it's very handy. But I have to say I guess I found a bug. If working on Windows (I test my websites on Windows but host them on Linux/FreeBSD then) the hard-coded slashes in the code (I mean like that: /) cause the bug. Windows puts backslashes in directory path and the plugin, quite contrary, adds slashes. It works OK until no arguments are specified (just ~~PAGEINDEX~~), but if something like ~~PAGEINDEX=dev;sidebar~~ is tried then it starts telling there are no documents to index. Please replace ALL hard-coded slashes to something platform-independent. Regards, Webmaster.
2007/12/30 I've altered the lines with '/' constants to use the DIRECTORY_SEPARATOR constant so paths should now be more platform independent.
kite [at] puzzlers [dot] org
User Comments
We had to replace the line
// New Oct 3, 2006 -- end $ns = cleanID(getNS("$data:dummy"));
with
// New Oct 3, 2006 -- end $ns = cleanID(getNS("{$parameters[0]}:dummy"));
to make the exclude function work. We also had to specify the full pagename including namespace: prefix to actually exclude the page.
Rüdiger Marwein / Roland Eckert / 21torr.com
Solution to last thing above
One way to avoid having to prefix the name space, is to add one line to the $skipitems loop.
Before snippet:
foreach($skipitems as $skip) { if($item['id'] == $skip) { $found = true; break;
After snippet:
foreach($skipitems as $skip) { $skip = strpos($skip,":") ? $skip : "$ns:$skip"; // Add ns if user didn't if($item['id'] == $skip) { $found = true; break;
Henrik Andreasson.
Bug: after copying the script from the page above I got a PHP error on my next “save page” click. I had to remove the ?>
part of the last line of the script and it functioned since.
It is reported here about this problem in general: php_closing_tags - Stephen (stephen-dot-leedle-at-gmx-dot-de)
I prefer the pagelist plugin for rendering. It's easy to add : Just replace theses lines :
$renderer->doc .= html_buildlist($checked, 'idx', 'html_list_index', 'html_li_index');
by
$pages = $checked; $pagelist =& plugin_load('helper', 'pagelist'); if (!$pagelist) return false; // failed to load plugin $pagelist->startList(); foreach ($pages as $page){ $pagelist->addPage($page); } $renderer->doc .= $pagelist->finishList();
You can set flags too with
$pagelist->setFlags(array("nouser", "desc")); // Just after $pagelist->startList();
I don't know why, but it don't work with “tag” and “comments” flags. Any idea ? (I have both plugins installed)
— Jean-Michel 2008-03-02 18:26
Possible bug
I really like this plugin, but I think I've found a bug. When I create a new page in a namespace, it doesn't appear on the list created by the plugin, but if I make a preview of the page it does appear.
May it be a problem of refreshing?
Ayla 2008-04-06 18:40
try to to a on the page with the ~~PAGEINDEX~~ . Every Page is cached in plain-HTML for a given time if not modified or with that tag.
Possible bug: No unicode (cyrillics, for example) support.