MediaWiki custom navigation menu (old style)
The navigation bar provides links to the most important locations in the wiki and supplies site administrators with a place to add a persistent collection of links. For instance, most wikis will link to their main page and some useful tools.
MediaWiki provides a standard mechanism to customize the navigation bar: Manual:Navigation bar.
The standard method is perfect for a static menu, but I wanted to provide a different menu if the user is logged in. Unfortunately, there doesn't seem to be a standard MediaWiki Variable for the user state, so we need to use code.
[edit] Checking if the user is logged in
The Raskin Center has a nice discussion of how they customized their wiki: Hacked Mediawiki Files:
"Besides moving around the order of the sidebars, the big change involved checking whether the user is logged in. This is done using a php hack (there ought to be a better way to do this):"
## Create a variable that is true (0) if the user is logged in. $logged_in = 1; if (sizeof($this->data['personal_urls']) > 1) { $logged_in = 0; }
[edit] Extending the Code
[edit] How the navigation menu is built
The navigation menu starts with an outline in the main message file. From MessagesEn.php:
/* The sidebar for MonoBook is generated from this message. Lines that do not begin with * or ** are discarded, furthermore lines that do begin with ** and do not contain | are also discarded, but don't depend on this behaviour for future releases. Also note that since each list value is wrapped in a unique XHTML id it should only appear once and include characters that are legal XHTML id names. */ $messages = array( 'sidebar' => ' * navigation ** mainpage|mainpage ** portal-url|portal ** currentevents-url|currentevents ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help ** sitesupport-url|sitesupport',
During initialization, this is parsed into a language- and site-specific data array:
$this->data['sidebar'] = { ["navigation"]=> array(7) { [0]=> array(4) { ["text"]=> string(9) "Main Page" ["href"]=> string(30) "/wiki/index.php/Main_Page" ["id"]=> string(10) "n-mainpage" ["active"]=> bool(false) } [1]=> array(4) { ["text"]=> string(16) "Community portal" ["href"]=> string(48) "/wiki/index.php/Wiki:Community_Portal" ["id"]=> string(8) "n-portal" ["active"]=> bool(false) } [2]=> array(4) { ["text"]=> string(14) "Current events" ["href"]=> string(35) "/wiki/index.php/Current_events" ["id"]=> string(15) "n-currentevents" ["active"]=> bool(false) } [3]=> array(4) { ["text"]=> string(14) "Recent changes" ["href"]=> string(42) "/wiki/index.php/Special:Recentchanges" ["id"]=> string(15) "n-recentchanges" ["active"]=> bool(false) } [4]=> array(4) { ["text"]=> string(11) "Random page" ["href"]=> string(35) "/wiki/index.php/Special:Random" ["id"]=> string(12) "n-randompage" ["active"]=> bool(false) } [5]=> array(4) { ["text"]=> string(4) "Help" ["href"]=> string(34) "/wiki/index.php/Help:Contents" ["id"]=> string(6) "n-help" ["active"]=> bool(false) } [6]=> array(4) { ["text"]=> string(9) "Donations" ["href"]=> string(44) "/wiki/index.php/Wiki:Site_support" ["id"]=> string(13) "n-sitesupport" ["active"]=> bool(false) } } };
The data array is ultimately used in the skin class to build the navigation menu:
<!-- Navigation Menu --> <div id="p-navigation"> <?php foreach ($this->data['sidebar'] as $bar => $cont) { ?> <ul> <?php foreach($cont as $key => $val) { ?> <li id="<?php echo htmlspecialchars($val['id']) ?>" <?php if ( $val['active'] ) { ?> class="active" <?php } ?>> <a href="<?php echo htmlspecialchars($val['href']) ?>"><?php echo htmlspecialchars($val['text']) ?></a> </li> <?php } ?> </ul> <?php } ?> </div> <!-- End of Navigation Menu -->
The final HTML looks like this:
<!-- Navigation Menu --> <div id="p-navigation"> <ul> <li id="n-mainpage" > <a href="/wiki/index.php/Main_Page">Main Page</a></li> <li id="n-portal" > <a href="/wiki/index.php/Wiki:Community_Portal">Community portal</a></li> <li id="n-currentevents" > <a href="/wiki/index.php/Current_events">Current events</a></li> <li id="n-recentchanges" ><a href="/wiki/index.php/Special:Recentchanges">Recent changes</a></li> <li id="n-randompage" > <a href="/wiki/index.php/Special:Random">Random page</a></li> <li id="n-help" > <a href="/wiki/index.php/Help:Contents">Help</a></li> <li id="n-sitesupport" > <a href="/wiki/index.php/Wiki:Site_support">Donations</a></li> </ul> </div> <!-- End of Navigation Menu -->
[edit] Customized site navigation menu
While it's easy to customize the navigation menu in a custom skin, a more generic approach is helpful. A relatively clean way to do this is to use the existing MediaWiki markup extension support.
MediaWiki extensions live in the extensions/ subdirectory in the MediaWiki installation. To create your own extension, first create a new file called YourExtensionName.php in this directory containing the following template code:
<?php $wgExtensionFunctions[] = "wfCustomMenus"; function wfCustomMenus() { global $wgParser; } ?>
Note that, unlike a regular parser extension, no rendering callback is registered.
All it takes to install the extension is adding a single line to the end of your LocalSettings.php file (above the "?>"):
require_once 'extensions/CustomMenus.php';
and you are ready to go. Go to the sandbox and see if it works.
SkinTemplate.php 161:
$tpl = $this->setupTemplate( $this->template, 'skins' );
Line 458:
$tpl->set( 'sidebar', $this->buildSidebar() ); $tpl->set( 'nav_urls', $this->buildNavUrls() );
Skin.php 1587:
function buildSidebar() {
Here's the basic extension function. It's crude in that it overwrites the global message cache, but it works.
<?php $wgExtensionFunctions[] = "wfCustomMenus"; function wfCustomMenus() { global $wgLang; # The following line is necessary to load the message cache $message = $wgLang->getMessage( 'sidebar' ); $wgLang->messages[ 'sidebar' ] = ' * navigation ** mainpage|mainpage ** Apollo_17_Flight_Journal|Flight Journal ** Category:Apollo_Flight_Journal_-_notes|AFJ Notes ** Special:Categories|Categories ** Special:Allpages|All Pages ** Special:Newpages|New Pages ** recentchanges-url|recentchanges ** helppage|help'; } ?>