IndexTemplate

Note: The recipes here are for PmWiki versions 0.6 and 1.0 only. For PmWiki 2.0 recipes, see Cookbook.


Goal

Index script to automatically add index of all pages. Similar to 'action=search' but formatted differently.

Installation

Download code below and place in local/ directory
Attach:DTIndex.php
add 'include_once("local/DTIndex.php"); to local.php

-should now be 'config.php', not 'local.php'
-and line can be 'include_once("DTIndex.php");'
-Kibitzer 18 June 2004

When an index is required add [[$Index]] on page. Can also get Index local to the group by using [[$Indexgroup]]

Example

Output will be similar to...

  A B C D E ... X Y Z

 A
     AnyPageName (Group)
 B
 C
 D   DarrenHomePage (Darren)
 etc...

A Standalone version is available, DTIndexExample, this is designed with non editable pages/groups in mind as manual updates required.

Comments, Bugs

It's a nice script and I am using it to index a list of book and I notice it also lists unexpected pages such as RecentChanges (under R) or GroupHeader (under G). So I added a configuration parameter in order to prevent these special pages to show up in the index.

At the beginning of the script, I added ( not exhaustive ) :

  $ignore_pages = array('GroupAttributes','GroupHeader','GroupFooter','HomePage','RecentChanges','RecentUploads');

Then I wrapped the chunk of code after $l_title = FmtPageName('$Title',$pagefile); with the following code :

  if ( !in_array( $l_title, $ignore_pages ) ) {
       $l_key = substr($l_title,0, 1);
        more code 
       $DTIndexArray[$l_key][] = $pagef;
  }

Note that you have to do that in both function DTIndexAll() and function DTIndexGroup()

Gilles, 5-Nov-2003

hej gilles - i now have the same problem that you had - but i'm not quite familiar with php. i always get a lot of errors when trying to apply your code: " Warning: Wrong datatype for second argument in call to in_array in c:\apache\htdocs\pmwiki\local\DTIndex.php on line 42 " . line 42 is: if ( !in_array( $l_title, $ignore_pages ) ) {

what to do ? i really need this feature . . .

simon, 4-jan-2004

I took the liberty to make some changes to the script see the change log: Example

  

<?php

/* 
    Copyright 2003 Darren Turland.

    This script provides an Index of pages for PmWiki. Similar to $search
    without any arguments.  Layout is different.

    A B C D E ....  X Y Z
    A
      AllPages.. (PmWiki)
    B
    C
    D 
      DarrenPage (Darren)
    etc..

    include_once("local/DTIndex.php"); in local.php

    then add [[$Index]] where-ever you require Index of all pages.
    Change Log:
    04-01-2004 bram-a-t-brambring-d-o-t-nl : i
           Removed DTIndexGroup, adjusted DTIndexAll to handle this
           Removed FmtPageName from DTIndexShow ( already done in DTIndexAll )
           Disabled display of unused characters
           Display in three columns



*/

SDV($InlineReplacements['/\\[\\[\\$Indexgroup\\]\\]/e'], "DTIndexAll('group')");
SDV($InlineReplacements['/\\[\\[\\$Index\\]\\]/e'], "DTIndexAll('')");

function DTIndexAll($group)
{
  global $WikiLibDirs;
  $ignore_pages = array('GroupAttributes','GroupHeader','GroupFooter',
                        'StartPagina','RecentChanges','Index','Log',
                        'PageFooter','PageHeader','SearchWiki');

  if ( $group ) {
   global $pagename;
   $group=FmtPageName('$Group', $pagename);
  }

  #Remove the comments if you want all characters in the index
  #for($l_loop=65;$l_loop<65+26;$l_loop++) 
  #  $DTIndexArray[chr($l_loop)] = "";

  foreach($WikiLibDirs as $dir) {
    $dfp = opendir($dir); if (!$dfp) continue;
    while (($pagefile=readdir($dfp))!=false) {

       $d1=FmtPageName('$Group',$pagefile);
       if ($d1 && ! ($group && ($group != $d1))) {
         $l_title = FmtPageName('$Title',$pagefile);
         if ( !in_array( $l_title, $ignore_pages ) ) {
	   $l_key = substr($l_title,0, 1);

	   $pagef = array();
	   $pagef['Title'] = FmtPageName('$Titlespaced',$pagefile);
           if ( ! $group ) {
	     $pagef['Group'] = FmtPageName('$Group',$pagefile);
           }
	   $pagef['Url'] = FmtPageName('$PageUrl',$pagefile);
	   $DTIndexArray[$l_key][] = $pagef;
         }
       }
    }
    closedir($dfp);
  }
  DTIndexShow($DTIndexArray);
}



function DTIndexShow($DTIndexArray) 
{
  print "<table width=90%><tr><th colspan=3>";
  print "<font size='+1'>";
  ksort($DTIndexArray,SORT_STRING );
  foreach(array_keys($DTIndexArray) as $fred) {
      print "<a href=\"#$fred\" >$fred</a>&nbsp;&nbsp;";
  }
  print "</font>";
  print "<tr>";
  $length=ceil(count($DTIndexArray)/3);
  $row=$length;
  foreach(array_keys($DTIndexArray) as $fred) {
    if ( $row >= $length  ) {
      print "<td valign=top>";
      $row=0;
    }
    $row++;
    if (is_array($DTIndexArray[$fred])) {
      print "<br /><a name=\"$fred\" id=\"$fred\"></a>";
      print "<strong><font size='+1'>$fred</font></strong>";
      sort($DTIndexArray[$fred['Title']]);  
      foreach($DTIndexArray[$fred] as $item) {
        print "<br />&nbsp;&nbsp;  " ;
        print "<a href=\"";
        print $item['Url'];
        print "\" >";
        print $item['Title'];
        print "</a>";
	if ($item['Group']) {
          print " ( ";
          print $item['Group'];
          print " )";
	}
      }
    }
  }
 print "</table>";
}

?>

bram 04-01-2004


I made a couple changes when I used bram's version on my site. First of all, depending on what pages you are ignoring, it's possible to have an index tag that doesn't return any pages. This causes ugly looking errors. So, I added the following line to the very start of the DTIndexShow function:

  
function DTIndexShow($DTIndexArray)
{
  if (!$DTIndexArray) return;
...

Secondly, I wanted individual groups to be able to add ignored pages. In order to accomplish this, I made the following changes (note the $IndexIgnorePages variable and the two if statements at the bottom):

  
$IndexIgnorePages = array();
function DTIndexAll($group)
{
  global $WikiLibDirs;
  $ignore_pages = array('GroupAttributes','GroupHeader','GroupFooter',
                        'StartPagina','RecentChanges','Index','Log',
                        'PageFooter','PageHeader','SearchWiki');
  global $IndexIgnorePages;

  if ( $group ) {
    global $pagename;
    $group=FmtPageName('$Group', $pagename);
  }

  #Remove the comments if you want all characters in the index
  #for($l_loop=65;$l_loop<65+26;$l_loop++)
  #  $DTIndexArray[chr($l_loop)] = "";

  foreach($WikiLibDirs as $dir) {
    $dfp = opendir($dir); if (!$dfp) continue;
    while (($pagefile=readdir($dfp))!=false) {

      $d1=FmtPageName('$Group',$pagefile);
      if ($d1 && ! ($group && ($group != $d1))) {
        $l_title = FmtPageName('$Title',$pagefile);
        if ( !in_array( $l_title, $ignore_pages ) ) {
          if ($group && $IndexIgnorePages[$group]) {
            if (in_array($l_title, $IndexIgnorePages[$group])) {
              continue;
            }
          }
...

Once that was in place, I could use the following commands in my local/MyGroup.php file:

  
global $IndexIgnorePages;
$IndexIgnorePages['MyGroup'] = array('HomePage', 'SideBar');

--Andrew Batishko 26-Aug-2004


I changed:

 $DTIndexArray[$l_key][] = $pagef;

To:

 if ( ( ! $DTIndexArray ) || ( ! $DTIndexArray[$l_key] ) || ( ! in_array($pagef, $DTIndexArray[$l_key] ) ) )
     $DTIndexArray[$l_key][] = $pagef;

And it no longer doubly includes pages which are in both wiki.d and wikilib.d (such as the sidebar).

--mrg 11/08/2004


Attach:DTIndex-JC.php
I created a standards-compliant version which makes use of unordered lists for the page names and headers for the index letters. [(approve links) edit diff]. --[(approve links) edit diff]


[(approve links) edit diff] may have double entries
Reason is concationation of wiki.d | wikibak.d | wikilib.d, WebMenu must be in wiki.d (Web Menu)

Patrick Ogay 23-Dec-2003

Contributors

  • Darren Turland - Initial template (17th Oct 2003)
  • Darren Turland - Added script to generate index (19th Oct 2003)
  • Darren Turland - Added [[$Indexgroup]] syntax (20th Oct 2003)

Questions

  • As i undestand it, one has to fill this form manually! Can we make it automatic? IMHO, it's faster to do an empty search action as in Index (which, as you know, can be limited to a single Group). Answer: Have added auto version.
  • Fantastic, thank you. A quick request for a change: can we have it create columns, and skip unused letters?

You may want to give DTIndexSkipEmpty.zip a try, it summarizes all unused letters. Darren, feel free to take this and incorparate it into your code if you like. pmwiki-2.2.138 -- Last modified by {{mrg}}?

from IP: 85.171.160.186 ip should be disabled by default for security reasons