struts-menu
===========
Introduction
------------
This project contains the source code for a web menuing component intended to work
with Jakarta "Struts" subproject. See http://jakarta.apache.org/struts for details
on Struts.
This project consists of the following major components:
- Menus are modeled in an xml resource file and parsed by a repository which is
intended to be provided as an application scope attribute.
- Implementations of a menu displayer interface that are used to display the menus
defined in the xml file. The displayers utilize property files that contain
the strings used for dislplaying the menus in html. The property files are
utilized as org.apache.struts.util.MessageResources. This allows a page
designer to modify the html (usually to change look and feel) in this file and
have the menu displayer use their custom file. A designer could potentially
have many variations of this file to provide many different look and feels for
their menus.
- A set of tags used for displaying menus using a menu displayer specified in the
xml resource mentioned above. For example:
For using a custom property file:
...
Installing and Using struts-menu
--------------------------------
You can utilize the binary distribution of struts-menu in your own web application
by following these steps:
- Download and install Struts into your web application. You can refer to the struts
documentation on how to do this at .
Note: struts-menu has not been tested with Struts 0.5, but with recent nightly
builds. It is recommneded that you use one of the more recent nightly builds.
- Copy the file "lib/struts-menu.tld" from the struts-menu distribution into the
"WEB-INF" directory of your web application.
- Copy the file "lib/struts-menu.jar" from the struts-menu distribution into the
"WEB-INF/lib" directory of your web application.
- Modify the application "WEB-INF/web.xml" file to include a tag library decleration
for the struts-menu taglibrary. For example:
/WEB-INF/struts-menu.tld
/WEB-INF/struts-menu.tld
- In each JSP page that will use the Struts custom tags, add the corresponding taglib
directive for struts-menu.tld. For example:
<%@ taglib uri="/WEB-INF/struts-menu.tld" prefix="menu" %>
- Create an XML resource file containing definitions for your menus and place it
under the WEB-INF/ directory of your web application. You may use the menu-config.xml
file from the struts-menu example application as the basis for this.
- Make the menu repository available to your web application as an application
(or some other) scope attribute. The defualt key used by the menu displayer tags
to find this attribute is "com.fgm.web.menu.MENU_REPOSITORY".
You may specify a different key, but you will need to specify the key when using
the useMenuDisplayer tag. Just use the default key, it's easier! ;)
The following is an example of how you can load the MenuRepository from your
action servlet:
---------- begin ----------------
MenuRepository repository = new MenuRepository();
repository.setLoadParam("/WEB-INF/menu-config.xml");
repository.setServlet(this);
try {
repository.load();
getServletConfig().getServletContext().
setAttribute(MenuRepository.MENU_REPOSITORY_KEY, repository);
} catch (Exception e) {
//handle this error
}
------------ end ----------------
The repository will obtain the menu-config.xml file as an input stream by using the
servlet.getServletContext().getResourceAsInputStream() method so that it may pass it
to the Struts xml digester.
You will probably want to subclass the ActionServlet and place this code into the
init() method. This is done in the example application.
Note: The load parameter has to do with my implementation of what I call a
"loadable resource". I won't go into great detail about why I did this, but
the jist of it is that at one time I was developing a web application in which
I had various "resources", like the MenuRepository, and there was the possibility
of adding more and reusing them in other JSP web applications. The basic idea
is that you want to make some kind of "resource" avaialable as an application
scope attribute, with as little effort as possible. I made my "loadable
resources" implement a simple interface and defined what resources I wanted to
load in an XML file. My controller servlet read and loaded all resources
that were found.
This is sort of akin to the MLET stuff in which services are implemented
with a common interface that allows it to managed generically (such as with a
stop() method). As an example, the MLET stuff is used by JBoss.
I may or may not strip out the loadable resource stuff.
Installing the Example Application
-----------------------------
- Copy webapps/struts-menu.war to your servlet container web applications directory.
- Run it! ;)
NOTE: At this time, I have placed some of the necessary libraries into the example
application. This is done only as a convenience and will be removed later!
The only additional thing you will need is a SAX API. If you are using
Tomcat 3.2 or >, it should already come with one.
Also, see instructions from the Struts binary distribution about installing it
with JSP/Servlet containers other than Tomcat (b/c that all I use :p ).
Tag and Display Behaviours
--------------------------
- useMenuDisplayer tag:
The tag is basically used to setup an instance of a
MenuDisplayer object for use by the displayMenu tags.
The attributes of useMenuDisplayer:
--name - Required attribute that specifies which menu displayer to use. The
displayer ar defined in the menu-config.xml file.
--bundle - Attribute key for a MessageResources object. If the MenuDisplayer
is of type MessageResourcesMenuDisplayer, it will obtain a Struts
MessageResources object as an attribute by doing a
pageContext.findAttribute(bundle).
--config - Specify a properties file to use for displaying the menu. The file
is utilized as a Struts MessageResources object and, of course, the
strings are obtained by the key value. The default file that is
used is com.fgm.web.menu.displayer.DisplayerStrings.
--locale - Attribute key for a locale object to use. If the displayer is of
type MessageResourcesMenuDisplayer, it will obtain the locale object
and set it in the displayer.
--repository - Attribute key for the MenuRepository. Really, you will probably
only need one MenuRepository.
- displayMenu tag:
Generally only valid within a tag. It will simply retrieve the
menu from the MenuRepository and use the MenuDisplayer provided by useMenuDisplayer to
display it.
The attributes:
--name - Required attribute that specifies which menu to get from the repository.
--target - Override the menu item target (meant to go into an tag) with this one.
- MessageResourcesMenuDisplayer
Abstract implementation of a MenuDisplayer interface that provides some common
methods for obtaining messages from MessageResources. i.e. it provides the ability
to internationalize certain aspects of the menu like title, toolTip, etc.
- SimpleMenuDisplayer
Subclass of MessageResourcesMenuDisplayer that implements the
display(MenuComponent menu) method. Displays a simple table layout of the provided
menu.
Note: All of the message keys used for this display is prefixed with "smd".
An example property: smd.menu.top=
- DropDownMenuDisplayer
Subclass of MessageResourcesMenuDisplayer that implements the
display(MenuComponent menu) method. Displays a collapsable menu based on the
provided menu object.
Note: The message keys are prefixed with "dd".
This display only works 100% with IE >= 5.0 :(
It works somewhat with Netscape 6.0 and the latest Mozilla. See notes below in
the "To Do" section.
To Do (not necessarily in any order)
------------------------------------
- Display dynamic menus (like collapsable, or heirarchical) that are compatible with
various browsers. This is really a pain in the ass, especially since I'm not a
JavaScript guru. I have found some web menuing libraries that perform this fairly
well, but it will take a good amount of time figure out how they work. One that I
have found is Joust (http://www.ivanpeters.com/) which seems to work on most common
browsers like, IE (bleck!), Mozilla, Opera, and Netscape (4 and 6). If anyone would
like to assist in this (please do!), just contact me.
- Develop an example menu displayer that will look at user permissions and display or not
display the appropriate menu components.
- Overall clean up, documentation, enhanced functionallity, etc. since this is only in
the early stages.
- Provide additional menu display strings property files so that people can choose
a look and feel for their menus from a default library.
If anyone would like to assist in any of this, please contact me.
Contact
------------
If you have any comments, questions, or wish to contribute, please contact me via
email at ssayles@fgm.com