Change to support dynamic top level menu items

45 views
Skip to first unread message

Ross Mellgren

unread,
Nov 21, 2009, 3:46:16 PM11/21/09
to lif...@googlegroups.com
In the recent thread, a couple people asked for the ability to create dynamic menu items per request from the database. David suggested Loc.supplimentalKidMenuItems which works fine for dynamic children of a static menu, but doesn't support the ability to make the top level menu dynamic.

Menu has a method called "makeMenuItem" which gives a Box of MenuItem. What about a new method makeMenuItems that gives a possible plurality of MenuItems whose default implementation deferred to the existing makeMenuItem in the case where it's not overridden? I made this change to my local copy of lift and it seems to work alright.

Example Menu:

case class DynMenu() extends Menu(Loc("dynmenu", Link(List("dynmenu"), true, "/dynmenu"), "Dynamic Menu")) {
override def makeMenuItems(path: List[Loc[_]]): Iterable[MenuItem] =
DynMenuItem.findAll.map(dmi => {
MenuItem(Text(dmi.label.is), Text(dmi.link.is), Nil, false, false, Nil)
})
}

That is, a Menu can generate 0 or more MenuItems when the menu is being generated. The disadvantage I see is similar to the one with supplimentalKidMenuItems -- that is, you have to manually compute the attributes of MenuItem such as current. However, it does give you the full power to make whatever kind of menu items you want.

I looked briefly at seeing if it would be feasible to use a function Box[Req] => SiteMap on LiftRules, but I think the RewritePF auto detection thing in LiftRules.setSiteMap prevents this from being the right thing.

The change to lift-webkit:

diff --git a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/Menu.scala b/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/Menu.scala
index d33d1dc..79194f5 100644
--- a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/Menu.scala
+++ b/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/Menu.scala
@@ -61,8 +61,10 @@ case class Menu(loc: Loc[_], kids: Menu*) extends HasKids {
}
// def buildChildLine: List[MenuItem] = kids.toList.flatMap(m => m.loc.buildItem(Nil, false, false))

+ def makeMenuItems(path: List[Loc[_]]): Iterable[MenuItem] = makeMenuItem(path)
+
def makeMenuItem(path: List[Loc[_]]): Box[MenuItem] =
- loc.buildItem(loc.buildKidMenuItems(kids), _lastInPath(path), _inPath(path))
+ loc.buildItem(loc.buildKidMenuItems(kids), _lastInPath(path), _inPath(path))

private def _inPath(in: List[Loc[_]]): Boolean = in match {
case Nil => false
diff --git a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/SiteMap.scala b/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/SiteMap.scala
index 7939938..f8fa307 100644
--- a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/SiteMap.scala
+++ b/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/SiteMap.scala
@@ -66,7 +66,7 @@ case class SiteMap(globalParamFuncs: List[PartialFunction[Box[Req], Loc.AnyLocPa
case Full(loc) => loc.breadCrumbs
case _ => Nil
}
- CompleteMenu(kids.flatMap(_.makeMenuItem(path)))
+ CompleteMenu(kids.flatMap(_.makeMenuItems(path)))
}
}

Thoughts?

-Ross

philip

unread,
Nov 22, 2009, 9:28:07 PM11/22/09
to Lift

Essential for the CMS I am programming as the user needs to be able to
define the menu structure.

Ross Mellgren

unread,
Nov 23, 2009, 7:55:03 PM11/23/09
to lif...@googlegroups.com
As much as I subscribe to the "a lack of dissent is implicit assent" policy, I'm hoping somebody deeply familiar with SiteMap can comment on whether this change seems like a bad idea? I guess if I don't hear anything I'll create an issue and submit the patch for review, but I'd feel better with a bit more discussion.

-Ross
> --
>
> You received this message because you are subscribed to the Google Groups "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/liftweb?hl=.
>
>

David Pollak

unread,
Nov 23, 2009, 8:15:18 PM11/23/09
to lif...@googlegroups.com
On Mon, Nov 23, 2009 at 4:55 PM, Ross Mellgren <dri...@gmail.com> wrote:
As much as I subscribe to the "a lack of dissent is implicit assent" policy, I'm hoping somebody deeply familiar with SiteMap can comment on whether this change seems like a bad idea? I guess if I don't hear anything I'll create an issue and submit the patch for review, but I'd feel better with a bit more discussion.

Give me a few days to respond please.
 
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

Ross Mellgren

unread,
Nov 23, 2009, 8:16:59 PM11/23/09
to lif...@googlegroups.com
Understood. Thanks.

-Ross

David Pollak

unread,
Nov 24, 2009, 5:42:28 PM11/24/09
to lif...@googlegroups.com
Ross,

You can dynamically add child elements right now:

new SiteMap(menuItems) {
  override  def buildMenu(current: Box[Loc[_]]): CompleteMenu = {
     val tmp = super.buildMenu(current)
     CompleteMenu(tmp.lines.toList ::: List(additional menus))

Ross Mellgren

unread,
Nov 24, 2009, 5:46:22 PM11/24/09
to lif...@googlegroups.com
I considered this but my problem was that you could not place them into the middle of a static flow, without rummaging around in the CompleteMenu looking for known MenuItems.

For example, I was thinking in the CMS case that you probably want a static Home Menu and then some dynamic menus and then maybe some more static menus after that, such as logout etc.

Of course, I'm just trying to help out, it's not my use case, so the existing solution of overriding SiteMap.buildMenu may work for philip.

-Ross

glenn

unread,
Nov 24, 2009, 6:45:45 PM11/24/09
to Lift
There is a "poor man's" approach to creating top-level menus
dynamically. Simply create
a number of hidden menus - guessing at the max number your app will
likely need - whose text representation, paths and hidden attributes
can be
adjusted programatically as needed by the application. Not a very
satisfactory solution, but
in a pinch...

Glenn
> >> For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en
> >> .
>
> >> --
> >> Lift, the simply functional web frameworkhttp://liftweb.net
> >> Beginning Scalahttp://www.apress.com/book/view/1430219890
> >> Follow me:http://twitter.com/dpp
> >> Surf the harmonics
>
> >> --
>
> >> You received this message because you are subscribed to the Google  
> >> Groups "Lift" group.
> >> To post to this group, send email to lif...@googlegroups.com.
> >> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com
> >> .
> >> For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en
> >> .
>
> > --
>
> > You received this message because you are subscribed to the Google  
> > Groups "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to liftweb+u...@googlegroups.com
> > .
> > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en
> > .
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
> > --
>
> > You received this message because you are subscribed to the Google  
> > Groups "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to liftweb+u...@googlegroups.com
> > .
> > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en
> > .

philip

unread,
Nov 25, 2009, 2:26:06 AM11/25/09
to Lift

Hi David,

Thanks.

This is what works for me in my old fashioned non-functional way of
programming.

var sitemap:SiteMap = new SiteMap(Nil, MenuInfo.menu :_*) {
override def buildMenu(current: Box[Loc[_]]): CompleteMenu = {
val tmp = super.buildMenu(current)

var childMenus1:ListBuffer[net.liftweb.sitemap.MenuItem] = new
ListBuffer[net.liftweb.sitemap.MenuItem]
childMenus1 + new MenuItem(Text("Child1"), Text("child1"),
Nil, false, false, Nil)
childMenus1 + new MenuItem(Text("Child2"), Text("child2"),
Nil, false, false, Nil)

var childMenus2:ListBuffer[net.liftweb.sitemap.MenuItem] = new
ListBuffer[net.liftweb.sitemap.MenuItem]
childMenus2 + new MenuItem(Text("Child3"), Text("child3"),
Nil, false, false, Nil)
childMenus2 + new MenuItem(Text("Child4"), Text("child4"),
Nil, false, false, Nil)

var menu:ListBuffer[net.liftweb.sitemap.MenuItem] = new
ListBuffer[net.liftweb.sitemap.MenuItem]
menu + new MenuItem(Text("Extra menu1"), Text("extramenu1/
test"), childMenus1.toList, false, false, Nil)
menu + new MenuItem(Text("Extra menu2"), Text("extramenu2/
test"), childMenus2.toList, false, false, Nil)

CompleteMenu(tmp.lines.toList ::: menu.toList)
}
}
LiftRules.setSiteMap(sitemap)

Philip


On 11月25日, 上午6時42分, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> >> liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com­>
> >> .
> >> > For more options, visit this group at
> >>http://groups.google.com/group/liftweb?hl=.
>
> >> --
>
> >> You received this message because you are subscribed to the Google Groups
> >> "Lift" group.
> >> To post to this group, send email to lif...@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com­>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/liftweb?hl=en.
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > liftweb+u...@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/liftweb?hl=en.
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com­>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/liftweb?hl=en.
>
> --
> Lift, the simply functional web frameworkhttp://liftweb.net
> Beginning Scalahttp://www.apress.com/book/view/1430219890
> Follow me:http://twitter.com/dpp
> Surf the harmonics- 隱藏被引用文字 -
>
> - 顯示被引用文字 -
Reply all
Reply to author
Forward
0 new messages