plugin:pageindex

pageindex plugin by Kite
Bulleted list of pages within a namespace

Last updated on 2006-08-01. Provides Syntax.
No compatibility info given!

Similar to nstoc.

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

    <?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.

     
    plugin/pageindex.txt · Last modified: 2009/10/10 16:28 by laynee
     
    Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
    Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
    WikiForumIRCBugsGitXRefTranslate