User defined menus
Last edited by GiorgosKontopoulos:
Replaces old-style internal links with new pipe-split links.
Fri, 20 May 2016 07:38 UTC [diff]
Replaces old-style internal links with new pipe-split links.
Fri, 20 May 2016 07:38 UTC [diff]
There is already a solution to create, manage and use menus from WikkaMenus. I was troubled because it allows any WikiUser to change any menu, possibly changing so the interface used by the other users. Also I wanted something closer from the users, allowing them to design icon-menus if they want.
An alternate solution
So I came with a simple idea that any user could simply define a WikiPage named UserLogonMenu where he would simply type in the menu he wants using the standard wikka formatting. He may define the ACLs of this menu page as he wish. This solution is perfectly compliant with the WikkaMenulets too.The header.php and the stylesheet needs to be slightly changed so that when the system finds a page named UserLogonMenu it simply use it as the user menu. It also allows the admin to design an alternate GuestMenu for unidentified users.
I decided to have a class different from the "header" one but this is not mandatory.
The code
This code relies on the ExistsPage()function available from 1.1.6.0.It also include the LoggedUsersHomepage proposal.
New header.php - the lines commented by only if you wish a different presentation are not mandatory
<?php
$message = $this->GetMessage();
$user = $this->GetUser();
$site_base = $this->GetConfigValue("base_url");
if ( substr_count($site_base, 'wikka.php?wakka=') > 0 ) $site_base = substr($site_base,0,-16);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title><?php echo $this->GetWakkaName().": ".$this->PageTitle(); ?></title>
<base href="<?php echo $site_base ?>" />
<?php if ($this->GetMethod() != 'show') echo "<meta name=\"robots\" content=\"noindex, nofollow\"/>\n";?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="keywords" content="<?php echo $this->GetConfigValue("meta_keywords") ?>" />
<meta name="description" content="<?php echo $this->GetConfigValue("meta_description") ?>" />
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetConfigValue("stylesheet") ?>" />
<link rel="stylesheet" type="text/css" href="css/print.css" media="print" />
<script language="JavaScript" type="text/javascript">
function fKeyDown()
{
if (event.keyCode == 9)
{
event.returnValue = false;
document.selection.createRange().text = String.fromCharCode(9);
}
}
</script>
</head>
<body
<?php echo (!$user || ($user["doubleclickedit"] == 'Y')) && ($this->GetMethod() == "show") ? "ondblclick=\"document.location='".$this->href("edit")."';\" " : "" ?>
<?php echo $message ? "onLoad=\"alert('".$message."');\" " : "" ?>
>
<div class="header">
<h2><?php echo $this->config["wakka_name"] ?> : <a href="<?php echo $this->href("", "TextSearch", "phrase=").urlencode($this->GetPageTag()); ?>"><?php echo $this->GetPageTag(); ?></a></h2>
<?php
if ($this->GetUser()) {
$username=$this->GetUserName();
$usermenu=$username."Menu";
if ($this->ExistsPage($usermenu)) {
$themenu=$this->LoadPage($usermenu);
echo '</div><div class="menuicon">'; //only if you wish a different presentation
echo $this->Format($themenu["body"]);
echo "</div>"; //only if you wish a different presentation
}
else
{
echo ($this->GetUser() ? $this->Link($this->config["logged_in_homepage"]) : $this->Link($this->config["root_page"]))." :: ";
echo $this->config["logged_in_navigation_links"] ? $this->Format($this->config["logged_in_navigation_links"])." :: " : "";
echo "You are ".$this->Format($this->GetUserName());
}
} else {
if ($this->ExistsPage(GuestMenu)) {
echo '</div><div class="menuicon">'; //only if you wish a different presentation
$themenu=$this->LoadPage(GuestMenu);
echo $this->Format($themenu["body"]);
echo "</div>"; //only if you wish a different presentation
}
else
{
echo $this->Link($this->config["root_page"])." :: ";
echo $this->config["navigation_links"] ? $this->Format($this->config["navigation_links"]) : "";
}
}
?>
</div>
$message = $this->GetMessage();
$user = $this->GetUser();
$site_base = $this->GetConfigValue("base_url");
if ( substr_count($site_base, 'wikka.php?wakka=') > 0 ) $site_base = substr($site_base,0,-16);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title><?php echo $this->GetWakkaName().": ".$this->PageTitle(); ?></title>
<base href="<?php echo $site_base ?>" />
<?php if ($this->GetMethod() != 'show') echo "<meta name=\"robots\" content=\"noindex, nofollow\"/>\n";?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="keywords" content="<?php echo $this->GetConfigValue("meta_keywords") ?>" />
<meta name="description" content="<?php echo $this->GetConfigValue("meta_description") ?>" />
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetConfigValue("stylesheet") ?>" />
<link rel="stylesheet" type="text/css" href="css/print.css" media="print" />
<script language="JavaScript" type="text/javascript">
function fKeyDown()
{
if (event.keyCode == 9)
{
event.returnValue = false;
document.selection.createRange().text = String.fromCharCode(9);
}
}
</script>
</head>
<body
<?php echo (!$user || ($user["doubleclickedit"] == 'Y')) && ($this->GetMethod() == "show") ? "ondblclick=\"document.location='".$this->href("edit")."';\" " : "" ?>
<?php echo $message ? "onLoad=\"alert('".$message."');\" " : "" ?>
>
<div class="header">
<h2><?php echo $this->config["wakka_name"] ?> : <a href="<?php echo $this->href("", "TextSearch", "phrase=").urlencode($this->GetPageTag()); ?>"><?php echo $this->GetPageTag(); ?></a></h2>
<?php
if ($this->GetUser()) {
$username=$this->GetUserName();
$usermenu=$username."Menu";
if ($this->ExistsPage($usermenu)) {
$themenu=$this->LoadPage($usermenu);
echo '</div><div class="menuicon">'; //only if you wish a different presentation
echo $this->Format($themenu["body"]);
echo "</div>"; //only if you wish a different presentation
}
else
{
echo ($this->GetUser() ? $this->Link($this->config["logged_in_homepage"]) : $this->Link($this->config["root_page"]))." :: ";
echo $this->config["logged_in_navigation_links"] ? $this->Format($this->config["logged_in_navigation_links"])." :: " : "";
echo "You are ".$this->Format($this->GetUserName());
}
} else {
if ($this->ExistsPage(GuestMenu)) {
echo '</div><div class="menuicon">'; //only if you wish a different presentation
$themenu=$this->LoadPage(GuestMenu);
echo $this->Format($themenu["body"]);
echo "</div>"; //only if you wish a different presentation
}
else
{
echo $this->Link($this->config["root_page"])." :: ";
echo $this->config["navigation_links"] ? $this->Format($this->config["navigation_links"]) : "";
}
}
?>
</div>
Add something like this in the style sheet file if you want a different presentation for these menus
.menuicon {
color: #333;
background: #CCCCCC;
text-align: center;
}
color: #333;
background: #CCCCCC;
text-align: center;
}
Menu samples
You may have something like:[[HomePage | Home]] - {{edit}} - [[PageIndex | Index]] - [[Docs:FormattingRules | Writing rules]] - SandBox - [[UserSettings | Settings]] - [[UserName | My Home]]
Or more sexy like (I already use an icons folder but the user could upload its own icons using the files action:
{{image alt="Home Page" title="Home Page" url="icons/32/home.png" link="HomePage"}}{{imageedit alt="Edit Page" title="Edit this page" url="icons/32/pen.png"}}{{image alt="Index" title="Pages Index" url="icons/32/dictionary.png" link="PageIndex"}}{{image alt="Formatting Rules" title="Formatting Rules" url="icons/32/Whiteboard.png" link="FormattingRules"}}{{image alt="Sandbox" title="Sandbox" url="icons/32/paddle.png" link="SandBox"}}{{image alt="User Settings" title="Change Settings/Logout" url="icons/32/kgpg.png" link="UserSettings"}}{{image alt="User Page" title="My own page" url="icons/32/identity.png" link="UserName"}}
Here is how this one here above looks like :
http://131.202.10.204/hostedimages/MyWikka.png
The page shown here above is what we call our WorkSpace and it also links to various pages through a dedicated menu: guess where these icons link to?
- To be honest, I can guess maybe (!) three or four (home, edit, attachment, search?) - the rest are a complete mystery to me... The problem with icons is that they have to be learned - no matter how pretty they look - and that can happen only if either the icons are standardized and used across many applications, or the user spends a lot of time with a particular application. Having a title attribute for each icon (as you do) would be necessary to enable the user to figure out what they mean! --JavaWoman
- Christian, thanks for posting this interesting suggestion, which looks quite similar to what other wikis have proposed so far. Although I like the idea, I'll try to give some arguments why a table-based approach like that of WikkaMenus has some advantages:
- I was troubled because it allows any WikiUser to change any menu
- This is not a real issue: WikkaMenus can be set to allow only some users or admins to the menu configuration interface, much as in your proposal. OTOH, see below how custom user menus can be made compatible with this approach. --ChristianBarthelemy
- Also I wanted something closer from the users, allowing them to design icon-menus if they want.
As a general rule, icons and layout properties should not be addressed in the code. They should all be taken care of by the appropriate CSS stylesheet. In WikkaMenus this is possible by adding a different id to each menu entry that can then be modified at will in the stylesheets. Still, if you really want a user to add a custom icon before a single menu entry on WikkaMenus (not already formatted with an icon by the CSS stylesheet), this is perfectly possible by adding something like {{image ...}} MenuItem in a single row in the menu interface.
- Agreed -ChristianBarthelemy
- Stylesheet issues
Actually I had started thinking of menus in a way very similar to yours. Then I realized that the biggest limit in using Wikka pages as a source for menus is that they allow very little control on the output. As I suggested in the WikkaMenus page, the proper solution for formatting menus (either horizontal or vertical) is to use unordered lists and to modify their appearance through the proper CSS selectors. This is difficult to do using the standard Wikka formatters (unless you embed HTML with style tags in the code, which is definitely not a good idea). How do you display the main menu as a vertical menu, following your approach? Consider that you can always produce "-" or ":" as menu item separators in the stylesheets (the power of CSS-generated content!).
- Agreed but Wikka will need some refactoring to allows the nice features provided through CSS: it is not obvious (for me at least) as it is now to design side menus or floating menus. -ChristianBarthelemy
- Custom/user menus
Another interesting aspect of WikkaMenus is that they allow an arbitrary number of menus to be created, deleted and renamed. You can always impose that some menus (like system menus) be read-only, while at the same time allowing the wikka admins to freely customize the number and appearance of menus (this was a suggestion made by JavaWoman). For instance, you might want to add a second (or third, or fourth) horizontal menu, or floating menus in the page etc. In the future, we might even consider the possibility of cross-referencing the menu table with the user table to store user-customized menu settings.
- I prefer to keep it simple. I do not see the possibility to have several menus as an added value - In the WikiWay you should rather design a dedicated page -ChristianBarthelemy
- Renaming menus instead of hardcoding them
WikkaMenus, finally, allow menus to be created, deleted and renamed, which gives the whole system more flexibility and does not make a sensitive element like a menu depend on the name of a hardcoded page.
- I prefer to keep it simple as explain above - however my approach needs some rework either to allow a user to delete its owned pages (already discussed somewhere else) or not to use the UserNameMenu if its body is empty -ChristianBarthelemy
- Thanks a lot for your comments as all you wrote makes a lot of sense. I am not yet convinced which way is the best for my own usage so I am using both solutions in parrallel until I make my mind. I have almost finished a (technically) similar development to manage ACLs for groups of users: will try to explain the concept at GroupManagement -ChristianBarthelemy
Look at SmiliesAction for a simpler image action, and for a workaround for IE handling of PNG's transparency
CategoryUserContributions