plugin:navilevel
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
plugin:navilevel [2009-05-14 20:00] – tm | plugin:navilevel [2018-06-04 23:36] (current) – Klap-in | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== navilevel Plugin ====== | ||
+ | |||
+ | ---- plugin ---- | ||
+ | description: | ||
+ | author | ||
+ | email : thanos.massias@gmail.com | ||
+ | type : syntax | ||
+ | lastupdate : 2007-06-15 | ||
+ | compatible : 2012-10-13 | ||
+ | depends | ||
+ | conflicts | ||
+ | similar | ||
+ | tags : navigation, menu, namespace | ||
+ | |||
+ | downloadurl: | ||
+ | ---- | ||
+ | |||
+ | This plugin takes as input a list of internal links and, according to the page that hosts it, | ||
+ | selectively displays a subset of them as an unordered list (UL). The order of | ||
+ | the original input is kept but only 'low level' links, ' | ||
+ | ' | ||
+ | The selection is based on comparing the path of the hosting page to the paths | ||
+ | of the links in the data list. This should be helpful for sites that have a | ||
+ | rather deep, tree-like structure. | ||
+ | |||
+ | The problem I tried to solve is how to provide easy navigation for a site with lots | ||
+ | of pages arranged in a namespace-based tree. Before that I experimented with per-namespace | ||
+ | sidebar pages but I'd need more than a dozen of them. Now I only have one sidebar page, but | ||
+ | depending on the current main page, a different subset of the navigation tree gets displayed. | ||
+ | |||
+ | |||
+ | I use | ||
+ | < | ||
+ | $conf[' | ||
+ | </ | ||
+ | and in the page containing the plugin data, I also use | ||
+ | < | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | I tried it with DokuWiki versions DokuWiki-2006-03-09 up to DokuWiki-2012-10-13 “Adora Belle”. | ||
+ | |||
+ | ===== In Action ===== | ||
+ | |||
+ | You can see this plugin in action at [[http:// | ||
+ | (the page is in Greek - sorry, but I currently have no publicly available example in English). | ||
+ | As you might guess, from the above URL, it is about a product line of some company. | ||
+ | Feel free to navigate up and down this URL and see how the sidebar changes. | ||
+ | There is only one '' | ||
+ | |||
+ | ===== Releases ===== | ||
+ | |||
+ | The current release is #5 from 2007-06-14. | ||
+ | |||
+ | ===== New features of ver. 2007-06-14 ===== | ||
+ | |||
+ | Release ver. 2007-06-14 supports a | ||
+ | < | ||
+ | : | ||
+ | </ | ||
+ | syntax. | ||
+ | |||
+ | In this way you may have some text before (i.e. ' | ||
+ | |||
+ | No formatting/ | ||
+ | |||
+ | Note that, there was a change from version #4 on how this works. | ||
+ | |||
+ | Release version 2007-06-14 also has a new feature. If the page that calls the plugin (or the " | ||
+ | |||
+ | ==== Issues with older releases ==== | ||
+ | |||
+ | * release #1 created invalid HTML | ||
+ | * release #2 was targeted to sites using start pages (with the same name) on each namespace. | ||
+ | * release #3 needed better configuration options. | ||
+ | * release #4 had no serious issues but lacked some functionality. | ||
+ | |||
+ | |||
+ | ===== Usage ===== | ||
+ | |||
+ | You must first design your sitemap. | ||
+ | |||
+ | There must be a 1st level link (located in the root namespace) as the 1st argument of the plugin. This typical will be your [[: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | : | ||
+ | . | ||
+ | . | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | The rest of the links must depict your navigation tree and for each link a parent (lower level) link must exist. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | This is right (use '' | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :index | ||
+ | :a:index | ||
+ | :a:b:index | ||
+ | : | ||
+ | : | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | This is wrong ('': | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :index | ||
+ | :a:index | ||
+ | : | ||
+ | : | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | This is right (use '' | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :a | ||
+ | :a:b | ||
+ | :c | ||
+ | :c:d | ||
+ | :c:d:e | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | This is wrong ('': | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :a | ||
+ | :a:b | ||
+ | :c:d | ||
+ | :c:d:e | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | If your site is using start pages (with the same name) on each namespace then then you should edit '' | ||
+ | < | ||
+ | $lowlevel = 2; | ||
+ | </ | ||
+ | |||
+ | |||
+ | If you don't base your site on a scheme where you use the same [[: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :a | ||
+ | :a:b | ||
+ | :a:b:c | ||
+ | :d | ||
+ | :d:e | ||
+ | :d:e:f | ||
+ | :d:e:g | ||
+ | :d:e:g:h | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | |||
+ | Then the default setting | ||
+ | < | ||
+ | $lowlevel = 1; | ||
+ | </ | ||
+ | will work. | ||
+ | |||
+ | |||
+ | ===== Example ===== | ||
+ | |||
+ | Insert something like this: | ||
+ | |||
+ | < | ||
+ | < | ||
+ | :index | ||
+ | :i:index | ||
+ | :i:a:index | ||
+ | :i:b:index | ||
+ | :h:index | ||
+ | :h:c:index | ||
+ | :h:d:index | ||
+ | : | ||
+ | :h:e:index | ||
+ | :h:f:index | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | :h:g:index | ||
+ | :h:m:index | ||
+ | :h:n:index | ||
+ | :h:r:index | ||
+ | :j:index | ||
+ | :j:c:index | ||
+ | :j:d:index | ||
+ | :j:e:index | ||
+ | :j:r:index | ||
+ | :k:index | ||
+ | :k:l:index | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | </ | ||
+ | ~~NOCACHE~~ | ||
+ | </ | ||
+ | |||
+ | in the pages: | ||
+ | < | ||
+ | :h:index | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | :h:f:index | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | : | ||
+ | </ | ||
+ | and see the different results, depending on the page that hosts it. | ||
+ | |||
+ | |||
+ | The plugin will try to create a reasonable navigation tree based on the current page. | ||
+ | |||
+ | ===== Installation ===== | ||
+ | |||
+ | Search and install the plugin using the [[plugin: | ||
+ | |||
+ | * [[http:// | ||
+ | | ||
+ | After installing it you may have to edit '' | ||
+ | |||
+ | Alternatively, | ||
+ | |||
+ | <code php><? | ||
+ | /** | ||
+ | | ||
+ | * | ||
+ | * Roland Hellebart' | ||
+ | | ||
+ | * | ||
+ | | ||
+ | * | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | |||
+ | if(!defined(' | ||
+ | if(!defined(' | ||
+ | require_once(DOKU_PLUGIN.' | ||
+ | |||
+ | /** | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | class syntax_plugin_navilevel extends DokuWiki_Syntax_Plugin { | ||
+ | |||
+ | | ||
+ | function getInfo(){ | ||
+ | return array( | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | | ||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function getType(){ | ||
+ | return ' | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function getAllowedTypes() { | ||
+ | return array(' | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function getPType(){ | ||
+ | return ' | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function getSort(){ | ||
+ | return 203; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function connectTo($mode) { | ||
+ | $this-> | ||
+ | } | ||
+ | | ||
+ | function postConnect() { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function handle($match, | ||
+ | switch ($state) { | ||
+ | case DOKU_LEXER_ENTER : | ||
+ | break; | ||
+ | case DOKU_LEXER_MATCHED : | ||
+ | break; | ||
+ | case DOKU_LEXER_UNMATCHED : | ||
+ | break; | ||
+ | case DOKU_LEXER_EXIT : | ||
+ | break; | ||
+ | case DOKU_LEXER_SPECIAL : | ||
+ | break; | ||
+ | } | ||
+ | return array($match, | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | | ||
+ | */ | ||
+ | function render($mode, | ||
+ | // You may have to configure $rellevel to suite your site | ||
+ | // | ||
+ | // $lowlevel = 1; --> sites not based on per-namespace start pages (default) | ||
+ | // $lowlevel = 2; --> sites based on per-namespace start pages | ||
+ | // | ||
+ | $lowlevel = 1; | ||
+ | |||
+ | global $ID; | ||
+ | global $ullevellast; | ||
+ | $linklineID = ':' | ||
+ | // In case you want the plugin to work correctly within a sidebar add the | ||
+ | // following two lines in '/ | ||
+ | // --------------------- | ||
+ | // global $PPID; | ||
+ | // $PPID = $ID; | ||
+ | // --------------------- | ||
+ | global $PPID; | ||
+ | if (' | ||
+ | if ($ID != $PPID){ | ||
+ | $linklineID = ':' | ||
+ | } | ||
+ | } | ||
+ | $partsID = explode(':', | ||
+ | $countpartsID = count($partsID); | ||
+ | |||
+ | $showall = 0; | ||
+ | if (($countpartsID == 2) && ($partsID[1] == ' | ||
+ | $showall = 1; | ||
+ | } | ||
+ | |||
+ | if($mode == ' | ||
+ | switch ($data[1]) { | ||
+ | case DOKU_LEXER_ENTER : | ||
+ | $renderer-> | ||
+ | break; | ||
+ | | ||
+ | case DOKU_LEXER_MATCHED : | ||
+ | break; | ||
+ | | ||
+ | case DOKU_LEXER_UNMATCHED : | ||
+ | $content = $data[0]; | ||
+ | |||
+ | // clean up the input data | ||
+ | // clear any trailing or leading empty lines from the data set | ||
+ | $content = preg_replace("/ | ||
+ | $content = preg_replace("/ | ||
+ | |||
+ | // Not sure if PHP handles the DOS \r\n or Mac \r, so being paranoid | ||
+ | // and converting them if they exist to \n | ||
+ | $content = preg_replace("/ | ||
+ | $content = preg_replace("/ | ||
+ | $result = $this-> | ||
+ | |||
+ | $ullevellast = 0; | ||
+ | | ||
+ | foreach ($result as $input){ | ||
+ | $arrinput = explode(' | ||
+ | $linkline = $arrinput[0]; | ||
+ | $linkline = trim($linkline); | ||
+ | $linktext_before = $arrinput[1]; | ||
+ | $linktext_before = trim($linktext_before); | ||
+ | $linkname = $arrinput[2]; | ||
+ | $linkname = trim($linkname); | ||
+ | $linktext_after = $arrinput[3]; | ||
+ | $linktext_after = trim($linktext_after); | ||
+ | if (strlen($linkline) > 0) { | ||
+ | $linkline = cleanID($linkline); | ||
+ | if (substr($linkline, | ||
+ | $linkline = ':' | ||
+ | } | ||
+ | |||
+ | $parts = explode(':', | ||
+ | $countparts = count($parts); | ||
+ | | ||
+ | $listlink = 0; | ||
+ | // low level links | ||
+ | if ($countparts < (2 + $lowlevel)){ | ||
+ | $listlink = 1; | ||
+ | }else{ | ||
+ | // children, yes - grandchildren and beyond, no | ||
+ | if ($countparts <= $countpartsID + 1){ | ||
+ | $listlink = 1; | ||
+ | $tmppathID = ''; | ||
+ | $tmppath | ||
+ | $i = 0; | ||
+ | foreach ($parts as $part){ | ||
+ | if (($i > 0) && ($i < $countparts - 2)){ | ||
+ | if (' | ||
+ | $tmppathID .= ':' | ||
+ | $tmppath | ||
+ | if ($tmppathID !== $tmppath){ | ||
+ | $listlink = 0; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | $i++; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | if ($listlink || $showall){ | ||
+ | $ullevel = $countparts - 1; | ||
+ | if ($ullevel == $ullevellast){ | ||
+ | $renderer-> | ||
+ | } | ||
+ | if ($ullevel > $ullevellast){ | ||
+ | $renderer-> | ||
+ | } | ||
+ | if ($ullevel < $ullevellast){ | ||
+ | for ($j = 0; $j < ($ullevellast - $ullevel); $j++){ | ||
+ | $renderer-> | ||
+ | } | ||
+ | $renderer-> | ||
+ | } | ||
+ | $ullevellast = $ullevel; | ||
+ | $renderer-> | ||
+ | if (strlen($linktext_before) > 0) { | ||
+ | $renderer-> | ||
+ | } | ||
+ | if (strlen($linkname) > 0) { | ||
+ | $renderer-> | ||
+ | }else{ | ||
+ | $renderer-> | ||
+ | } | ||
+ | if (strlen($linktext_after) > 0) { | ||
+ | $renderer-> | ||
+ | } | ||
+ | $renderer-> | ||
+ | }else{ | ||
+ | $renderer-> | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | break; | ||
+ | | ||
+ | case DOKU_LEXER_EXIT : | ||
+ | $ullevel = 1; | ||
+ | if ($ullevel == $ullevellast){ | ||
+ | $renderer-> | ||
+ | } | ||
+ | if ($ullevel > $ullevellast){ | ||
+ | $renderer-> | ||
+ | } | ||
+ | if ($ullevel < $ullevellast){ | ||
+ | for ($j = 0; $j < ($ullevellast - $ullevel); $j++) { | ||
+ | $renderer-> | ||
+ | } | ||
+ | $renderer-> | ||
+ | } | ||
+ | $renderer-> | ||
+ | break; | ||
+ | |||
+ | case DOKU_LEXER_SPECIAL : | ||
+ | break; | ||
+ | } | ||
+ | return false; | ||
+ | } | ||
+ | | ||
+ | // unsupported $mode | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | function tree_explode_node(& | ||
+ | $len = strlen($str) + 1; | ||
+ | $inside = false; | ||
+ | $word = ''; | ||
+ | for ($i = 0; $i < $len; ++$i) { | ||
+ | $next = $i+1; | ||
+ | if ($str[$i] == " | ||
+ | $out[] = $word; | ||
+ | $word = ''; | ||
+ | } elseif ($next == $len) { | ||
+ | $out[] = $word; | ||
+ | $word = ''; | ||
+ | } else { | ||
+ | $word .= $str[$i]; | ||
+ | } | ||
+ | } | ||
+ | $str = substr($str, | ||
+ | $out[] = $word; | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Setup VIM: ex: et ts=4 enc=utf-8 : | ||
+ | ?></ | ||
+ | |||
+ | ====== Tip ===== | ||
+ | |||
+ | To have the current link highlighted when using a sidebar template: | ||
+ | |||
+ | ---- | ||
+ | |||
+ | Add the following two lines in '/ | ||
+ | < | ||
+ | global $PPID; | ||
+ | $PPID = $ID; | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | Add in '/ | ||
+ | < | ||
+ | function internallink($id, | ||
+ | </ | ||
+ | |||
+ | |||
+ | After | ||
+ | < | ||
+ | global $ID; | ||
+ | </ | ||
+ | add | ||
+ | < | ||
+ | global $PPID; | ||
+ | </ | ||
+ | |||
+ | and after | ||
+ | < | ||
+ | if ($id == $ID) { | ||
+ | $link[' | ||
+ | $link[' | ||
+ | } | ||
+ | </ | ||
+ | add | ||
+ | < | ||
+ | if ($id == $PPID) { | ||
+ | $link[' | ||
+ | $link[' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | Add the following style in '/ | ||
+ | |||
+ | < | ||
+ | .curid { | ||
+ | font-weight: | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Multilingual content ====== | ||
+ | |||
+ | With a slight modification, | ||
+ | |||
+ | ====== Discussion ====== | ||
+ | |||
+ | I have no idea how to use this. Under usage you say: | ||
+ | |||
+ | //You must first design your sitemap. | ||
+ | |||
+ | There must be a 1st level link (located in the root namespace) as the 1st argument of the plugin. This typically will be your start page (for example index). However, there may be more 1st level links present. Thus we have: | ||
+ | |||
+ | < | ||
+ | : | ||
+ | . | ||
+ | . | ||
+ | </ | ||
+ | |||
+ | What do you mean there must be a 1st level link in the root namespace? | ||
+ | |||
+ | \\ | ||
+ | ----------- 2007-01-03\\ | ||
+ | >This navigation only based on namespaces and the corresponding page eg. start. You must create the list in e.g. sidebar by hand. There ist no autom. generated list. (I can´t found such a function). \\ | ||
+ | >< | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >: | ||
+ | >-> and so on | ||
+ | ></ | ||
+ | |||
+ | |||
+ | ----------- 2009-04-21 - Josef Meile < | ||
+ | |||
+ | What about doing only one index file an including it on each page were you want it to appear? Just like the way the TracNav plugin does it: | ||
+ | [[http:// | ||
+ | |||
+ | |||
+ | Actually, this is close to how this plugin works. I include the relevant code in the sidebar page (I'm obviously using a template with a sidebar) and the navigation tree adapts to the current page. The example site I mention above, demonstrates just that. However, I like the approach of the [[plugin: | ||
+ | |||
+ | --- // | ||
+ | |||
+ | Unluckily this plugin won't unfold any more with angua. I've used [[plugin: | ||
+ | |||
+ | --- // | ||
+ | |||
+ | Actually this plugin still works. I'm now using it with “Adora Belle”. BTW, there are some cool things you can do with it by creatively using the ' | ||
+ | |||
+ | --- // | ||
+ | |||