DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:pageindex

This is an old revision of the document!


pageindex Plugin

Compatible with DokuWiki

No compatibility info given!

plugin Bulleted list of pages within a namespace

Last updated on
2006-08-01
Provides
Syntax

This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.

Similar to dir, nspages, nstoc, pagequery

Tagged with listing, menu, namespace, navigation

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/plugin:pageindex',
        );
    }
 
    /**
     * 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

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'   => '2006-08-01',
            'name'   => 'Page Index',
            'desc'   => 'Presents an index list of files in the current namespace',
            'url'    => 'http://www.dokuwiki.org/plugin:pageindex',
        );
    }
 
    /**
     * 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.


:!: It's not a bug, it's a feature

If you use some templates that make a sitemap on the right or on the left … beware of redefinition of function search_list_index() workaround is vi regexp in the pasted syntax.php :

:%s/search_list_index/search_list_index_whateveryouwant/g 

:!: Possible bug: No unicode (cyrillics, for example) support.


:!: Possible bug: Not obeying config:hidepages.

plugin/pageindex.1565632493.txt.gz · Last modified: 2019-08-12 19:54 by Aleksandr

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki