[Lift] Re: Issue with Context Handling
Just to continue this thread, Marius has done some great work, and its on review board i just tried it with my app and its working super duper; it appears the context handling was a bit screwed before. Marius, kudos - as always, your fast turn around is awesome and greatly appreciated. Cheers, Tim On Dec 31 2009, 6:20 pm, Timothy Perrett wrote: > Ok sounds like we are making progress - the behaviour Ross details is > indeed correct and what I want. > > Marius, by cleaning this up, do you think I can get the behaviour I > want? If so, when can this find its way into master? ;-) > > Cheers, Tim > > On Dec 31, 5:28 pm, Marius wrote: > > > > > Sure thing ! > > > Br's, > > Marius > > > On Dec 31, 7:19 pm, David Pollak > > wrote: > > > > On Thu, Dec 31, 2009 at 8:39 AM, Marius wrote: > > > > O I think I know what the problem is: > > > > > We have both: > > > > > LiftRules.calcContextPath ... used by LiftSession.contextpath > > > > > AND > > > > > LiftRules.calculateContextPath ... used by Req.contextPath > > > > > which leads to confusing behavior. IMO this is a very confusing API > > > > and I think calcContextPath should go away. There should be a single > > > > point where the user can specify how the contextPath is calculated. > > > > > Dave, I'm not sure why we keep them both but let me know if you have > > > > some reasons for keeping them both. Otherwise I'll work on a fix in > > > > the next days > > > > Yeah... there should be just one. Thanks for volunteering to clean this > > > one > > > up. > > > > > Br's, > > > > Marius > > > > > On Dec 31, 6:22 pm, Marius wrote: > > > > > Also Req.context path is defined as: > > > > > > val contextPath = LiftRules.calculateContextPath(request) openOr > > > > > request.contextPath > > > > > > Br's, > > > > > Marius > > > > > > On Dec 31, 6:14 pm, Marius wrote: > > > > > > > LiftSession is created with the contextPath that container provides. > > > > > > See LiftRules._getLiftSession > > > > > > > However LiftSession.contextPath is defined as: > > > > > > > def contextPath = (LiftRules.calcContextPath(this) or > > > > > > S.curRequestContextPath) openOr _contextPath > > > > > > > thus can you try it by setting in boot: > > > > > > > LiftRules.calculateContextPath = {req => Empty} ? > > > > > > > that should get you the contexPath the same as S. BT S.contextPath > > > > > > is > > > > > > defined as: > > > > > > > def contextPath: String = session.map(_.contextPath) openOr "" > > > > > > > which essentially takes is from LiftSession. > > > > > > > Br's, > > > > > > Marius > > > > > > > On Dec 31, 5:41 pm, Ross Mellgren wrote: > > > > > > > > The problem I experienced with X-Lift-ContextPath is that it does > > > > > > > not > > > > > > > > set LiftSession.contextPath, which is where the AJAX path is > > > > generated > > > > > > > from. It set Req.contextPath, but not the session. > > > > > > > > I found this by using an nginx with this config: > > > > > > > > location /foobar { > > > > > > > rewrite ^/foobar(.*)$ $1 break; > > > > > > > proxy_passhttp://127.0.0.1:8080; > > > > > > > proxy_set_header X-Lift-ContextPath "foobar"; > > > > > > > } > > > > > > > > Pointing at a lift-archetype-basic with the hello world snippet > > > > > > > replaced by: > > > > > > > > def howdy(in: NodeSeq): NodeSeq = > > > > > > > Request contextPath = { S.request.map(_.contextPath) > > > > > > > openOr "unkwn" } ++ > > > > > > > Session contextPath = { S.session.map(_.contextPath) > > > > > > > openOr "unkwn" } > > > > > > > > With jetty configured at the default (contextPath at root), the > > > > output > > > > > > > is: > > > > > > > > Welcome to your project! > > > > > > > > Request contextPath = foobar > > > > > > > Session contextPath = > > > > > > > > It looks like there is a LiftRules method intended to let you set > > > > > > > the > > > > > > > > session context path separately -- LiftRules.calcContextPath -- > > > > > > > but > > > > it > > > > > > > is a val and not a RulesSeq or anything mutable. > > > > > > > > -Ross > > > > > > > > On Dec 31, 2009, at 10:28 AM, Marius wrote: > > > > > > > > > No I don't think so. But one can deploy the same application > > > > multiple > > > > > > > > times with different context-paths as different copies. > > > > > > > > Sure > > > > it > > > > > > > > is not ideal but I do not think lift misbehaves when it comes to > > > > JEE > > > > > > > > contextpath. > > > > > > > > > Maybe I misunderstood the problem ... so I need to ask: Do > > > > > > > > people > > > > want > > > > > > > > to deploy the same application (say the same war not separate > > > > copies) > > > > > > > > under multiple context paths? If so then AFAIK this is a > > > > > > > > limitation > > > > on > > > > > > > > JEE containers but one that can be worked around at framework > > > > level. > > > > > > > > Is this the problem ? > > > > > > > > > Defect 68 is
[Lift] mapper CRUDify
Hi, I'm a newbie with Lift. with CRUDify, is it possible to override _showAllTemplate to show a limited number of columns? My table is big so I don't want to show everything when the List All menu is invoked. Thanks -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
[Lift] Re: Nice 404s sans Redirect
That sounds like a great approach to me Marius! On Jan 1, 6:31 am, Marius wrote: > It probably should ... but personally I still believe in equal rights > of 404 pages with any other template. > > David's solution is great and definitely works. But this thread made > me realize that a higher/easier level of addressing this is helpful. > From user perspective saying something like ".. .if a template cannot > be found, just use the template denominated by this path (i.e. > "foo" :: "bar" :: "404" :: Nil) instead.". Lift then would process > this template as the regular one with the difference that it will use > 404 status code automatically. > > Currently I have a prototype implementation and an offline discussion > with David about other more internal implications. We'll see where it > goes. > > Br's, > Marius > > On Jan 1, 12:12 am, Alex Black wrote: > > > That sounds great. > > > Just curious though, is there any chance runTemplate should just do > > the head merge? > > > On Dec 31, 3:12 pm, David Pollak > > wrote: > > > > On Wed, Dec 30, 2009 at 7:43 PM, Alex Black wrote: > > > > Ok, I tried this, it gets closer. > > > > > I noticed one issue: the head merge didn't get done, so I have two > > > > tags in the result. I'm attempting to set the title in the > > > > 404.html template, maybe there is a way I can set the title without > > > > using head merge? > > > > I'm opening up the merge method, so once the code is in master, you'll be > > > able to do: > > > > def generate404(): LiftResponse = { > > > import scala.xml.Node > > > > val resp: Box[Node] = S.setVars("expandAll" -> "true") { > > > for { > > > session <- S.session > > > req <- S.request > > > rendered <- S.runTemplate("404" :: Nil) > > > } yield session.performHeadMerge(rendered, req) > > > } > > > > XhtmlResponse(resp openOr Got a 404, > > > Empty, List("Content-Type" -> "text/html; > > > charset=utf-8"), > > > > Nil, 404, S.ieMode) > > > } > > > > This will do the head merge and give you the ability to do anything Lift > > > does. > > > > > - Alex > > > > > On Dec 30, 2:54 pm, David Pollak > > > > wrote: > > > > > In Boot.scala (the boot method): > > > > > > LiftRules.passNotFoundToChain = false > > > > > > LiftRules.uriNotFound.prepend { > > > > > case _ => generate404() > > > > > } > > > > > > In the Boot class: > > > > > > def generate404(): LiftResponse = { > > > > > import scala.xml.Node > > > > > > val resp: Box[Node] = S.setVars("expandAll" -> "true") { > > > > > for { > > > > > rendered <- S.runTemplate("404" :: Nil) > > > > > } yield rendered(0) > > > > > } > > > > > > XhtmlResponse(resp openOr Got a 404, > > > > > Empty, List("Content-Type" -> "text/html; > > > > charset=utf-8"), > > > > > Nil, 404, S.ieMode) > > > > > } > > > > > > And a 404.html file (which can be localized): > > > > > > > > > > > Couldn't find your page... sorry > > > > > > > > > > > The uriNotFound code is executed within the S scope, so you've got all > > > > the > > > > > goodness of knowing who the current user is, etc. > > > > > > The reason that the menu was not being rendered in your example is > > > > > that > > > > menu > > > > > rendering is based on the location property in the Req(uest). If > > > > > there > > > > is > > > > > no location (as defined in the SiteMap), then no menu can be rendered. > > > > > There's an option for displaying the entire sitemap by setting the > > > > > expandAll="true" attribute when invoking the Menu.builder snippet. > > > > > But > > > > you > > > > > don't really want to show the entire menu on all pages, so the > > > > > S.setVars("expandAll" -> "true") {...} method (which is a good > > > > > candidate > > > > for > > > > > renaming for all you renamers out there) allows us to set the > > > > > expandAll > > > > > attribute for the duration of the code block. > > > > > > Then we use S.runTemplate() to locate and run the 404.html template. > > > > > > Finally, we create the XhtmlResponse with the 404 error code. > > > > > > So, you can put whatever you want in the 404.html template (including > > > > > snippets) and all will work as expected. > > > > > > Thanks, > > > > > > David > > > > > > On Wed, Dec 30, 2009 at 10:45 AM, Alex Black > > > > > wrote: > > > > > > > It's not rewriting. > > > > > > > I didn't say it was. I just said it seemed most similar to > > > > > > re-writing. > > > > > > > > Trying to mix the two will muddy the concept of rewriting and > > > > > > > when it > > > > > > > happens. > > > > > > > Makes sense. > > > > > > > > As far as I can tell, the two problems you are facing are: > > > > > > > > 1. There's a non-trivial amount of your code that needs to run > > > > > > > to > > > > > > render > > > > > > > the 404 error page. This would be corrected by the suggestion > > > > that I > > > > > > posted > > > > > > >
[Lift] multiple forms on a page.
Start to play with lift now. My first issue is a simple guest book. There are several guest notes in the guest book list page. I want to display a reply form under each guest note. But I don't know how to bind the reply form to its note record. How can I do with this? I'm using Mapper now. Below is the snippet and list page. Thanks for your reply and time. PS. As I was blocked from the google groups. I'm sorry to say that maybe I cannot reply to your comment in time. Thanks again in advance. gbook.html: Wellcome to my Guest Book GuestBook.scala: class GuestBook { // Set up a requestVar to track the GuestNote object for edits and adds object noteVar extends RequestVar(new GuestNote()) def note = noteVar.is def addNote(html: NodeSeq): NodeSeq = { def doAdd() = { if (isValideNote(note)) { note.createdTime(new Date()) note.repliedByAdmin(0) note.save S.redirectTo("/gbook") } } def isValideNote(toCheck : GuestNote) : Boolean = List((if (toCheck.title.length == 0) { S.error("You must provide a title"); false } else true), (if (toCheck.email.length == 0) { S.error("You must provide a email address"); false } else true), (if (toCheck.content.length == 0) { S.error("You must provide some note content"); false } else true) ).forall(_ == true) bind("note", html, "title" -> SHtml.text(note.title, note.title(_)), "email" -> SHtml.text(note.email, note.email(_)), "content" -> SHtml.textarea(note.content, note.content(_)), "submit" -> SHtml.submit("Add my Note", doAdd)) } def list(html: NodeSeq): NodeSeq = { toShow.flatMap(item => { curListNote = item bind("item", html, "title" -> item.title, "email" -> item.email, "content" -> item.content, "reply" -> getReplyContent(item) ) } ) } def replyNote(html: NodeSeq): NodeSeq = { def doReply() = { println((S.param("id") openOr "")+(S.param("replyContent") openOr "")) } bind("note", html, "replyContent" -> SHtml.textarea(curListNote.replyContent, curListNote.replyContent(_)), "submit" -> SHtml.submit("Reply", doReply) ) } private def toShow = GuestNote.findAll() var curListNote: GuestNote = _ private def getReplyContent(item: GuestNote) = { if (item.repliedByAdmin == 0) { Not replied by admin } else {"Replied by admin at: "+item.replyTime} } } /templates-hidden/gbook/addForm.html Title: Email: Your Note: /templates-hidden/gbook/replyForm.html Your Reply: -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
Re: [Lift] Re: Problem in Lift 1.1-SNAPSHOT ?
1.1-M7 is a broken release. Dont use it. The latest is M8, also available in the downloads section, so use that instead. Cheers, Tim On 1 Jan 2010, at 02:52, Java1Guy wrote: > I'm not quite understanding... I just got the zip files from the > download page of the GitHub (http://github.com/dpp/liftweb/downloads) > for both 1.1-M7 and Lift-1.1-M8-release. > Both of them fail the build with the same error: > C:\Users\mark\Library\Lift-1.1-M7\lift-modules\lift-jta\src\main\scala > \net\liftweb\transaction\TransactionContext.scala:206: error: class > TransactionContext needs to be abstract, since method getUnitName in > trait ScalaEMFactory of type => String is not defined > class TransactionContext(private implicit val transactionService: > TransactionService) > ^ > one error found > > Are those snapshots/releases not "complete"? > I ran "mvn install" (no clean, since I just downloaded the zip...) > According to the pom, the Scala version they want is 2.7.7. I imagine > maven gets the compiler from the proper scala jar file instead of > using the "system" compiler. Even if that's not true, my SCALA_HOME > points to 2.7.7 and 'which scalac' points to the 2.7.7 version. > (FWIW, this also happens for 'mvn clean install' not surprisingly) > > I guess since it's in the jta module I don't really care since I'm not > using that... > > Cheers, Mark > > -- > > You received this message because you are subscribed to the Google Groups > "Lift" group. > To post to this group, send email to lift...@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscr...@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 lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
[Lift] Re: Nice 404s sans Redirect
It probably should ... but personally I still believe in equal rights of 404 pages with any other template. David's solution is great and definitely works. But this thread made me realize that a higher/easier level of addressing this is helpful. >From user perspective saying something like ".. .if a template cannot be found, just use the template denominated by this path (i.e. "foo" :: "bar" :: "404" :: Nil) instead.". Lift then would process this template as the regular one with the difference that it will use 404 status code automatically. Currently I have a prototype implementation and an offline discussion with David about other more internal implications. We'll see where it goes. Br's, Marius On Jan 1, 12:12 am, Alex Black wrote: > That sounds great. > > Just curious though, is there any chance runTemplate should just do > the head merge? > > On Dec 31, 3:12 pm, David Pollak > wrote: > > > On Wed, Dec 30, 2009 at 7:43 PM, Alex Black wrote: > > > Ok, I tried this, it gets closer. > > > > I noticed one issue: the head merge didn't get done, so I have two > > > tags in the result. I'm attempting to set the title in the > > > 404.html template, maybe there is a way I can set the title without > > > using head merge? > > > I'm opening up the merge method, so once the code is in master, you'll be > > able to do: > > > def generate404(): LiftResponse = { > > import scala.xml.Node > > > val resp: Box[Node] = S.setVars("expandAll" -> "true") { > > for { > > session <- S.session > > req <- S.request > > rendered <- S.runTemplate("404" :: Nil) > > } yield session.performHeadMerge(rendered, req) > > } > > > XhtmlResponse(resp openOr Got a 404, > > Empty, List("Content-Type" -> "text/html; charset=utf-8"), > > > Nil, 404, S.ieMode) > > } > > > This will do the head merge and give you the ability to do anything Lift > > does. > > > > - Alex > > > > On Dec 30, 2:54 pm, David Pollak > > > wrote: > > > > In Boot.scala (the boot method): > > > > > LiftRules.passNotFoundToChain = false > > > > > LiftRules.uriNotFound.prepend { > > > > case _ => generate404() > > > > } > > > > > In the Boot class: > > > > > def generate404(): LiftResponse = { > > > > import scala.xml.Node > > > > > val resp: Box[Node] = S.setVars("expandAll" -> "true") { > > > > for { > > > > rendered <- S.runTemplate("404" :: Nil) > > > > } yield rendered(0) > > > > } > > > > > XhtmlResponse(resp openOr Got a 404, > > > > Empty, List("Content-Type" -> "text/html; > > > charset=utf-8"), > > > > Nil, 404, S.ieMode) > > > > } > > > > > And a 404.html file (which can be localized): > > > > > > > > > Couldn't find your page... sorry > > > > > > > > > The uriNotFound code is executed within the S scope, so you've got all > > > the > > > > goodness of knowing who the current user is, etc. > > > > > The reason that the menu was not being rendered in your example is that > > > menu > > > > rendering is based on the location property in the Req(uest). If there > > > is > > > > no location (as defined in the SiteMap), then no menu can be rendered. > > > > There's an option for displaying the entire sitemap by setting the > > > > expandAll="true" attribute when invoking the Menu.builder snippet. But > > > you > > > > don't really want to show the entire menu on all pages, so the > > > > S.setVars("expandAll" -> "true") {...} method (which is a good candidate > > > for > > > > renaming for all you renamers out there) allows us to set the expandAll > > > > attribute for the duration of the code block. > > > > > Then we use S.runTemplate() to locate and run the 404.html template. > > > > > Finally, we create the XhtmlResponse with the 404 error code. > > > > > So, you can put whatever you want in the 404.html template (including > > > > snippets) and all will work as expected. > > > > > Thanks, > > > > > David > > > > > On Wed, Dec 30, 2009 at 10:45 AM, Alex Black wrote: > > > > > > It's not rewriting. > > > > > > I didn't say it was. I just said it seemed most similar to re-writing. > > > > > > > Trying to mix the two will muddy the concept of rewriting and when > > > > > > it > > > > > > happens. > > > > > > Makes sense. > > > > > > > As far as I can tell, the two problems you are facing are: > > > > > > > 1. There's a non-trivial amount of your code that needs to run to > > > > > render > > > > > > the 404 error page. This would be corrected by the suggestion > > > that I > > > > > posted > > > > > > regarding a LiftRule that generates the default 404 template. > > > > > > 2. Putting navigation on the page. I'm still noodling how to > > > address > > > > > > this particular issue. > > > > > > > If there are issues other than 1 and 2, please enumerate them. > > > > > > Those do sound like the issues. Just to reflect it back to you from > > > > > my perspective (in case one of us