Here it is
import net.liftweb.http._
import net.liftweb.util._
import net.liftweb.sitemap._
import net.liftweb.sitemap.Loc._
import scala.xml._
object ParamsLoc {
def apply(name: String, uri: Uri, params: LocStuff*) = new ParamsLoc(name,
uri, Hidden :: params.toList)
class ParamsLink(uri: Uri) extends Link[NullLocParams](List(), false) {
override def isDefinedAt(req: RequestState): Boolean = req.path.partPath
== List(uri.templateName)
}
implicit def strToUriString(in: String): UriString = UriString(in)
}
class ParamsLoc(theName: String, uri: Uri, params: List[LocStuff]) extends
Loc[NullLocParams] {
def name = theName
def link: Loc.Link[NullLocParams] = new ParamsLoc.ParamsLink(uri)
def text: Loc.LinkText[NullLocParams] = null // No link?
def defaultParams: Can[NullLocParams] = Full(NullLocParams)
def stuff: List[LocStuff] = params
override def rewrite: LocRewrite = Full(new
PartialFunction[RewriteRequest, (RewriteResponse, NullLocParams)] {
override def isDefinedAt(req: RewriteRequest): Boolean =
uri.matches(req.path.partPath)
override def apply(req: RewriteRequest): (RewriteResponse,
NullLocParams) =
(RewriteResponse(List(uri.templateName),
uri.params(req.path.partPath)), NullLocParams)
})
}
trait UriElement {
def /(that: UriElement): Uri = Uri(this :: that :: Nil)
}
case class UriString(str: String) extends UriElement
case class Param(name: String) extends UriElement {
var isOptional = false
def optional = {isOptional = true; this}
}
case class Uri(elements: List[UriElement]) extends UriElement {
override def /(that: UriElement): Uri = Uri(this.elements ::: List(that))
def templatePath: List[String] = for (UriString(str) <- elements) yield
str
def templateName: String = templatePath.mkString("", "-", "")
def params(path: List[String]): Map[String, String] = Map((
for ((Param(name), value) <- elements zip path) yield name -> value
):_*)
def matches(path: List[String]): Boolean = {
val lastParamIsOptional = elements.last match {
case p: Param => p.isOptional
case _ => false
}
if (path.length == elements.length || lastParamIsOptional &&
elements.length == path.length+1)
List.forall2(elements, path)((el, pathPart) => el match {
case el: UriString => el.str == pathPart
case el: Param => true
case _ => false
})
else
false
}
}
On Mon, Oct 27, 2008 at 4:45 PM, Tim Perrett <[EMAIL PROTECTED]> wrote:
>
> Hey Sasha,
>
> Thanks for your input - if your willing to post the code that would be
> brilliant :)
>
> Cheers, Tim
>
> On Oct 26, 11:50 pm, "Sasha Kazachonak" <[EMAIL PROTECTED]> wrote:
> > Unfortunately, I don't fully understand how the current Loc stuff is
> > supposed to be used. I like many things in lift a lot, but I want
> > first-class friendly URL's support. So I wrote it. It is used like this:
> >
> > val entries =
> > Menu(Loc("index", List("index"), "Main")) ::
> > ...
> > Menu(ParamsLoc("user-profile", "user"/Param("user")) ::
> > Menu(ParamsLoc("user-actions", "user"/Param("user")/"actions")) ::
> > Menu(ParamsLoc("user-message", "user
> > "/Param("user")/"message"/Param("to").optional))) :: Nil
> > LiftRules.setSiteMap(SiteMap(entries:_*))
> >
> > Of course, I still use LocStuff:
> > Menu(ParamsLoc("one", "two"/Param("three"), If(Everything.right _,
> > S.??("no-no")))))
> >
> > Then in a snippet I can use params like this:
> > def showProfile = (for (
> > id <- S.param("user");
> > user <- User.findByKey(id.toLong)
> > ) yield
> > <table>
> > ...
> > </table>
> > ) openOr Text("User not found")
> >
> > Actual templates for above locations are user.html, user-actions.html and
> > user-message.html. Notice, I could use user/actions.html, but current
> menus
> > don't let you have a folder with the same name as a template. For example
> > Menu(Loc("a", List("a"), "a")) ::
> > Menu(Loc("b", List("a", "b"), "b")) ::
> > work separately. But if you put them in one menu together and try
> entering "
> > server.com/a" url, you'll get confusing
> > Message: java.lang.IllegalArgumentException: line 1 does not exist
> > scala.io.Source.getLine(Source.scala:280)
> > ...
> > Is it a bug?
> >
> > My solution is not ideal, but works for me and took only about 50 LOCs to
> > write:) If you are interested, I'll attach the code.
> >
> > On Sat, Oct 25, 2008 at 5:43 PM, Tim Perrett <[EMAIL PROTECTED]>
> wrote:
> >
> > > Right, i've been working on this for most of the day trying to
> > > understand exactly whats going on. I have a working sample, but its
> > > not how I would want it to work in an ideal world.
> >
> > >http://github.com/timperrett/bloglite/tree/master/src/main/scala/eu/g.
> ..
> >
> > > What I really want to do is split the functionality to point at
> > > differnet HTML files to keep it all tidy as possible and so that the
> > > scala file doesnt get cologged with HTML. So, I try rewriting to a
> > > file called "list" as opposed to "articles" with the following:
> >
> > > override val rewrite: LocRewrite = Full({
> > > case RewriteRequest(ParsePath("index" :: Nil, _, _,_),_, _) =>
> > > (RewriteResponse("list" :: Nil), ListLoc)
> > > })
> >
> > > But it refuses to have it - jetty just serves the contents of the
> > > directory. There is obviously something going on that is not obvious -
> > > like I say, it all works fine if i just use a single HTML file, but
> > > thats *really* not what I want as its messy.
> >
> > > How can I resolve this?
> >
> > > Cheers
> >
> > > Tim
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---