Not logged in. · Lost password · Register
Forum: General Help and Support Plugins RSS
Problem with a navigation plugin
Avatar
Scarecrow #1
Member since Dec 2006 · 20 posts
Group memberships: Members
Show profile · Link to this post
Subject: Problem with a navigation plugin
Hi,

I wanted to have a plugin, which adds navigation buttons to my dokuWiki pages, so I made this up:

  1. <?php
  2. /**
  3.   */
  4. if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
  5. if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  6. require_once(DOKU_PLUGIN.'syntax.php');
  7.  
  8. /**
  9. * All DokuWiki plugins to extend the parser/rendering mechanism
  10. * need to inherit from this class
  11. */
  12. class syntax_plugin_prevarrow extends DokuWiki_Syntax_Plugin {
  13.  
  14.     /**
  15.      * return some info
  16.      */
  17.     function getInfo(){
  18.         return array(
  19.         );
  20.     }
  21.  
  22.     function getType(){ return 'substition'; }
  23.     function getPType(){ return 'block'; }
  24.     function getSort(){ return 200; }
  25.     function connectTo($mode) { $this->Lexer->addSpecialPattern("{{prev>.+?}}",$mode,'plugin_prevarrow'); }
  26.  
  27.  /**
  28.    * Handle the match
  29.    */
  30.  function handle($match, $state, $pos, &$handler){
  31.       preg_match("/{{prev>.+?}}>/", $match, $link);
  32.  
  33.       return array($match[0], cleanID($match[0]));
  34.  }   
  35.  
  36.     /**
  37.      * Create output
  38.      */
  39.     function render($mode, &$renderer, $data) {
  40.         global $conf;
  41.         if($mode == 'xhtml'){
  42.             $renderer->doc .= '<p class="plugin_prevarrow"><a href="$match"><img src="'.DOKU_URL.'lib/plugins/prevarrow/recprev.GIF'.$conf['plugin_prevarrow']['image'].'" alt="PREV"/></a></p>';
  43.             return true;
  44.         } else {
  45.             return false;
  46.         }
  47.     }
  48.        
  49. }
  50.  
  51. ?>

The problem however is, it does not do the linking right.
I use the plugin like this:
{{prev>namespace:namespace:page}}
Now it should read the link and put it into the <a href=...> in the renderer, but thats not working.
As I am a complete php beginner I don`t know how to handle this.

A little help would be greatly appreciated
greetings
Scarecrow
Avatar
andi (Administrator) #2
Member since May 2006 · 2448 posts · Location: Berlin Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by Scarecrow:
  1.     function render($mode, &$renderer, $data) {
  2.         global $conf;
  3.         if($mode == 'xhtml'){
  4.             $renderer->doc .= '<p class="plugin_prevarrow"><a href="$match"><img src="'.DOKU_URL.'lib/plugins/prevarrow/recprev.GIF'.$conf['plugin_prevarrow']['image'].'" alt="PREV"/></a></p>';

You're using the variable $match here but it's nowhere defined. You probably want to access $data instead.
Read this if you don't get any useful answers.
Lies dies wenn du keine hilfreichen Antworten bekommst.
Avatar
Scarecrow #3
Member since Dec 2006 · 20 posts
Group memberships: Members
Show profile · Link to this post
Subject: still not right
Thanks for your help!

It did not do the trick yet, but I`m currently playing around with that, so it should work soon I hope :)

Edit: Unfortunately it is still not working as planed, I edited the code like this and added some comments:

  1. function connectTo($mode) { $this->Lexer->addSpecialPattern("{{prev>.+?}}",$mode,'plugin_prevarrow'); }
Here I get the input, eg. {{prev>namespace:page}}
  1.  function handle($match, $state, $pos, &$handler){
  2.       preg_match("/({{prev>)?(.+?)}}/", $match, $data);
then I compare the input with the searchstring    and write the results to $data
  1.       return array($match, $data[2]);
  2. }
then I return the value which matched the second searchstring (.+?), that should be namespace:page
  1.         function render($mode, &$renderer, $data) {
  2.         global $conf;
  3.         if($mode == 'xhtml'){
  4.             
  5.             $renderer->doc .= '<p class="plugin_prevarrow"><a href=doku.php?id=$data><img src="'.DOKU_URL.'lib/plugins/prevarrow/recprev.GIF'.$conf['plugin_prevarrow']['image'].'" alt="PREV"/></a></p>';
  6.             return true;
  7.         } else {
  8.             return false;
  9.         }
  10.     }
Here it should output the graphic with the link doku.php?id=namespace:page, but everything I get is the graphic with the link doku.php?id=$data.
So supposedly I made a (lot of?) mistake somewhere, but I can`t figure out where I understood something wrong.
Could somebody give me another little hint for my problem

Thanks
Scarecrow
This post was edited on 2006-12-14, 14:33 by Scarecrow.
Avatar
Scarecrow #4
Member since Dec 2006 · 20 posts
Group memberships: Members
Show profile · Link to this post
Sorry, but may I bump this thread just once for this problem still persists

Thanks
Scarecrow
Avatar
tobiaseigen #5
Member since Feb 2007 · 21 posts
Group memberships: Members
Show profile · Link to this post
Hi Scarecrow -

did you ever figure this out? I'm interested in having left/up/right type navigation at the bottoms of selected pages in my wiki.

Cheers,

Tobias
Tobias Eigen

Kabissa - Space for Change in Africa
http://www.kabissa.org
Avatar
Kite #6
Member since Mar 2007 · 9 posts · Location: Vancouver, BC, Canada
Group memberships: Members
Show profile · Link to this post
In reply to post #1
Quote by Scarecrow on 2006-12-13, 09:53:
  1.     function connectTo($mode) {
  2.             $this->Lexer->addSpecialPattern("{{prev>.+?}}",$mode,'plugin_prevarrow');
  3.      }
  4.  
  5.  /**
  6.    * Handle the match
  7.    */
  8.  function handle($match, $state, $pos, &$handler){
  9.       preg_match("/{{prev>.+?}}>/", $match, $link);
  10.  
  11.       return array($match[0], cleanID($match[0]));
  12.  }

Your regular expression really needs to have some inner brackets: "/{{prev>(.+)?}}>/" if you want to use preg_match(). Without the ( ) group, your $link never contains just the topic ID you want.  

Your return should not return $match since that is just an input.  It should return $link and only the [1] item since that contains your ( ) group:

return array($link[1], cleanID($link[1]));

 
Quote by Scarecrow on 2006-12-13, 09:53:
  1.     /**
  2.      * Create output
  3.      */
  4.     function render($mode, &$renderer, $data) {
  5.         global $conf;
  6.         if($mode == 'xhtml'){
  7.             $renderer->doc .= '<p class="plugin_prevarrow"><a href="$match"><img src="'.DOKU_URL.'lib/plugins/prevarrow/recprev.GIF'.$conf['plugin_prevarrow']['image'].'" alt="PREV"/></a></p>';
  8.             return true;
  9.         } else {
  10.             return false;
  11.         }
  12.     }

You have several problems here, too.  You do use $match and that should almost certainly be $data.  But, more significantly, you use $match inside single quotes and it is only a literal string there.  I'd tend to write (note: \" for inner quotes):

$renderer->doc .= "<p class= \"plugin_prevarrow \"><a href= \"$match\">...

Your URL mixes the usage of src="'.DOKU_URL.'lib/plugins/prevarrow/recprev.GIF'   and src="'.DOKU_URL.$conf['plugin_prevarrow']['image']. '"' .   I think that should be one or the other.


Another way to write these function would be to all supporting more that one arrow (eventually).  I'm using this code to develop this further, but running into some weird behavior where my output seems to be interpreted further by something later in the process.

  1. function connectTo($mode) {
  2.         $this->Lexer->addSpecialPattern("{{prev>(.+)?}}",$mode,'plugin_prevarrow');
  3.         $this->Lexer->addSpecialPattern("{{next>(.+)?}}",$mode,'plugin_prevarrow');
  4.     }
  5.  /**
  6.    * Handle the match
  7.    */
  8.  function handle($match, $state, $pos, &$handler){
  9.       if (preg_match("/{{prev>(.+)?}}>/", $match, $link)) {
  10.           return array("prev", $link);
  11.       }
  12.       if (preg_match("/{{next>(.+)?}}>/", $match, $link)) {
  13.           return array("next", $link);
  14.       }
  15.  
  16.     function render($mode, &$renderer, $data) {
  17.         global $conf;
  18.         if($mode == 'xhtml'){
  19.                    $found = false;   // just in case we don't handle it
  20.                    // PREV case
  21.                    if($data[0] = 'prev') {
  22.                         $found = true;   // we handle it
  23.             if(is_array($data[1])) {
  24.                     foreach($data1 as $item) {
  25.                         $renderer->doc .= "<p class=\"plugin_prevarrow\">Prev Item:" . $item . "</p>";
  26.                     }
  27.                 } else {
  28.                     $renderer->doc .= "<p class=\"plugin_prevarrow\">Prev:" . $data[1] . "</p>";
  29.                 }
  30.             }
  31.                     }
  32.                    // NEXT case
  33.                    if($data[0] = 'next') {
  34.                         $found = true;   // we handle it
  35.             if(is_array($data[1])) {
  36.                     foreach($data1 as $item) {
  37.                         $renderer->doc .= "<p class=\"plugin_prevarrow\">Next Item:" . $item . "</p>";
  38.                     }
  39.                 } else {
  40.                     $renderer->doc .= "<p class=\"plugin_prevarrow\">Next:" . $data[1] . "</p>";
  41.                 }
  42.             }
  43.                     }
  44.             return $found;
  45.         } else {
  46.             return false;
  47.         }
  48.     }

As I said, this is development code and not working for me now (at 2am PDT).

Kite
Avatar
Kite #7
Member since Mar 2007 · 9 posts · Location: Vancouver, BC, Canada
Group memberships: Members
Show profile · Link to this post
Subject: Navigation Pointers
Ok, so I've got this all working now. 

Just needs a few things to do:
1. Edit conf/local.php to add some lines.
2. add syntax.php to lib/plugins/prevarrow/
3. add style.css to lib/plugins/prevarrow/
4. add your prefered set of pointer graphics to lib/plugins/prevarrow/.

conf/local.php
===============
  1. $conf['plugin_prevarrow']['prev_image'] = 'lib/plugins/prevarrow/prev.gif';
  2. $conf['plugin_prevarrow']['next_image'] = 'lib/plugins/prevarrow/next.gif';
  3. $conf['plugin_prevarrow']['up_image']   = 'lib/plugins/prevarrow/up.gif';
  4. $conf['plugin_prevarrow']['down_image'] = 'lib/plugins/prevarrow/down.gif';
===============

lib/plugins/prevarrow/syntax.php
===============
  1. <?php
  2.  
  3. /*
  4. *
  5. */
  6.  
  7. if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
  8. if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  9.  
  10. require_once(DOKU_PLUGIN.'syntax.php');
  11.  
  12.  
  13. /**
  14. * All DokuWiki plugins to extend the parser/rendering mechanism
  15. * need to inherit from this class
  16. */
  17. class syntax_plugin_prevarrow extends DokuWiki_Syntax_Plugin {
  18.  
  19.     /**
  20.      * return some info
  21.      */
  22.     function getInfo(){
  23.         return array(
  24.             'author' => 'Scarecrow',
  25.             'email'  => '<email>',
  26.             'date'   => '2006-12-13',
  27.             'name'   => 'PrevArrow Navigation',
  28.             'desc'   => 'Display Navigation Links.\nsyntax ~~prev>ID~~ or ~~next>ID~~ .' ,
  29.             'url'    => 'http://forum.dokuwiki.org/thread/483',
  30.         );
  31.     }
  32.  
  33.     function getType(){ return 'substition'; }
  34.  
  35.     function getPType(){ return 'block'; }
  36.  
  37.     function getSort(){ return 200; }
  38.  
  39.     function connectTo($mode) {
  40.                 // Really shouldn't need all of these, but no Regex like (prev|next|up|down) would let me use just one
  41.         $this->Lexer->addSpecialPattern("~~prev>[^~]+~~",$mode,'plugin_prevarrow');
  42.         $this->Lexer->addSpecialPattern("~~next>[^~]+~~",$mode,'plugin_prevarrow');
  43.         $this->Lexer->addSpecialPattern("~~up>[^~]+~~",$mode,'plugin_prevarrow');
  44.         $this->Lexer->addSpecialPattern("~~down>[^~]+~~",$mode,'plugin_prevarrow');
  45.     }
  46.  /**
  47.    * Handle the match
  48.    */
  49.  function handle($match, $state, $pos, &$handler){
  50.       echo "<!-- DEBUG handle() arrow called -->\n";
  51.       if (preg_match("/~~(prev|next|up|down)>([^~]+)~~/", $match, $link)) {
  52.           return  $link;
  53.       }
  54.       return array("match", "nothing", "nothing");
  55.  }   
  56.     /**
  57.      * Create output
  58.      */
  59.     function render($mode, &$renderer, $data) {
  60.         global $conf;
  61.         if($mode == 'xhtml'){
  62. // =======================================
  63. //      $data[0] = original markup text
  64. //      $data[1] = first regex group: prev, next, up, or down
  65. //      $data[2] = ID value of the page to be pointed to
  66. // =======================================
  67.             if(is_array($data)) {
  68.                 $image = DOKU_URL . $conf['plugin_prevarrow'][$data[1] . "_image"];
  69.         $renderer->doc .= "<p class=\"plugin_prevarrow\"><a href=\"" . wl($data[2]) . "\">" .
  70.                             "<img src=\"$image\" alt=\"$data[1]\"/></a>".
  71.                             html_wikilink($data[2]) . "</p>";
  72.             } else {
  73.                  $renderer->doc .= "<p class=\"plugin_prevarrow\">Bad values: " . $data . "</p>";
  74.             }
  75. // =======================================
  76.             return true;
  77.     } else {
  78.             return false;
  79.         }
  80.     }
  81.  
  82. }
  83.  
  84. ?>
===============


This CSS file will need more work to fit your own (or anyone else's) site.

lib/plugins/prevarrow/style.css
===============
p.plugin_prevarrow {
    list-style:disc;
    color:#FF0000;
}
p.plugin_prevarrow a {
    list-style:disc;
    color:#FF0000;
    text-decoration:none;
}
p.plugin_prevarrow a:hover {
    list-style:disc;
    color:#0000FF;
    font-weight:bold;
    text-decoration:underline;
}
p.plugin_prevarrow a:visited {
    list-style:disc;
    color:#00FF00;
    text-decoration:underline;
}
===============

My test page is at http://www.puzzlers.org/dokuwiki/doku.…?id=webmaster:pre….  Obviously, you should test with a page ID that is on your own site.

===============
~~NOCACHE~~

====== Prev Arrow Test ======

===== PREV =====

~~prev>webmaster:start~~


===== NEXT =====

~~next>webmaster:start~~

===== UP =====

~~up>webmaster:test~~

===== DOWN =====

~~down>webmaster:start~~
===============

Hope that helps.

Kite
This post was edited 3 times, last on 2007-03-26, 05:55 by Kite.
Avatar
Kite #8
Member since Mar 2007 · 9 posts · Location: Vancouver, BC, Canada
Group memberships: Members
Show profile · Link to this post
My "version 2" of the above plug-in. 
  • I don't like all the links being paragraph based (they are now <div>).
  • I wanted more of the control to be in the CSS, as well -- I have several classes of <div>. 
  • And I wanted more control over where the links should display since I like the "next" links to be right aligned and "up" to be centered, and the arrow should be properly relative to the text.

Again, just needs a few things to do:

1. add syntax.php to lib/plugins/prevarrow/
2. add style.css to lib/plugins/prevarrow/
3. add your prefered set of pointer graphics to lib/plugins/prevarrow/
4. Add two configuration manager files into  lib/plugins/prevarrow/config
5. If you installed the previous version, remove the lines from conf/loca.php -- the configuration is now integrated into Dokuwiki and there are new files under the plug-in directory.

lib/plugins/prevarrow/syntax.php

===============
  1. <?php
  2.  
  3. /*
  4. *
  5. */
  6.  
  7. if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
  8. if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  9.  
  10. require_once(DOKU_PLUGIN.'syntax.php');
  11.  
  12.  
  13. /**
  14. * All DokuWiki plugins to extend the parser/rendering mechanism
  15. * need to inherit from this class
  16. */
  17. class syntax_plugin_prevarrow extends DokuWiki_Syntax_Plugin {
  18.  
  19.     /**
  20.      * return some info
  21.      */
  22.     function getInfo(){
  23.         return array(
  24.             'author' => 'Scarecrow',
  25.             'email'  => '<email>',
  26.             'date'   => '2006-12-13',
  27.             'name'   => 'PrevArrow Navigation',
  28.             'desc'   => 'Display Navigation Links.\nsyntax ~~prev>ID~~ or ~~next>ID~~ .' ,
  29.             'url'    => 'http://forum.dokuwiki.org/thread/483',
  30.         );
  31.     }
  32.  
  33.     function getType(){ return 'substition'; }
  34.  
  35.     function getPType(){ return 'block'; }
  36.  
  37.     function getSort(){ return 200; }
  38.  
  39.     function connectTo($mode) {
  40.         $this->Lexer->addSpecialPattern("~~prev>[^~]+~~",$mode,'plugin_prevarrow');
  41.         $this->Lexer->addSpecialPattern("~~next>[^~]+~~",$mode,'plugin_prevarrow');
  42.         $this->Lexer->addSpecialPattern("~~up>[^~]+~~",$mode,'plugin_prevarrow');
  43.         $this->Lexer->addSpecialPattern("~~down>[^~]+~~",$mode,'plugin_prevarrow');
  44.     }
  45.  /**
  46.    * Handle the match
  47.    */
  48.  function handle($match, $state, $pos, &$handler){
  49.       echo "<!-- DEBUG handle() arrow called -->\n";
  50.       if (preg_match("/~~(prev|next|up|down)>([^~]+)~~/", $match, $link)) {
  51.           return  $link;
  52.       }
  53.       return array("match", "nothing", "nothing");
  54.  }   
  55.     /**
  56.      * Create output
  57.      */
  58.     function render($mode, &$renderer, $data) {
  59.         global $conf;
  60.         if($mode == 'xhtml'){
  61. // =======================================
  62. //      $data[0] = original markup text
  63. //      $data[1] = first regex group: prev, next, up, or down
  64. //      $data[2] = ID value of the page to be pointed to
  65. // =======================================
  66.              if(is_array($data)) {
  67.                 $dir   = $data[1];                                           // Direction
  68.                 $url   = wl($data[2]);                                       // Just a url
  69.                 $link  = html_wikilink($data[2]);                            // Complete anchor and title
  70.                 $image = DOKU_URL . $this->getConf("prevarrow_" . $dir . "_image");   // Config value
  71.                 $pos   = $this->getConf("prevarrow_" . $dir . "_pos");                // Config value
  72.                 //$renderer->doc .= "<!-- $dir $pos $url $image -->\n";
  73.                 switch($pos) {
  74.                 case 'left':
  75.                 default:
  76.                     $renderer->doc .= "<div class=\"plugin_prevarrow_" . $pos . "\">" .
  77.                             "<a class=\"plugin_prevarrow\" href=\"$url\">" .
  78.                                                 "<img src=\"$image\" alt=\"$data[1]\"/></a>&nbsp;&nbsp;$link</div>\n";
  79.                     break;
  80.                    
  81.                 case 'center':
  82.                     $renderer->doc .= "<div class=\"plugin_prevarrow_" . $pos . "\">" .
  83.                               "<a class=\"plugin_prevarrow\" href=\"$url\">" . "
  84.                                                   "<img src=\"$image\" alt=\"$data[1]\"/></a><br />" .
  85.                           "$link</div>\n";
  86.                     break;
  87.                 case 'right':
  88.                     $renderer->doc .= "<div class=\"plugin_prevarrow_" . $pos . "\">$link&nbsp;&nbsp;" .
  89.                           "<a class=\"plugin_prevarrow\" href=\"$url\">" . "
  90.                                               "<img src=\"$image\" alt=\"$data[1]\"/></a></div>\n";
  91.                     break;
  92.                
  93.                 }
  94.              } else {
  95.                  $renderer->doc .= "<p class=\"plugin_prevarrow\">Bad values: " . $data . "</p>";
  96.              }
  97. // =======================================
  98.              return $true;
  99.         } else {
  100.             return false;
  101.         }
  102.     }
  103.  
  104. }
  105.  
  106. ?>
===============

This CSS file will (still) need more work to fit your own (or anyone else's) site.  Now there are 3 <DIV> styles for controlling each position.  Also, the <a> tags have a class selector assigned.

lib/plugins/prevarrow/style.css
===============
div.plugin_prevarrow_left {
    color:#FF0000;
    margin: 6px;
    text-align: left;
}
div.plugin_prevarrow_right {
    color:#FF0000;
    margin: 6px;
    text-align: right;
}
div.plugin_prevarrow_center {
    color:#FF0000;
    margin: 6px;
    text-align: center;
    vertical-align: middle;
}
a.plugin_prevarrow {
    color:#003399;
    text-decoration:none;
}
a.plugin_prevarrow:hover {
    color:#0099FF;
    font-weight:bold;
    text-decoration:underline;
}
a.plugin_prevarrow:visited {
    color:#009966;
    text-decoration:underline;
}
===============

The newest part of this plugin is that the configuration integrates into Dokuwiki using conf/defaults.php and conf/metadata.php.   Once these are in place, Dokuwiki can manage all the settings using the system's native configuration forms.   It may be possible to clean up the settiing strings ... as long as you also fix the values in syntax.php.

lib/plugins/prevarrow/conf/default.php
===============
  1. <?php
  2. /*
  3. * Default Configuration for the prevarrow plug-in
  4. */
  5.  
  6. $conf['prevarrow_prev_image'] = 'lib/plugins/prevarrow/prev.gif';
  7. $conf['prevarrow_next_image'] = 'lib/plugins/prevarrow/next.gif';
  8. $conf['prevarrow_up_image']   = 'lib/plugins/prevarrow/up.gif';
  9. $conf['prevarrow_down_image'] = 'lib/plugins/prevarrow/down.gif';
  10. $conf['prevarrow_prev_pos']   = 'left';
  11. $conf['prevarrow_next_pos']   = 'right';
  12. $conf['prevarrow_up_pos']     = 'left';
  13. $conf['prevarrow_down_pos']   = 'right';
  14.  
  15.  
  16. ?>
===============

lib/plugins/prevarrow/conf/metadata.php
===============
  1. <?php
  2. /**
  3. * Configuration-manager metadata for indexmenu plugin
  4. *
  5. * @license:    GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author:     Kite <kite@puzzlers.org>
  7. */
  8. $meta['prevarrow_prev_image'] = array('string');
  9. $meta['prevarrow_next_image'] = array('string');
  10. $meta['prevarrow_up_image']   = array('string');
  11. $meta['prevarrow_down_image'] = array('string');
  12. $meta['prevarrow_prev_pos']   = array('multichoice','_choices' => array('left','center','right'));
  13. $meta['prevarrow_next_pos']   = array('multichoice','_choices' => array('left','center','right'));
  14. $meta['prevarrow_up_pos']     = array('multichoice','_choices' => array('left','center','right'));
  15. $meta['prevarrow_down_pos']   = array('multichoice','_choices' => array('left','center','right'));
  16.  
  17. ?>
===============

The accepted syntax is still:
  • ~~prev>ID~~
  • ~~next>ID~~
  • ~~up>ID~~
  • ~~down>ID~~

Kite
Avatar
Kite #9
Member since Mar 2007 · 9 posts · Location: Vancouver, BC, Canada
Group memberships: Members
Show profile · Link to this post
Ok, this is essentially "Revision 3" of this plugin.

If you installed either of the previous versions, you should remove them from your Wiki since the Syntax overlaps a LOT (4 of 5 requests).   This version adds to the accepted syntax:

    * ~~booknav>~~   <-- NEW
    * ~~prev>ID~~
    * ~~next>ID~~
    * ~~up>ID~~
    * ~~down>ID~~

lib/plugins/booknav/syntax.php
==========================
  1. <?php
  2.  
  3. if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
  4. if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  5.  
  6. require_once(DOKU_PLUGIN.'syntax.php');
  7.  
  8. function booknav_sort($a, $b)
  9. {
  10.    if(strcasecmp('start', $a['id']) == 0) { echo "<!-- a['id'] is start -->\n"; return -1; }
  11.    if(strcasecmp('start', $b['id']) == 0) { echo "<!-- b['id'] is start -->\n"; return 1; }
  12.    return strcasecmp($a['id'], $b['id']);
  13. }
  14.  
  15.  
  16. /**
  17. * All DokuWiki plugins to extend the parser/rendering mechanism
  18. * need to inherit from this class
  19. */
  20. class syntax_plugin_booknav extends DokuWiki_Syntax_Plugin {
  21.     /**
  22.      * return some info
  23.      */
  24.     function getInfo(){
  25.         return array(
  26.             'author' => 'kite',
  27.             'email'  => '<kite@puzzlers.org>',
  28.             'date'   => '2007-3-27',
  29.             'name'   => 'Booknav Navigation',
  30.             'desc'   => 'Display Navigation Links.\nsyntax ~~booknav>prevID|upID|nextID~~ or ~~prev>ID~~ or ~~next>ID~~ .  Based on Scarecrow\'s plug-in' ,
  31.             'url'    => 'http://forum.dokuwiki.org/thread/483',
  32.         );
  33.     }
  34.     function getType(){ return 'substition'; }
  35.     function getPType(){ return 'block'; }
  36.     function getSort(){ return 200; }
  37.     function connectTo($mode) {
  38.             $this->Lexer->addSpecialPattern("~~booknav>[^~]*~~",$mode,'plugin_booknav');   // THIS IS THE MAGIC
  39.         $this->Lexer->addSpecialPattern("~~prev>[^~]*~~",$mode,'plugin_booknav');
  40.         $this->Lexer->addSpecialPattern("~~next>[^~]*~~",$mode,'plugin_booknav');
  41.         $this->Lexer->addSpecialPattern("~~up>[^~]*~~",$mode,'plugin_booknav');
  42.         $this->Lexer->addSpecialPattern("~~down>[^~]*~~",$mode,'plugin_booknav');
  43.     }
  44.  /**
  45.    * Handle the match
  46.    */
  47.  function handle($match, $state, $pos, &$handler){
  48.       echo "<!-- DEBUG handle() arrow called -->\n";
  49.       if (preg_match("/~~(booknav|prev|next|up|down)>([^~]*)~~/", $match, $link)) {
  50.           return  $link;
  51.       }
  52.       return array("match", "nothing", "nothing");
  53.  }   
  54.     /**
  55.      * Create output
  56.      */
  57.     function render($mode, &$renderer, $data) {
  58.         global $conf;
  59.         if($mode == 'xhtml'){
  60.              if(is_array($data)) {
  61. //      $data[0] = original markup text
  62. //      $data[1] = first regex group: booknav, prev, next, up, or down
  63. //      $data[2] = ID value of the page to be pointed to
  64.                 if($data[1] <> 'booknav') {
  65.                     $dir   = $data[1];   // page relation
  66.                     if(strlen($data[2]) < 1) { // User gave an ID?
  67.                         $page = $this->_getrelativepage($data[1]);   // Find a page relative to the current one
  68.                     } else {
  69.                         $page = $data[2];                                     // User supplied value
  70.                     }
  71.                     $image = DOKU_URL . $this->getConf("booknav_" . $dir . "_image");   // Config value
  72.                     $pos   = $this->getConf("booknav_" . $dir . "_pos");                // Config value
  73.                    
  74.                     $renderer->doc .=  $this->_build_reference( $dir, $pos$page, $image);
  75.                 } else {
  76.                     $page_prev = $this->_getrelativepage('prev');
  77.                     $page_next = $this->_getrelativepage('next');
  78.                     $renderer->doc .=  "\n<table class=\"plugin_booknav\"><tr>\n\t<td class=\"plugin_booknav\">";
  79.                     if(strlen($page_prev) > 0) {
  80.                         $renderer->doc .=  $this->_build_reference( 'prev',
  81.                             $this->getConf("booknav_prev_pos")
  82.                             $page_prev,
  83.                             DOKU_URL . $this->getConf("booknav_prev_image"));
  84.                     } else {
  85.                         $renderer->doc .=  "<!-- No previous peer page -->";
  86.                     }
  87.                     $renderer->doc .=  "</td>\n\t<td class=\"plugin_booknav\">" .         
  88.                         $this->_build_reference( 'up',
  89.                             $this->getConf("booknav_up_pos")
  90.                             $this->_getrelativepage('up'),
  91.                 DOKU_URL . $this->getConf("booknav_up_image"));
  92.                     $renderer->doc .=  "</td>\n\t<td class=\"plugin_booknav\">";
  93.                     if(strlen($page_next) > 0) {
  94.                         $renderer->doc .=  $this->_build_reference( 'next',
  95.                             $this->getConf("booknav_next_pos")
  96.                             $page_next,
  97.                             DOKU_URL . $this->getConf("booknav_next_image"));
  98.                     } else {
  99.                         $renderer->doc .=  "<!-- No following peer page -->";
  100.                     }
  101.                     $renderer->doc .= "</td>\n</tr></table>\n";
  102.                 }
  103.              } else {
  104.                  $renderer->doc .= "<p class=\"plugin_booknav\">Bad values: " . $data . "</p>";
  105.              }
  106.              return $true;
  107.         } else {
  108.                 return false;
  109.             } // if($mode == 'xhtml')
  110.     }  // render($mode, &$renderer, $data)
  111.     function _build_reference( $dir, $pos$page, $image) {
  112.         $url   = wl($page);                                                 // Just a url
  113.         $link  = html_wikilink($page);                                      // Complete anchor and title
  114.         $result = "<!-- _build_reference(): \$dir=$dir | \$pos=$pos \$page=$page | \$image=$image -->\n";
  115.         switch($pos) {
  116.         case 'left':
  117.         default:
  118.             $result .= "<div class=\"plugin_booknav_" . $pos . "\">" .
  119.                     "<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" " .
  120.                                              "alt=\"$data[1]\"/></a>&nbsp;&nbsp;$link</div>\n";
  121.             break;
  122.         case 'center':
  123.             $result .= "<div class=\"plugin_booknav_" . $pos . "\">" .
  124.                       "<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" alt=\"$data[1]\"/></a><br />" .
  125.                       "$link</div>\n";
  126.             break;
  127.         case 'right':
  128.             $result .= "<div class=\"plugin_booknav_" . $pos . "\">$link&nbsp;&nbsp;" .
  129.                   "<a class=\"plugin_booknav\" href=\"$url\"><img src=\"$image\" alt=\"$data[1]\"/></a></div>\n";
  130.             break;
  131.         } // switch($pos)
  132.         return $result;
  133.     } // _build_reference()
  134.    
  135.     function _getrelativepage($relation) {
  136.         $dir = dirname(wikiFN(getID()));
  137.         $data = array();
  138.         $ns = getNS(getID());
  139.         $current = noNS(getID());
  140.  
  141.         search($data, $dir,'search_index',array('ns' => $ns));
  142.         usort($data, booknav_sort);   // Just makes 'start' always the first page
  143.  
  144.         $found = false;
  145.         foreach($data as $item) {
  146.             $isfile = 0 == strcmp("f", $item["type"]);
  147.             if($isfile && $found) {
  148.                 // find the first file AFTER being found
  149.                 $next = "$ns:" . $item["id"];
  150.                 break;   // we're done now
  151.             }
  152.             if(!$found) {
  153.                 // Once we've found the item, ignore following values
  154.                 // until we find the item, only consider files
  155.                 $match = 0 == strcasecmp($item["id"], $current);
  156.                 $found = ($isfile && $match)// Is this the one we want?
  157.             }
  158.             if($isfile && !$found) {
  159.                 // if the one we want hasn't been found, then track the last for $prev
  160.                 $prev = "$ns:" . $item["id"];         
  161.             }
  162.         }
  163.         switch($relation) {
  164.         case 'up' :
  165.             $result = getNS($ns) . ':start';
  166.             break;
  167.         case 'prev':
  168.             $result = $prev;
  169.             break;
  170.         case 'next':
  171.             $result = $next;
  172.             break;
  173.         default:
  174.             $result = "ns:" . $current;
  175.             break;
  176.         }
  177.         return $result;
  178.     } // _getrelativepage()
  179. }
  180. ?> // class syntax_plugin_booknav
==========================

lib/plugins/booknav/style.css
==========================
div.plugin_booknav_left { color:#FF0000; margin: 6px; text-align: left; }
div.plugin_booknav_right { color:#FF0000; margin: 6px; text-align: right; }
div.plugin_booknav_center { color:#FF0000; margin: 6px text-align: center; vertical-align: middle; }
a.plugin_booknav { color:#003399; text-decoration:none; }
a.plugin_booknav:hover {color:#0099FF;     font-weight:bold; text-decoration:underline; }
a.plugin_booknav:visited { color:#009966; text-decoration:underline; }
table.plugin_booknav { width:100%; }
td.plugin_booknav { width:33%;  }
==========================


lib/plugins/booknav/config/default.php
==========================
  1. <?php
  2. /*
  3. * Default Configuration for the booknav plug-in
  4. */
  5. $conf['booknav_prev_image'] = 'lib/plugins/booknav/prev.gif';
  6. $conf['booknav_next_image'] = 'lib/plugins/booknav/next.gif';
  7. $conf['booknav_up_image']   = 'lib/plugins/booknav/up.gif';
  8. $conf['booknav_down_image'] = 'lib/plugins/booknav/down.gif';
  9. $conf['booknav_prev_pos']   = 'left';
  10. $conf['booknav_next_pos']   = 'right';
  11. $conf['booknav_up_pos']     = 'center';
  12. $conf['booknav_down_pos']   = 'center';
  13. ?>
==========================


lib/plugins/booknav/config/metadata.php
  1. <?php
  2. /**
  3. * Configuration-manager metadata for booknav plugin
  4. *
  5. * @license:    GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author:     Kite <kite@puzzlers.org>
  7. */
  8. $meta['booknav_prev_image'] = array('string');
  9. $meta['booknav_next_image'] = array('string');
  10. $meta['booknav_up_image']   = array('string');
  11. $meta['booknav_down_image'] = array('string');
  12. $meta['booknav_prev_pos']   = array('multichoice','_choices' => array('left','center','right'));
  13. $meta['booknav_next_pos']   = array('multichoice','_choices' => array('left','center','right'));
  14. $meta['booknav_up_pos']     = array('multichoice','_choices' => array('left','center','right'));
  15. $meta['booknav_down_pos']   = array('multichoice','_choices' => array('left','center','right'));
  16. ?>

Of course, you still need the four arrows to match the style of your Wiki.  How to use this in your wiki?   I think that to be globally useful, you need to put some code in your main.php template file.  For example, this code would work:
  1. <?php if ($ACT == 'show') {
  2.     echo "<div id='booknav_plugin'>\n\t";
  3.     echo p_render('xhtml',p_get_instructions("~~booknav>~~"),$info);
  4.     echo "\n</div>\n";
  5. } ?>

oops ... out of space.   /kite
This post was edited 3 times, last on 2007-03-27, 17:02 by Kite.
Avatar
Kite #10
Member since Mar 2007 · 9 posts · Location: Vancouver, BC, Canada
Group memberships: Members
Show profile · Link to this post
Further on "Version 3"...

Its not heavily tested yet, but seems functional.  Feel free to adapt it to your own wiki and needs.  I'd appreciate a note and/or a copy if you add new features.   :-p

 :-/  I see possible issues with cached pages; I don't recall if the entire page is cached, or just the wiki-ish bits from the data/pages.  There may be a need for the plugin to touch the rest of the folder's pages when it finds itself generating a new footer.  Perhaps not.  I'd hate to say add ~~NOCACHE~~ to every page.  This becomes a non-issue if the outline of your site is reasonably stable.

The layout for the ~~booknav>~~ layout uses a table; not perfect and someone better with CSS maybe able to remove that.   Also, currently the parameters to this macro is not used but is possible.  I have the idea of being able to hard code ~~booknav>prevID|upID|nextID~~ under some cases ... its open to use as it passes in as $data[2] just as it did before. 

Another configuration idea may be to allow pages other than than start be the "up page" ... I don't know if anyone uses anything else or mixes them; if you don't mix, just replace 'start' with 'index' or whatever you use.

If (when?) you add customizations to the main.php, you really should add some sort of marking that will let you find them should you need to upgrade.   In my site, all the customizations are functions with a puz_ prefix, for example.  I can search for that prefix and copy each customization to the newest template.

Edited: 29Mar2007

Added one more file to my booknav plugin. This adds vastly improves the text on the configuration form.

lib/plugins/booknav/lang/en/settings.php
  1. <?php
  2. /**
  3. * English language text for booknav plugin
  4. *
  5. * @license:    GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author:     Kite <kite@puzzlers.org>
  7. */
  8. $lang['booknav_prev_image'] = "\"Prev\" arrow image";
  9. $lang['booknav_next_image'] = "\"Next\" arrow image";
  10. $lang['booknav_up_image']   = "\"Up\" arrow image";
  11. $lang['booknav_down_image'] = "\"Prev\" arrow image";
  12. $lang['booknav_prev_pos']   = "Position of \"Prev\" image relative to text";
  13. $lang['booknav_next_pos']   = "Position of \"Next\" image relative to text";
  14. $lang['booknav_up_pos']     = "Position of \"Up\" image relative to text";
  15. $lang['booknav_down_pos']   = "Position of \"Down\" image relative to text";
  16. ?>


Kite
This post was edited on 2007-03-29, 09:37 by Kite.
Avatar
tobiaseigen #11
Member since Feb 2007 · 21 posts
Group memberships: Members
Show profile · Link to this post
Hello Kite -

Thanks much for contributing this! I have installed it on my wiki and it appears to work, though I need to tweak the css and in the meantime will turn it off.

We will be doing a "soft launch" of our wiki tomorrow - stay tuned.

Cheers,

Tobias
Tobias Eigen

Kabissa - Space for Change in Africa
http://www.kabissa.org
Avatar
asdfgqw #12
Member since Oct 2007 · 21 posts
Group memberships: Members
Show profile · Link to this post
deleted by asdfgqw
had a cache problem with this plugin, but it works now. Thanks to the developers.
This post was edited on 2007-10-16, 13:12 by asdfgqw.
Avatar
prami #13
Member since Jan 2008 · 2 posts
Group memberships: Members
Show profile · Link to this post
Hi all

I'm using dokuwiki version 2007-06-26b.
I tried to create the plugin as descrided above.
No I get following error:
Fatal error: Call to undefined function: search() in .../lib/plugins/booknav/syntax.php on line 141
    function _getrelativepage($relation) {
...
        search($data, $dir,'search_index',array('ns' => $ns));
...

I then realized, that following line was missing at top and had to be inserted.
require_once(DOKU_INC.'inc/search.php');

So just for all which get a similar problem.. ;-)

Thx for the plugin.
Wolfgang
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Go to forum
Imprint
This board is powered by the Unclassified NewsBoard software, 20120620-dev, © 2003-2011 by Yves Goergen
Current time: 2014-04-24, 15:32:11 (UTC +02:00)