Provides a hierarchical Menu control. Application menus are defined using a
/WEB-INF configuration file located under the
/WEB-INF directory or the root classpath. An example Menu configuration files is provided below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <menu> <menu label="Home" path="user/home.htm" roles="tomcat, role1"/> <menu label="User" path="user/home.htm" roles="tomcat, role1"> <menu label="User Page 1" path="user/user-1.htm" roles="tomcat, role1"/> <menu label="User Page 2" path="user/user-2.htm" roles="tomcat, role1"/> </menu> <menu label="Admin" path="admin/admin-1.htm" roles="role1"> <menu label="Admin Page 1" path="admin/admin-1.htm" roles="tomcat, role1"/> <menu label="Admin Page 2" path="admin/admin-2.htm" roles="tomcat, role1"/> </menu> </menu>
To include the root menu item in your page, simply use the default Menu constructor:
public class MenuPage extends Page { public Menu rootMenu = Menu.getRootMenu(); public ActionLink logoutLink = new ActionLink(this, "onLogoutClick"); }
To render the configured Menu hierarchy you will need to use a Velocity #macro or Velocity code in your page. For example:
#writeMenu($rootMenu)
An example menu Velocity macro is provided below:
#macro( writeMenu $rootMenu ) <table id="menuTable" border="0" width="100%" cellspacing="0" cellpadding="0" style="margin-top: 2px;"> <tr> <td> <div id="searchbar"> <div class="menustyle" id="menu"> <ul class="menubar" id="dmenu"> #foreach ($topMenu in $rootMenu.children) #if ($topMenu.isUserInRoles() || $topMenu.isUserInChildMenuRoles()) #if ($topMenu.children.empty) <li class="topitem">$topMenu</li> #else <li class="topitem">$topMenu <ul class="submenu" #foreach ($subMenu in $topMenu.children) #if ($subMenu.isUserInRoles()) ><li>$subMenu</li #end #end ></ul> </li> #end #end #end #if ($request.remoteUser) <li class="topitem"><a href="$logoutLink.href">Logout</a></li> #end </ul> </div> </div> </td> </tr> </table> #end
This example uses role path based security to only display the menu items the user is authorized to see. If you not using this security feature in your application you should remove the macro {@link #isUserInRoles()} checks sothe menu items will be rendered.
Note individual menu items will render themselves as simple anchor tags using their {@link #toString()} method. For more fine grain control you shouldextend your Velocity macro to render individual menu items.
Security
Menus support role based security via the {@link #isUserInRoles()}method. When creating secure menus define the valid roles in the menu items. For example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <menu> <menu label="Home" path="user/home.htm" roles="user,admin"> <menu label="Home" path="user/home.htm" roles="user,admin"/> <menu label="Search" path="user/search.htm" roles="user,admin"/> </menu> <menu label="Admin" path="admin/admin.htm"> <menu label="Home" path="admin/admin.htm" roles="admin"/> </menu> </menu>
The underlying implementation of isUserInRoles() method is provided by an {@link AccessController} interface. The default AccessController is providedby the {@link RoleAccessController} which uses the JEE container is user inrole facility. By providing your own AccessController you can have menu access control using other security frameworks such as JSecurity or Spring Security (Acegi).
Menu Configuration DTD
The Menu config file DTD is provided below:
<!-- The Menu (menu.xml) Document Type Definition. --> <!ELEMENT menu (menu*)> <!ATTLIST menu label CDATA #IMPLIED> <!ATTLIST menu path CDATA #IMPLIED> <!ATTLIST menu target CDATA #IMPLIED> <!ATTLIST menu title CDATA #IMPLIED> <!ATTLIST menu imageSrc CDATA #IMPLIED> <!ATTLIST menu external (true|false) "false"> <!ATTLIST menu separator (true|false) "false"> <!ATTLIST menu roles CDATA #IMPLIED> <!ATTLIST menu pages CDATA #IMPLIED>
CSS and JavaScript resources
The Menu control makes use of the following resources (which Click automatically deploys to the application directory,
/click):
- click/menu.css
- click/extras-control.js
To import these Menu files simply reference the variables
$headElements and
$jsElements in the page template.
@see org.apache.click.extras.security.AccessController