Ask:
Hi,
I want to add/remove Menu at runtime, for dynamically managing menu
list.
so I need to persist the menu list(SiteMap?) to the database,
and retrieve it from the database when users access the home page.
the menu items link to the same page, pass some different params so
let that page show different data.
so I want to dynamically build the menu of home page.
is it possible to do this by using SiteMap and Menu of liftweb?
Answer:
In a word, yes.
In a bunch of example... well if you have a static menu that you want to
enable, disable based on some calculation, use If() and Unless() when you're
defining your Loc(). You can see an example in ProtoUser.scala.
For a custom menu based on RDBMS content:
class BaseContentLoc(val name: String, _aspect: String) extends
Loc[CustomContent] {
// the name of the page
// def name = "Content"
val BaseAspect = _aspect
def defaultParams = Full(ContentLocStuff.NullCustomContent)
override def forceParam = defaultParams
// the default parameters (used for generating the menu listing)
override def additionalKidParams =
CustomContent.findAll(By(CustomContent.aspect, BaseAspect),
OrderBy(CustomContent.displayOrder, Ascending))
// no extra parameters
def params = List(Loc.PlaceHolder, Loc.Template(myTemplate))
def myTemplate() =
<lift:surround with="default-final" at="content"><lift:display
/></lift:surround>
/**
* Generate a link based on the current page
*/
val link =
new Loc.Link[CustomContent](List(BaseAspect), false) {
override def createLink(in: CustomContent) = {
Full(Text("/"+urlEncode(BaseAspect)+"/"+urlEncode(in.page)))
}
}
/**
* What's the text of the link?
*/
val text = new Loc.LinkText(calcLinkText _)
def calcLinkText(in: CustomContent): NodeSeq = {
if (in.page.length > 0) Text(in.page) else Text(name)
}
object Finder {
def unapply(page: String): Option[CustomContent] =
CustomContent.findContent(page, BaseAspect)
}
/**
* Rewrite the request and emit the type-safe parameter
*/
override val rewrite: LocRewrite =
Full({
case RewriteRequest(ParsePath(BaseAspect :: Finder(content) :: Nil,
_, _, _), _, _) =>
(RewriteResponse(BaseAspect :: Nil), content)
})
/**
* Check for page-specific snippets and
* do appropriate dispatching
*/
override val snippets: SnippetTest = {
case ("display", Full(v)) => display(v) _
}
def display(v: CustomContent)(in: NodeSeq) = v.content openOr in
}
Thanks,
David