previously

March 20, 2015 ยท View on GitHub

h1. Playframework Menu module

h2. What's New in v1.1a

  • Add Mongo menu implementation
  • Automatically choose mongo implementation if Morphia or MongoDB plugin found
  • IMenu.getContext() dropped, use IMenu.hasLabel() instead
  • Support user define the yaml file name with "menu.yamlFile" configuration
  • Always load menu from yaml file on application startup if "menu.loadFrom" is "yml"
  • Support load all menus into memory if "menu.cache" is set to 'true'
  • Simplified menu yaml file

bc.

previously

_Menu(home): name: home url: '@{Application.index()}'

now

home: name: home url: '@{Application.index()}'

h2. What's New in v1.0c

  • Support reverse url mapping. I.e. in your _menu.yml file you can define url as '@{Demo.index()}'

The Menu module is developed to enable Playframework application developer to quickly implement web navigation menu

h2. Motivation

It is a usual task for web developer to implement navigation menu. The idea of Menu module is to enable developer to quickly define menu structure and inject the menu using tag in the play groovy templates.

h2. features

  • Define menu structure with yaml data file
  • Provide easy to use menu tag to insert navigation menu to your web page
  • Support current menu
  • Support hierarchical structure
  • Using label to group your menus

h2. TODO List

  • Add themes (js/css)

h2. Dependencies

  • Although Play Menu module is developed on Play-1.1beta, I don't think there are any reason to prevent it be running on Play-1.0, except the sample application. The sample application demonstrate how you can implement your own Menu model besides using Menu module's built-in _Menu model. The user defined Menu model of the sample application use MongoDB to store the menu structure via play-morphia plugin.

h2. Usage

h3. Configuration

bc.. # Define menu default implementation class

default is: models._Menu

menu.class=models.MyMenuImpl

h3. Prepare _menu.yml file

you can define menu hierarchies in _menu.yml file (if you use default menu implementation), otherwise, you should define menu hierarchies in corresponding files loaded in your customized menu implementation ".loadMenu()" method. But the content of this file should be the same.

bc..

Sample _menu.yml

play: name: play url: / labels: - play

doc: name: learn url: /doc title: play documentation parent: play labels: - play - doc

com: name: community url: /community title: play community parent: play labels: - play - community

code: name: code url: /code parent: play labels: - play - code

module: name: modules url: /modules parent: play labels: - play - module

akka: name: akka support url: /modules/akka parent: module labels: - play - module

bespin: name: Bespin online editor url: /modules/bespin parent: module labels: - play - module

user: name: Manage user url: /admin/users context: admin # context is deprecated, use labels instead labels: - play - admin

p. As you can find in the above sample _menu.yml file, each menu item can have five enties:

  • name
  • url
  • title (optional)
  • labels (optional, could be used to partition your navigation menu depends on the context, e.g. admin)
  • parent (optional, if no parent specified, then this entry is the top level menu)

p. Start from v1.0c, you can use reverse URL mapping in menu yml file, e.g. url: '@{Application.index}' will map to '/'. Note, you must use quotation mark "'" to use the reverse URL mapping style.

h3. Use menu tag in your template

p. Basically you don't need to do anything else once you have created your _menu.yml file. Just make sure you have configured db in your application.conf file because the default menu implementation use JPA (unless you have Morphia or MongoDB plugin enabled, in which case MongoMenu will be used). Now you can easily insert menu in your groovy template file. For example:

bc..

p. That's it, easy, isn't? -One important note, if you decide to use default _Menu model built-in the module (I guess 90% case you will use the built-in one), make sure you delete the _Menus.java in menu/app/controllers directory. That one is prepared in case you have your own IMenu model implementation, just as demonstrated in the sample app-.

h3. Use label to group menu

p. First you need to assign label(s) to menu items in your menu definition file "_menu.yml" if you use default implementation. Then you can define require menu.menu tag to display menus which are associated with specific label. You can do it in two ways:

bc.. /* apply label method 1: use controller to set the label */ @Before static void setMenuLabel() { renderArgs.put("_menu_label", "play"); }

/* apply label method 2: assign label in your template file */

#{menu.menu menu_label: 'admin' /}
#{menu.menu menu_label: 'user' />

p. Note: menu items labeled with '_global' will always get displayed unless '_menu_no_global' options set to true

h3. Other RenderArgs

  • _menu_top_list: a list of IMenu object to be rendered in the web page
  • _menu_current: url indicate the current menu

h3. Create your own Menu model implementation

p. It's possible that you will not be able to use the default Menu impl. One obvious reason is GAE does not support JPA. In the case, you need to implement your own IMenu in your models package. The demo application provides a Menu model implementation with mongodb, you can refer to it on how to implement your own Menu model. -There are several notes need to be mentioned:-

  • -Always implement your menu model using models.Menu as the package/class name. Otherwise you can't benefit from controllers._Menus which prepare renderArgs for menu.menu tag.-
  • -Plugin will always load _menu.yml unless you disable it, i.e. menu.no_def_impl=true. You can choose to put your menu structure in that file, or (most probably) implement your own bootstrap load mechanism. In the demo app, there is a Bootstrap job created OnApplicationStart to load menu.yml file. The load process use Fixtures.load because Morphia Model support that. If you are using Model doesnot support Fixture.load, you are on your own to create and load your own intial data file or input the menu struture data in your db storage directly-.

h3. How to customize look&feel of the navigation menu rendered in my web page?

p. Refer to {play.path}/modules/menu-xx/public/stylesheets/_menu.css