官术网_书友最值得收藏!

Dynamic menu rendering

Menus are an important part of an application. They show a hierarchical structure and how the application is organized. Users will use them to navigate through the application.

Lift does offer a good built-in snippet for creating menus, as I briefly said before. In this recipe, I'll show you how to use this snippet to create complex menu structures, and how to render them with fine-grained control.

Getting ready

Create a new project and add the following code in the Boot class to create the SiteMap:

Val isAdmin_? = If(() => {
  S.param("admin").flatMap(asBoolean).openOr(false)
  }, () => RedirectWithState("/", MessageState(
  "Authorized personnel only" -> NoticeType.Warning))
)
val entries = List(
  Menu.i("Home") / "index" >> LocGroup("content"), // the simple way to declare a menu

  Menu("Admin") / "admin" >> Hidden
  submenus(
    Menu(Loc("List", List("list"), "List Contacts", isAdmin_?, LocGroup("admin"))),
    Menu(Loc("Create", List("create"), "Create Contact", isAdmin_?, LocGroup("admin"))),
    Menu(Loc("Edit", List("edit"), "Edit Contact", isAdmin_?, LocGroup("admin"))),
    Menu(Loc("Delete", List("delete"), "Delete Contact", isAdmin_?, LocGroup("admin"))),
    Menu(Loc("View", List("view"), "View Contact", isAdmin_?, LocGroup("admin")))
  ),
  Menu("Search") / "search" >> LocGroup("content"),
  Menu("Contact Us") / "contact" >> LocGroup("footer"),
  Menu("About Us") / "about" >> LocGroup("footer"),

  // more complex because this menu allows anything in the
  // /static path to be visible
  Menu(Loc("Static", Link(List("static"), true, "/static/index"),
"Static Content", LocGroup("content"))))

How to do it...

Rendering a menu dynamically can be done by following these steps:

  1. In the default.html file, change the invocation to the MenuBuilder snippet from <span class="lift:Menu.builder"></span> to <span class="lift:Menu.builder?group=content"></span>.
  2. Add the following code snippet after the div tag with content as the value of the id field:
    <div>
      <span class="lift:Menu.builder?group=admin"></span>
    </div>
  3. Then remove the h4 tag and the tag within the div tag and containing the class last, and add the following code:
    <span class="lift:Menu.builder?group=footer"></span>
  4. Start the application and access http://localhost:8080 and http://localhost:8080?admin=true. You should see a page similar to the one shown in the following screenshot:

How it works...

I'll start with the Scala code because it will be easier to first understand what this code does before trying to understand the HTML code. In fact, once you grasp how the SiteMap was built and how it works, the HTML code becomes pretty simple.

If you pay attention to the code, you'll see that we are creating a list of menu items, just like we discussed earlier, but this code is different from the previous one as it uses LocGroup and hidden, and has a submenu. The former can be used to place together menu items in logical groups, while the latter creates hierarchical menu structures, like the one appearing in the following screenshot:

We used the hidden property to prevent the menu from being shown on the page when the MenuBuilder snippet gets invoked. The submenu is shown only for users who are administrators. We did this by invoking the isAdmin_? function. This function evaluates the admin parameter and returns true or false depending upon the value of the parameter which could either be true or false. If the function returns true, the menu item will be both visible and accessible. However, it will not be visible if the function returns false, and if you try to access the URL directly, Lift will call the isAdmin_? function, which will redirect the user to / if the function returns false.

We also used LocGroup to divide the SiteMap into three logical groups: content, footer, and admin. So, the SiteMap has three groups, and one of them is hidden and has a submenu that is only visible to users with the right credentials. We now need to understand how this structure is transformed into HTML by Lift.

Looking closely at the HTML snippet, you'll find invocations to the MenuBuilder snippet. But, we are not just invoking snippets here. We are invoking and passing parameters to them.

Note

You can pass parameters to snippets like you would with URL parameters—a question mark and a bunch of key-value pairs. For example, ?key1=value1&key2=value2....

Lift uses these parameters as filters and will render only the items that have LocGroup specified by the parameter. When we say ?group=content, we are telling Lift to render only the items with LocGroup("content").

The final point to cover is the menu with LocGroup("admin") which we defined as hidden; a menu item defined as hidden is not rendered by Lift when the MenuBuilder snippet is invoked. If the menu item is not rendered, how will we access the items in the admin menu? As it turns out, the only item that is hidden is the one defined as hidden. Submenus are not affected. But we still want to let only users with the right credentials access the admin menu. To accomplish this, I created a function to tell Lift whether or not it should render the admin submenu items. Lift will only show it if we pass the admin parameter in the URL as true.

The isAdmin_? function is executed on every request and will be evaluated as true if you pass the admin parameter, and then Lift will render the menu. In this case, I used LocGroup("admin") to group all items together, so I can render them in a different area of the page.

Note

If you call Menu.builder with no parameter, Lift will render a complete SiteMap hierarchically. However, there is one catch—it will not render submenus hierarchically when LocGroup classes are used.

See also

  • The Defining a SiteMap recipe in Chapter 1, Getting Started with Lift Basics
主站蜘蛛池模板: 白银市| 青海省| 海宁市| 屏边| 浦东新区| 长岭县| 东阳市| 庄河市| 柏乡县| 读书| 梁河县| 防城港市| 唐河县| 浦东新区| 横峰县| 双柏县| 廊坊市| 怀化市| 溧阳市| 宝鸡市| 嵊泗县| 六盘水市| 黄浦区| 连州市| 耿马| 哈尔滨市| 灵山县| 克拉玛依市| 乐山市| 南宁市| 巴中市| 华坪县| 江华| 新安县| 平阴县| 莱州市| 渝北区| 蕉岭县| 甘孜县| 浠水县| 娄底市|