Extension:MenuTabs

Update
The extension has been modified to work with any skin/template without modification to any CSS files as the CSS is now embedded into the extension itself

Introduction
Whilst building our internal Wiki it became apparent to those new to the idea that navigation could be improved upon. A member of my team loved the way that http://www.apple.com top menu navigation system worked i.e. you have a main menu with sub menu items underneath. I was asked as to whether this could be replicated in MediaWiki and so set about the task. The fruits of my labour are detailed below. The credit for the CSS code goes to http://labs.silverorange.com/archives/2004/may/updatedsimple



Extension Code
Copy the following code into a file called MenuTabs.php and save this in the extensions directory:

 'MenuTabs', 'author' => 'Robert Castley', 'description' => 'allows for the creation of a menu navigation bar on each page if desired ');

function menuTabsCSS { global $wgOut; $css = << width: auto; display: block; float: left; padding: 4px 0px; padding-left: 4px; padding-right: 4px; margin-top: 1px; margin-right: 2px; text-align: center; font-family: Arial; font-size: 85%; text-decoration: none; color: #333; } border: 1px solid #666; border-bottom: none; background: #e6f0ff; padding-bottom: 6px; padding-left: 4px; padding-right: 4px; margin-top: 0; } width: auto; display: block; float: left; padding: 0 5px; margin: 0; text-align: center; border: none; border-left: 1px dotted #AAA; background: none; } border-left: 1px dotted #AAA; } eof; $wgOut->addHTML($css); }
 * 1) main { border-top: 1px solid #666; clear: both; width: 100%; }
 * 2) contents { background: #9aa4b3; border-top: 2em solid #e6f0ff; }
 * 3) header { position: relative; width: 100%; height: 2em; width: 45em; }
 * 4) header ul#primary { margin: 0; padding: 0; position: absolute; bottom: -1px; left: 20px; width: 45em; }
 * 5) header ul#primary li { display: inline; list-style: none; }
 * 6) header ul#primary a,#header ul#primary span,#header ul#primary a.current, #header ul#primary strong {
 * 1) header ul#primary span,#header ul#primary a.current,#header ul#primary a.current:hover, #header ul#primary strong {
 * 1) header ul#primary a { background: #bbc8da; border: 1px solid #AAA; border-bottom: none; }
 * 2) header ul#primary a:hover { margin-top: 0; border-color: #666; background: #FFF7CD; padding-bottom: 5px; }
 * 3) header ul#secondary { position: absolute; margin: 0; padding: 0; bottom: -1.4em; left: 1px; width: 50em; }
 * 4) header ul#secondary li a,#header ul#secondary li span ,#header ul#secondary li strong {
 * 1) header ul#secondary li a { color: #06C; text-decoration: underline; }
 * 2) header ul#secondary li a:hover { color: #333; background: transparent; padding: 0 5px; border: none;
 * 1) header ul#secondary li a:active { color: #333; font-weight: normal; background: transparent; }
 * 2) header ul#secondary li:first-child a, #header ul#secondary li:first-child span { border: none; }

function wfMenuTabs { global $wgParser; menuTabsCSS; $wgParser->setHook( "maintab", "renderMainTab" ); $wgParser->setHook( "subtab", "renderSubTab" ); }

function renderMainTab( $input ) { global $wgOut; global $wgTitle; global $wgRequest; global $wgUser; global $wgParser; $parserOptions = ParserOptions::newFromUser( $wgUser ); $parser = & new Parser; $item = ''; $title = $wgRequest->getVal( 'title' ); $title = preg_replace("/_/", " ", $title); $fields = explode("||",$input); $prepend = "\n"; $prepend .= "\n"; foreach ($fields as $field) { if ($title == $field) { $item .= " $field \n"; } else { $item .= "$field\n"; }	}	$output = & $parser->parse($item, $wgTitle, $parserOptions); $linkoutput = $output->getText; return $prepend. $linkoutput; }

function renderSubTab( $input ) { global $wgOut; global $wgTitle; global $wgRequest; global $wgUser; global $wgParser; $parserOptions = ParserOptions::newFromUser( $wgUser ); $parser = & new Parser; $item2 = ''; $fields2 = explode("||", $input); $prepend = "\n"; foreach ($fields2 as $field2) { if ($field2 != '') { $item2 .= "$field2\n"; }	}	$output = & $parser->parse($item2, $wgTitle, $parserOptions); $linkoutput = $output->getText; $append = "\n"; $append .= "\n"; $append .= " \n"; $append .= "\n"; $append .= " \n"; $append .= " \n"; return $prepend. $linkoutput. $append; } ?>

Then add this include statement to your LocalSettings.php: include("extensions/MenuTabs.php");

Troubleshooting
I've encountered problems using this extension with mediawiki 1.7.1 ... each tag  is parsed like this : &lt /li &gt ... This cause the extension not working ... In order to bypass this problem I've add the two following lines just after each $linkoutput = $output->getText; lines in the source code listed before : $linkoutput = str_replace ( '&lt;', '<', $linkoutput ); $linkoutput = str_replace ( '&gt;', '>', $linkoutput ); Hope this could help :)

Best Regards, KlinT ( klint@klintcentral.net )

With mediawiki 1.8.2 the extension don't work with and without the two lines above. Can anyone help?
 * Yes check the mod on the discussion page, that worked for me in 1.8.2. The above mod didn't. Rune.
 * Thanks

Alternate method:  Step1: Remove the '||' between menu items eg: HomeProfessional ServicesSalesSoftwareSupportCorporate

PS Best PracticesDocumentationTraining Step 2: Replace                       $item .= "$field</li>\n"; with                        $item .= "$field\n";

Usage
To generate your tabs you use the tags ... and ... . BOTH MUST BE USED TOGETHER EVEN IF SUBTABS DO NOT EXIST e.g.

Main Tabs with Sub Tabs
Home||Professional Services||Sales||Software||Support||Corporate PS Best Practices||Documentation||Training||Group Services||Webinars||Cool Tools

Main Tabs with empty Sub Tabs
Home||Professional Services||Sales||Software||Support||Corporate

Example
You should then end up with something looking similar to the following screenshot:







Usage in a production Wiki
The way I have implemented this into our Wiki is to add MenuTab code into a template and then include that template on each Wiki page. Therefore, every single page in the Wiki has it's own nice CSS tabbed navigation to take you to key areas within the Wiki.