Up: Chapter 3

3.2 SiteMap

Lift has an optional feature called SiteMap. You don’t have to use it. But if you do set a sitemap in boot, then Lift will use the sitemap as a white list of HTML pages for your site (note that REST URLs do not need to be listed in the sitemap). SiteMap defines navigation and access control, allows you to create hierarchical menus, grouped menu items, display the entire sitemap, a relative sitemap, as well breadcrumbs. This section will discuss some of SiteMap’s capabilities.

3.2.1 Defining the SiteMap

The SiteMap must be defined in boot and is only defined once [B]  [B] In development mode, the sitemap can be changed dynamically to support changes to site content without having to re-start your application each time navigation changes. This is a development-time feature only. There are significant performance penalties associated with rebuilding the sitemap on each page load including forcing the serialization of serving pages. There are plenty of features in SiteMap that allow you to enable/disable menu items and have dynamically generated submenus. Don’t rely on Lift’s development-mode menu reloading for your application design.. Typically, you will define a function that returns a SiteMap instance:
    // Build SiteMap
    def sitemap(): SiteMap = ...
And then define the SiteMap in LiftRules:
    // set the sitemap.  Note if you don’t want access control for
    // each page, just comment this line out.
    LiftRules.setSiteMapFunc(() => sitemap())
In development mode, the function will be called on each page load to rebuilt the SiteMap. In all other Lift run modes, the sitemap will be built once during boot.
A SiteMap is a collection of Menu instances. Each Menu has one Loc[_] and a set of Menu instances as submenus (zero or more). Each Menu instance has a unique name.
If an HTML page is not defined in the sitemap, Lift will not serve it. SiteMap is a white list of pages to serve. Further, the Loc[_] has parameters that can include multiple access control rules.

3.2.2 Simplest SiteMap

The simplest sitemap defines a single page:
    def sitemap(): SiteMap = SiteMap(Menu.i("Home") / "index")
This is a SiteMap with a single menu item. The Menu has the name “Home” and will be displayed as the localized (see 8.1 on page 1↓) string “Home”. The Menu.i method generates a Menu with a Loc[Unit].

3.2.3Menu and Loc[_]

You may be wondering why a Menu and a Loc[_] (short for location, pronouned “Loke”) are separate and why the Loc takes a type parameter.
A Menu contains a location and many submenus. The original thought was that you could have a single Loc[_] that might be placed in different places in the menu hierarchy. So, historically, they are separated, but there’s a one to one relation between them.
The Loc[_] takes a type parameter which defines a current value type for the Loc. For example, if the Loc refers to a page that will display a wiki page, then the type parameter of the Loc would be WikiPage: Loc[WikiPage].
Each Loc can have many parameters (know as LocParam, “loke param”) that define behavior for the Loc[_]. These parameters include access control testing, template definition, title, group, etc.

3.2.4 Access Control

You can control access to the URL/page represented by the Loc with the If() LocParam:
  /**
   * Calculate if the page should be displayed.
   * In this case, it will be visible every other minute
   */
  def displaySometimes_? : Boolean = 
    (millis / 1000L / 60L) % 2 == 0
​
      Menu.i("Sometimes") / "sometimes" >> If(displaySometimes_? _,
                                            S ? "Can’t view now")
We define a method that returns true if access is allowed. Adding the If() LocParam will restrict access to the page unless the function returns true. Menu items will not be visible for pages that do not pass the access control rules and even if the user types the URL into the browser, the page will not be displayed (by default, the user will be redirected by to the home page and an error will be displayed.)

3.2.5Hidden and Group

Menu items can be hidden from the default menu hierarchy even if the page is accessible. The Hidden LocParam says “hide from default menu.”
 Menu.i("About") / "about" >> Hidden >> LocGroup("bottom")
Menu items can also be grouped together in a named group and then displayed:
 <span class="lift:Menu.group?group=bottom"></span>
Which results in:
 <a href="/about">About</a> <a href="/feedback">Feedback</a> <a href="/sitemap">Sitemap</a> 

3.2.6 Submenus

You can nest menus:
      // A menu with submenus
      Menu.i("Info") / "info" submenus(
        Menu.i("About") / "about" >> Hidden >> LocGroup("bottom"),
        Menu.i("Contact") / "contact",
        Menu.i("Feedback") / "feedback" >> LocGroup("bottom"))
The About, Contact and Feedback pages are nested under the Info page.

3.2.7 Parameters

You can parse the incoming URL and extract parameters from it into type-safe variables:
// capture the page parameter information
case class ParamInfo(theParam: String)
​
  // Create a menu for /param/somedata
  val menu = Menu.param[ParamInfo]("Param", "Param", 
                                   s => Full(ParamInfo(s)), 
                                   pi => pi.theParam) / "param"
The above code creates a menu called “Param”. The menu is for the url /param/xxx where xxx can match anything.
When the URL /param/dogfood or /param/fruitbat is presented, it matches the Loc and the function (s => Full(ParamInfo(s))) is invoked. If it returns a Full Box, the value is placed in the Loc’s currentValue.
It’s possible to hand-write Loc implementation that will match many URL parameters.
For information on accessing the captured parameters (in this case the ParamInfo), see 3.4.5 on page 1↓.

3.2.8 Wildcards

You can create menus that match all the contents of a given path. In this case, all the html files in /static/ will be served. That includes /static/index, /static/fruitbat, and /static/moose/frog/wombat/meow.
      // more complex because this menu allows anything in the
      // /static path to be visible
      Menu.i("Static") / "static" / **
Note that Lift will not serve any files or directories that start with . (period) or _ (underscore) or end with -hidden.

3.2.9 Summary

We’ve demonstrated how to create a SiteMap with many different kinds of menu items. Next, let’s look at the views.
Up: Chapter 3

(C) 2012 David Pollak