Version 23, last updated by heralight at 2013-09-18
Lift’s SiteMap contains a structured representation of all the pages on your site. Anything not listed in the SiteMap will (normally) not exist as part of the public-facing part of the app. This means that routing and access control happens here.
The Lift SiteMap is not just a menu that gives users access to important pages on your site, it is a comprehensive representation of every page of your site and the access rules that govern who can access what and when.The Menu.builder snippet then lets you dynamically render those items accessible in the current context.
If you don’t add a page to your SiteMap it will not be displayed by Lift on your web site.
A SiteMap is made up of Menu objects which are hierarchically structured: Each Menu is made from a Loc and optional kid Menus. A Loc is a location in a site and comprises of a unique name, a list of Strings which form a link, a title and a set of parameters of type LocParam.
Here’s a simple example Loc using Scala 2.8 named arguments to make it absolutely clear what is being set here:
val myLoc = Loc(theName: "HomePage", theLink: new Link(List("index")), theText: "Home Page")
Please notice that the text is a Scala By-Name-Parameter that will be evaluated on every “usage”. That means you could also pass a function returning a string instead of a static string, e.g. in order to i18n your app.
In much of the example code you will see that the Link parameter is given as a List[String], because there is an implicit conversion between a list of Strings and a Link: Loc.strLstToLink(…). So the Loc above would typically be defined with this code:
val myLoc = Loc("HomePage", "index" :: Nil, "Home Page")
… which is exactly the same as the above.
From Requests to Templates
In the Loc defined above we have a Link that refers to “index”. How do we actually get to XHTML that will get returned to the browser? By default Lift looks for an XHTML template file called index.html (or .htm or .xhtml or …) in the root of your app (src/main/webapp at development time if using Maven). It will then process the template, a large enough subject in its own right that it has its own wiki page.
You may organize your templates into subdirectories: new Link(“about” :: “lift” :: Nil) will use a template at src/main/webapp/about/lift.html.
If you want code to run before a page is loaded, and afterward either continue rendering the page as normal or return some other HTTP response, use EarlyResponse. It takes a nullary function that returns a Box[LiftResponse]. Return Empty to have Lift proceed as normal, or a Full Box containing a LiftResponse to override the default behavior and return your own response. For a complete list of response types available see LiftResponse.scala. They include JsonResponse for JSON responses, InMemoryResponse to return binary data, and RedirectResponse to trigger a redirect.
Once you have created your Loc objects, you can construct Menu objects either by simply wrapping a Loc in a Menu like this:
val myMenu = Menu(myLoc)
or by assembling menus together in a hierarchy like this:
val myMenu = Menu(myHelpMenuLoc, myUserHelpMenu, myTechnicalHelpMenu)
Here the first argument is a Loc followed by zero or more Menu arguments representing sub-menus of the menu you are creating.
You assemble your top level menus in a list, often by prepending your menu or menus to the default menus for Lift’s user management which are accessed by the User.menus method (defined in trait net.liftweb.mapper.MetaMegaProtoUser).
Once you have all your menus you create a SiteMap from your menus:
val mySiteMap = SiteMap(allMenus: _*)
If you are unfamiliar with Scala you may wonder what : _* means. It is a sequence argument marker according to section 6.6 of the Scala Language Specification.SiteMap takes a variable number of arguments all of which should be Menu objects. But allMenus is a List[Menu]. The : _* syntax tells Scala to take a List and pass it to a method as separate arguments.
Finally, you need to tell lift to use your SiteMap. You do this with the command:
To display the menus of your SiteMap in a template all you have to do is add the following snippet Menu.builder and it will display your menus as an unordered list by default.
If the xhtml that Lift produces isn’t what you were looking for you can customize the menu by using the following prefixes:
ul: Attributes of menu elements.
li: Attributes of menu item elements.
li_item: Attributes of the currently selected menu
top:id: The id attribute of the top-most menu element.
outer_tag: The tag of menu elements. By default this is <ul>, though you can chose any tag you want.
inner_tag: The tag of menu item elements. By default this is <li>.
level: What level of the entire selected menu tree to show. Counting begins at zero, for the top level. Consider a top level menu with ‘item1’, ‘item2’, and ‘item3’ and supposed ‘item1’ has a submenu with items ‘item1a’ and ‘item1b’. Level 0 will show the top level plus the submenus (see next option). If item2 or item3 is selected level 1 will show nothing, while if one of the item1 variants is selected the item1a and item1b entries will be displayed.
expand: Whether to expand submenus of the currently selected menu item. The default is true, the other option is false.
linkToSelf: Whether the currently selected space should be a link or not (becomes a span if set to false).