(by Marc Wäckerlin, marc [at] waeckerlin [dot-org])
If you like a site navigation bar, that looks similar to what you see in the Index, then read ahead to find out, how I added one. You also get an arrow to the right and to the left: The arrow to the right leads you to the next page. The arrow to the left not really, but more or less to the previous page (if you are on the top of the actual namespace (=directory) it leads you to the top of the index page of the upper namespace-sibling). Also a <link/>-tag is inserted for rel="next" and rel="previous".
Disadvantage: No caching, scanning the directory every time.
Main difference to the Index: When you click on a directory name, it opens the tree, but the directory itself has no associated page. I changed this: Every directory (which is a namespace) contains a page named 00 Index, which is opened, when you click on the directory itself.
If I want a given sort order of the pages inside a directory, I name the pages like: 01 First Page, 02 Second Page, and so on. The same trick I used by naming the index pages 00 Index.
In the templates main.php (e.g. lib/tpl/default/main.php) change the following:
On the very top, after the long header comment, after the <!DOCTYPE...-line, add the following:
function build_navigation_list($ns) { require_once(DOKU_INC.'inc/search.php'); global $conf; global $ID; $dir = $conf['datadir']; $ns = cleanID($ns); #fixme use appropriate function if(empty($ns)){ $ns = dirname(str_replace(':','/',$ID)); if($ns == '.') $ns =''; } $ns = utf8_encodeFN(str_replace(':','/',$ns)); $data = array(); search($data, $conf['datadir'] ,'search_nav_index', array('ns' => $ns)); return $data; } function html_navigation($data) { print html_buildlist($data, 'idx', 'html_navigation_ref', 'html_navigation_li'); } function html_navigation_ref($item) { if ($item['type']=='d') $item['id'] .= ':00_index'; global $ID; $ret = ''; $base = ':'.$item['id']; $base = substr($base,strrpos($base,':')+1); if ($item['id']!=$ID) $ret .= html_wikilink(':'.$item['id']); else { require_once(DOKU_INC.'inc/parser/xhtml.php'); static $xhtml_renderer = NULL; if (is_null($xhtml_renderer)) $xhtml_renderer = new Doku_Renderer_xhtml(); $name=$xhtml_renderer ->_getLinkTitle(NULL, $xhtml_renderer->_simpleTitle($item['id']), $isImage, $item['id']); $ret .= '<span class="hereiam">'.$name.'</span>'; } return $ret; } function html_navigation_li($item){ if($item['type'] == "f"){ return '<li class="level'.$item['level'].'">'; }elseif($item['open']){ return '<li class="open">'; }else{ return '<li class="closed">'; } } function search_nav_index(&$data, $base, $file, $type, $lvl, $opts) { $return = true; $item = array(); if ($type == 'd' && !preg_match('#^'.$file.'(/|$)#','/'.$opts['ns'])) { //add but don't recurse $return = false; } elseif($type == 'f' && !preg_match('#\.txt$#',$file)) { //don't add return false; } $id = pathID($file); $base = substr($id,strrpos($id,':')+1); if ($base=="00_index" && $base!=$id) return false; if ($base=="playground") return false; if ($base=="diskussion") return false; //check hidden if($type=='f' && isHiddenPage($id)){ return false; } //check ACL if($type=='f' && auth_quickaclcheck($id) < AUTH_READ){ return false; } $data[]=array( 'id' => $id, 'type' => $type, 'level' => $lvl, 'open' => $return ); return $return; }
After <?php tpl_metaheaders()?> and the following <link rel="shortcut icon"...-line add:
<?php if ($conf['navigation']) { $NAVIGATION_DATA = build_navigation_list($ID); $PREVIOUS = ''; $NEXT = ''; foreach ($NAVIGATION_DATA as $i => $item) { if ($item['id'].(($item['type']=='d')?':00_index':'')==$ID) { if ($i>0) { $PREVIOUS = $NAVIGATION_DATA[$i-1]['id'] .(($NAVIGATION_DATA[$i-1]['type']=='d')?':00_index':''); print '<link rel="previous" href="'.wl($PREVIOUS).'" />'; } if (isset($NAVIGATION_DATA[$i+1])) { $NEXT = $NAVIGATION_DATA[$i+1]['id'] .(($NAVIGATION_DATA[$i+1]['type']=='d')?':00_index':''); print '<link rel="next" href="'.wl($NEXT).'" />'; } break; } } } ?>
And after the <div class="page">-line, add:
<?php if ($conf['navigation'] && $ACT == 'show') { ?> <div class="navigation"> <div style="float: right; padding-right: 1em;"> <?php if ($PREVIOUS!="") print html_wikilink(':'.$PREVIOUS, "←") ?> <?php if ($NEXT!="") print html_wikilink(':'.$NEXT, "→") ?> </div> <div class="title"> Navigation </div> <div class="nav" style="clear: both"> <?php html_navigation($NAVIGATION_DATA); ?> </div> </div> <?php } ?>
Add the following code to your template's design.css (e.g. lib/tpl/default/design.css):
div.navigation{ margin-left: 2em; margin-top: 1.2em; margin-bottom: 0; float: right; width: 200px; font-size: 80%; clear:both; } div.navigation div.title { padding: 3px; border: 1px solid __dark__; background-color: __medium__; text-align: left; font-weight:bold; margin-bottom: 2px; } div.navigation div.nav { border: 1px solid __dark__; background-color: __white__; text-align: left; padding-top: 0.5em; padding-bottom: 0.7em; } div.navigation div.nav ul { list-style-type: none; list-style-image: none; line-height: 1.2em; margin: 0; padding: 0; padding-left: 1em; } div.navigation div.nav ul * { list-style-type: none; list-style-image: none; } div.navigation div.nav ul li { background: transparent url(images/tocdot2.gif) 0 0.6em no-repeat; padding-left:0.4em; } div.navigation div.nav * a { color: __extern__; text-decoration:none; } div.navigation div.nav * a:hover { color: __black__; text-decoration:underline; }
Enable the navgation bar by adding the following to conf/local.php:
$conf['useheading'] = 1; $conf['navigation'] = 1;