Revision [2208]
This is an old revision of WikkaMenus made by DarTar on 2004-11-15 20:52: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, 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 their appearance on the page;
Installation
1. Create the table
You will need to change your wikka prefix, e.g. "wikka_", to fit 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. Create 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;
}
}
2. Create the menu configuration interface (action/menu.php)
// Menu Configuration Interface
// Version 0.1
<h3>Menu Configuration</h3>
<br />
<?php
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** --- ");
echo $this->Format("Thanks for updating the menu configuration! --- --- ");
// update forms
$main = $posted_main;
$logged_in = $posted_logged_in;
$aux = $posted_aux;
}
// print form
?>
<?php 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>");
}
?>
// Version 0.1
<h3>Menu Configuration</h3>
<br />
<?php
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** --- ");
echo $this->Format("Thanks for updating the menu configuration! --- --- ");
// update forms
$main = $posted_main;
$logged_in = $posted_logged_in;
$aux = $posted_aux;
}
// print form
?>
<?php 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
Two uses of Custom 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 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