Revision [2223]
This is an old revision of WikkaMenus made by DarTar on 2004-11-16 11:09:53.
Wikka Menus
I've written a first version of a simple module for customizing Wikka menus.
The module uses a dedicated wikka_menus table, in which the settings for several menus can be stored, along with their CSS selectors.
The output is an unordered list of links, which can be then formatted as a horizontal or vertical menu through the appropriate CSS style.
Why a menu table?
- it is much safer having a script modify single table entries than write into the Wikka configuration file (which contains all system settings).
- it is possible to create as many menus as needed, without cluttering up the system configuration, and store each menu in the table along with a CSS class/id that will determine its appearance on the page;
Installation
1. Create the table
You will need to change your wikka prefix, e.g. "wikka_", to match your configuration.
The INSERT lines are just meant to be an example.
CREATE TABLE `wikka_menus` ( `type` varchar(20) NOT NULL default '', `menu` varchar(255) NOT NULL default '', `css_class` varchar(20) NOT NULL default '', UNIQUE KEY `type` (`type`) ) TYPE=MyISAM; INSERT INTO `wikka_menus` VALUES ('main_menu', 'HomePage\n[[Categories]]\nUserSettings', 'main_menu'); INSERT INTO `wikka_menus` VALUES ('logged_in_menu', 'HomePage\n[[Categories]]\nUserSettings\nRecentChanges', 'logged_in_menu'); INSERT INTO `wikka_menus` VALUES ('aux_menu', 'MyPages\nRecentChanges\nRecentlyCommented', 'aux_menu');
2. Add the menu functions in wikka.php
function LoadMenu($type) {
$menu = $this->LoadSingle("SELECT menu FROM ".$this->config["table_prefix"]."menus WHERE type = '".$type."'");
return $menu;
}
function SaveMenu($type, $list) {
$this->Query("UPDATE ".$this->config["table_prefix"]."menus SET menu ='".mysql_real_escape_string(trim(str_replace("\r", "", $list)))."' WHERE type = '".$type."' LIMIT 1");
}
function TrimMenu($list) {
foreach (explode("\n", $list) as $line)
{
$line = trim($line);
$trimmed_list .= $line."\n";
}
return $trimmed_list;
}
function PrintMenu($menutype) {
if ($menurow = $this->LoadSingle("SELECT * FROM ".$this->config["table_prefix"]."menus WHERE type = '".$menutype."'")) {
$menu = "<ul class=\"".$menurow["css_class"]."\">";
foreach (explode("\n", $menurow["menu"]) as $menuitem){
$menu .="<li>".$this->Format($menuitem)."</li>\n";
}
$menu .= "</ul>\n";
return $menu;
}
}
$menu = $this->LoadSingle("SELECT menu FROM ".$this->config["table_prefix"]."menus WHERE type = '".$type."'");
return $menu;
}
function SaveMenu($type, $list) {
$this->Query("UPDATE ".$this->config["table_prefix"]."menus SET menu ='".mysql_real_escape_string(trim(str_replace("\r", "", $list)))."' WHERE type = '".$type."' LIMIT 1");
}
function TrimMenu($list) {
foreach (explode("\n", $list) as $line)
{
$line = trim($line);
$trimmed_list .= $line."\n";
}
return $trimmed_list;
}
function PrintMenu($menutype) {
if ($menurow = $this->LoadSingle("SELECT * FROM ".$this->config["table_prefix"]."menus WHERE type = '".$menutype."'")) {
$menu = "<ul class=\"".$menurow["css_class"]."\">";
foreach (explode("\n", $menurow["menu"]) as $menuitem){
$menu .="<li>".$this->Format($menuitem)."</li>\n";
}
$menu .= "</ul>\n";
return $menu;
}
}
3. Create the menu configuration interface (action/menu.php)
<?php
// Menu Configuration Interface
// Version 0.1
echo "<h3>Menu Configuration</h3><br />";
if ($this->IsAdmin())
{
// load existing menu settings from menu table
$default_main = $this->LoadMenu("main_menu");
$default_logged_in = $this->LoadMenu("logged_in_menu");
$default_aux = $this->LoadMenu("aux_menu");
$main = $default_main["menu"];
$logged_in = $default_logged_in["menu"];
$aux = $default_aux["menu"];
if ($_POST)
{
// get posted values and store them in database
$posted_main = $_POST["main_menu"];
$posted_logged_in = $_POST["logged_in_menu"];
$posted_aux = $_POST["aux_menu"];
$this->SaveMenu("main_menu", $this->TrimMenu($posted_main));
$this->SaveMenu("logged_in_menu", $this->TrimMenu($posted_logged_in));
$this->SaveMenu("aux_menu", $this->TrimMenu($posted_aux));
echo $this->Format("<<**New menu configuration stored** --- Thanks for updating the menus!<<::c:: --- --- ");
// update forms
$main = $posted_main;
$logged_in = $posted_logged_in;
$aux = $posted_aux;
}
// print form
echo $this->Format('Please enter menu items on separate lines. --- ');
echo $this->Format('You can either use //""CamelCase"" links// like ##""PageIndex""## --- ');
echo $this->Format ('or //forced links// like: ##""[[http://www.mydomain.com External Link]]""## --- --- ');
echo $this->FormOpen("","","post");
?>
<strong>Main Menu</strong><br />
<textarea name="main_menu" rows="6" cols="30"><?php echo $main ?></textarea><p> <p>
<strong>Logged-in Main Menu</strong><br />
<textarea name="logged_in_menu" rows="6" cols="30"><?php echo $logged_in ?></textarea><p> </p>
<strong>Auxiliary Menu</strong><br />
<textarea name="aux_menu" rows="6" cols="30"><?php echo $aux ?></textarea><p> </p>
<input type="submit" value="Update" style="width: 120px" accesskey="s" />
<input type="button" value="Cancel" onClick="history.back();" style="width: 120px" />
<?php
print($this->FormClose());
}
else
{
print("<em>Sorry, You don't have access to this page.</em>");
}
?>
// Menu Configuration Interface
// Version 0.1
echo "<h3>Menu Configuration</h3><br />";
if ($this->IsAdmin())
{
// load existing menu settings from menu table
$default_main = $this->LoadMenu("main_menu");
$default_logged_in = $this->LoadMenu("logged_in_menu");
$default_aux = $this->LoadMenu("aux_menu");
$main = $default_main["menu"];
$logged_in = $default_logged_in["menu"];
$aux = $default_aux["menu"];
if ($_POST)
{
// get posted values and store them in database
$posted_main = $_POST["main_menu"];
$posted_logged_in = $_POST["logged_in_menu"];
$posted_aux = $_POST["aux_menu"];
$this->SaveMenu("main_menu", $this->TrimMenu($posted_main));
$this->SaveMenu("logged_in_menu", $this->TrimMenu($posted_logged_in));
$this->SaveMenu("aux_menu", $this->TrimMenu($posted_aux));
echo $this->Format("<<**New menu configuration stored** --- Thanks for updating the menus!<<::c:: --- --- ");
// update forms
$main = $posted_main;
$logged_in = $posted_logged_in;
$aux = $posted_aux;
}
// print form
echo $this->Format('Please enter menu items on separate lines. --- ');
echo $this->Format('You can either use //""CamelCase"" links// like ##""PageIndex""## --- ');
echo $this->Format ('or //forced links// like: ##""[[http://www.mydomain.com External Link]]""## --- --- ');
echo $this->FormOpen("","","post");
?>
<strong>Main Menu</strong><br />
<textarea name="main_menu" rows="6" cols="30"><?php echo $main ?></textarea><p> <p>
<strong>Logged-in Main Menu</strong><br />
<textarea name="logged_in_menu" rows="6" cols="30"><?php echo $logged_in ?></textarea><p> </p>
<strong>Auxiliary Menu</strong><br />
<textarea name="aux_menu" rows="6" cols="30"><?php echo $aux ?></textarea><p> </p>
<input type="submit" value="Update" style="width: 120px" accesskey="s" />
<input type="button" value="Cancel" onClick="history.back();" style="width: 120px" />
<?php
print($this->FormClose());
}
else
{
print("<em>Sorry, You don't have access to this page.</em>");
}
?>
4. Use the menus in your wiki pages
Once you've set the appropriate CSS styles, two different usages of custom Wikka Menus are possible:
You can either print your menus in the page header, by modifying actions/header.php as follows
<?php
($this->GetUser())? echo $this->PrintMenu("logged_in_menu") : echo $this->PrintMenu("main_menu");
?>
($this->GetUser())? echo $this->PrintMenu("logged_in_menu") : echo $this->PrintMenu("main_menu");
?>
or use them in the page body, through a simple action action/printmenu.php which can be called on the page with a syntax like {{printmenu type="main_menu"}}
<?php
// Print Menu action
echo $this->PrintMenu($type);
?>
// Print Menu action
echo $this->PrintMenu($type);
?>
Notes
- The code above can be easily modified to allow the creation of an indefinite number of custom menus, each with its name, content and css selector.
- The same approach might be used to allow users to modify their own custom menu (which would be stored in a dedicated row of users table)
- I wonder if menus are better handled by CSS id's or classes: do you think menus of the same type are susceptible to occur more than once on a page?
- Improvements and suggestions for the code above are welcome :)
-- DarTar
CategoryDevelopment