> At any rate, I'm just trying to help Alex, I'm not invested in any  
> reason other than it's informative to try and solve. Is there any way  
> to get a templated 404 response?

Sorry Ross, perhaps my response didn't convey my appreciation for your
help, or maybe it came off sounding negative, I didn't mean that.

What I meant was: thanks for offering that solution, it looks like a
step forward, I appreciate your help, but based on my gut feeling
looking at that code and based on Marius's opinon, I don't think we're
yet at an elegant robust solution, so lets keep coming up with more
ideas.

- Alex

>
> -Ross
>
> On Dec 30, 2009, at 4:32 AM, Marius wrote:
>
> > Re init-ing S is a very risky thing to do. You loose all your context
> > information. uriNotFound is called by Lift from several key points.
> > From those key points, Lift uses the S context and updates the
> > function Map. With your example if your template is binding Scala
> > functions, those function will be written to a function map that will
> > not be seen by Lift as you're writing to a different S context.
>
> > I would advice no doing such things or if you do, then expect side
> > effects. In general avoid bypassing Lift's rendering pipeline. Lift
> > does a lot of things some of them internal and missing those you can
> > get into nasty hidden problems.
>
> > For head merge you could use HeadHelper.scala but note that internally
> > Lift doesn't use this ... it uses a more sophisticated head merge ...
> > see LiftMerge.scala. HeadHelper holds the old merge. IMO it should be
> > removed.
>
> > I'm not really sure why you guys don't like redirects, probably to
> > avoid traffic, but IMO this is not very relevant. But regardless, you
> > guys have your own reasons.
>
> > Br's,
> > Marius
>
> > On Dec 30, 9:39 am, Ross Mellgren <dri...@gmail.com> wrote:
> >> I think the problem with the site map is that the request you have  
> >> is for a page that doesn't exist so it can't build the current-page-
> >> relative sitemap.
>
> >> Here's a version that works:
>
> >> In Boot:
>
> >>         val notFoundNode = <lift:embed what="404" />
> >>         LiftRules.uriNotFound.prepend {
> >>             case _ => XhtmlTemplateResponse(notFoundNode, 404)
> >>         }
>
> >> And the other part:
>
> >> object XhtmlTemplateResponse extends HeaderStuff {
> >>     def apply(nodeToRender: NodeSeq, statusCode: Int): LiftResponse  
> >> = {
> >>         val renderedNode = {
> >>             val forceToRoot: LiftRules.RewritePF = { case _ =>  
> >> RewriteResponse(Req.parsePath("/"), TreeMap.empty, true) }
> >>             for (req <- S.request; session <- S.session) yield
> >>                 S.init(Req(req, forceToRoot::Nil), session) {
> >>                     session.processSurroundAndInclude("/",  
> >> nodeToRender)
> >>                 }
> >>         } openOr {
> >>             error("No session")
> >>         }
>
> >>         new XhtmlResponse(Group(renderedNode), Empty, headers,  
> >> cookies, statusCode, false)
> >>     }
>
> >> }
>
> >> The secret sauce is reiniting S with a new request that has been  
> >> rewritten to seem as if it were a hit to /
>
> >> I'm not sure if this is a good idea, but it seems to work for the  
> >> site map thing.
>
> >> However, I can't find a way to make the head merge work properly.  
> >> It looks like the head merging lies in the code path inside  
> >> LiftSession that is private to Lift. You could rearrange your  
> >> template to make only one head I guess, or wait until someone more  
> >> wise than I can direct you as far as that goes.
>
> >> -Ross
>
> >> On Dec 30, 2009, at 12:32 AM, Alex Black wrote:
>
> >>> I noticed another problem: the head merge is not working in this
> >>> scenario, the resulting page is not valid XHTML because it has two
> >>> head tags :)  So, this makes me think I'm going about things the  
> >>> wrong
> >>> way.
>
> >>> I'm hoping you can suggest the right way, to create a custom 404  
> >>> page,
> >>> correctly (without a redirect, with 404 status code), and  
> >>> processed by
> >>> the template engine so it uses our default template with sitemap  
> >>> etc.
>
> >>> - Alex
>
> >>> On Dec 30, 12:22 am, Alex Black <a...@alexblack.ca> wrote:
> >>>> One more detail:
>
> >>>> notFoundNode is defined like this:
>
> >>>>   val notFoundNode = <lift:embed what="404" />
>
> >>>> and 404.html like this:
>
> >>>> <lift:surround with="default" at="content">
> >>>>     <head>
> >>>>         <title>Page Not Found</title>
> >>>>     </head>
> >>>>         <h1>Page Not Found</h1>
> >>>>         <p>We couldn't find the page you were looking for.</p>
> >>>> </lift:surround>
>
> >>>> And my default.html hidden template has a site map tag in it, and  
> >>>> the
> >>>> sitemap contains a number of entries.
>
> >>>> On Dec 30, 12:14 am, Alex Black <a...@alexblack.ca> wrote:
>
> >>>>> I emailed Ross directly and said I did run with -
> >>>>> Drun.mode=production.
>
> >>>>> Here's what I'm seeing:
> >>>>> 1. If I run with -Drun.mode=production, and I access a not found  
> >>>>> url,
> >>>>> say mysite.com/foobar, then, I *do* see the custom 404 page as
> >>>>> expected, but, where I normally see my sitemap I see "No  
> >>>>> Navigation
> >>>>> Defined".
> >>>>> 2. If I run *without* that production flag, and I access a not  
> >>>>> found
> >>>>> url, I get a blank white screen that says "The requested page  
> >>>>> was not
> >>>>> defined in your SiteMap, so access was blocked.  (This message is
> >>>>> displayed in development mode only)".
>
> >>>>> So #2 is expected, #1 is not.
>
> >>>>> Ross, when you emailed me you said you tried to reproduce this,  
> >>>>> but I
> >>>>> think one difference between your scenario and mine is that on  
> >>>>> my 404
> >>>>> page I have a sitemap rendered.
>
> >>>>> So instead of what dpp had:
>
> >>>>> LiftRules.uriNotFound.prepend {
> >>>>>       case _ =>  XhtmlResponse((<html> <body>Silly goose</body> </
> >>>>> html>),
> >>>>>                                Empty, List("Content-Type" ->  
> >>>>> "text/
> >>>>> html;
> >>>>> charset=utf-8"), Nil, 404, S.ieMode)
> >>>>>     }
>
> >>>>> I have:
>
> >>>>>     // Catch 404s
> >>>>>     LiftRules.uriNotFound.prepend {
> >>>>>       case (req, _) => XhtmlTemplateResponse(notFoundNode, 404)
> >>>>>     }
>
> >>>>> with
>
> >>>>> object XhtmlTemplateResponse extends HeaderStuff {
> >>>>>   def apply(nodeToRender: Node, statusCode: Int): LiftResponse = {
> >>>>>     val renderedNode = S.render(nodeToRender,
> >>>>> S.request.get.request).first
> >>>>>     new XhtmlResponse(renderedNode, Empty, headers, cookies,
> >>>>> statusCode, false)
> >>>>>   }
>
> >>>>> }
>
> >>>>> - Alex
>
> >>>>> On Dec 29, 7:49 pm, Ross Mellgren <dri...@gmail.com> wrote:
>
> >>>>>> This is the production run mode thing dpp talked about. Try  
> >>>>>> your app with -Drun.mode=production
>
> >>>>>> -Ross
>
> >>>>>> On Dec 29, 2009, at 7:39 PM, Alex Black wrote:
>
> >>>>>>> Thanks for pointing that out, the catch-all sounds dangerous.
>
> >>>>>>> I tried your suggestion, and it works well except I'm  
> >>>>>>> encountering one
> >>>>>>> issue, my sitemap renders as "No Navigation Defined." for urls  
> >>>>>>> that
> >>>>>>> are not found.   I'm using 1.1-M8, I launched jetty in  
> >>>>>>> production mode
> >>>>>>> as you indicated, and added the passNotFoundToChain = false.
>
> >>>>>>> Did you expect that - or is the passNotFoundToChain meant to  
> >>>>>>> solve the
> >>>>>>> sitemap issue?
>
> >>>>>>> - Alex
>
> >>>>>>> On Dec 29, 6:10 pm, David Pollak <feeder.of.the.be...@gmail.com>
> >>>>>>> wrote:
> >>>>>>>> Keep in mind that Lift's behavior for 404s differs between  
> >>>>>>>> development and
> >>>>>>>> production mode in Lift 1.1-xxx
>
> >>>>>>>> To have your app/Lift handle a 404 rather than passing it to  
> >>>>>>>> your web
> >>>>>>>> container, in Boot.scala:
>
> >>>>>>>>     LiftRules.passNotFoundToChain = false
>
> >>>>>>>>     LiftRules.uriNotFound.prepend {
> >>>>>>>>       case _ =>  XhtmlResponse((<html> <body>Silly goose</
> >>>>>>>> body> </html>),
> >>>>>>>>                                Empty, List("Content-Type" ->  
> >>>>>>>> "text/html;
> >>>>>>>> charset=utf-8"), Nil, 404, S.ieMode)
> >>>>>>>>     }
>
> >>>>>>>> In development mode, Lift will tell you about SiteMap as this  
> >>>>>>>> was a common
> >>>>>>>> confusion point among new developers.  In production mode,  
> >>>>>>>> Lift will use
> >>>>>>>> that code.  To put Lift in production mode:
>
> >>>>>>>> mvn -Drun.mode=production jetty:run
>
> >>>>>>>> I would strongly recommend against a "catch-all" entry in  
> >>>>>>>> SiteMap as it will
> >>>>>>>> expose every page on your site to access.
>
> >>>>>>>> On Tue, Dec 29, 2009 at 11:17 AM, Alex Black  
> >>>>>>>> <a...@alexblack.ca> wrote:
> >>>>>>>>> Ok, I got this working, with 1.1-M8 using S.render.
>
> >>>>>>>>>  // A node which embeds our 404 template (e.g. 404.html)
> >>>>>>>>>  val notFoundNode =
> >>>>>>>>>    <lift:embed what="404" />
>
> >>>>>>>>>    // Catch 404s
> >>>>>>>>>    LiftRules.uriNotFound.prepend {
> >>>>>>>>>      case (req, _) => XhtmlTemplateResponse(notFoundNode, 404)
> >>>>>>>>>    }
>
> >>>>>>>>>  // If you're using a sitemap, make sure you have a catch-
> >>>>>>>>> all item,
> >>>>>>>>> e.g
> >>>>>>>>>  //    Menu(Loc("Catchall", Pair(Nil, true), "", Hidden ::  
> >>>>>>>>> Nil)) ::
>
> >>>>>>>>> using this object:
>
> >>>>>>>>>  object XhtmlTemplateResponse extends HeaderStuff {
> >>>>>>>>>    def apply(nodeToRender: Node, statusCode: Int):  
> >>>>>>>>> LiftResponse = {
> >>>>>>>>>      val renderedNode = S.render(nodeToRender,
> >>>>>>>>> S.request.get.request).first
> >>>>>>>>>      new XhtmlResponse(renderedNode, Empty, headers, cookies,
> >>>>>>>>> statusCode, false)
> >>>>>>>>>    }
> >>>>>>>>>  }
>
> >>>>>>>>> I think the wiki page:
> >>>>>>>>>http://wiki.liftweb.net/index.php/Setting_up_a_custom_404_page
> >>>>>>>>> should be updated.  The current code hides the 404 status  
>
> ...
>
> read more »

--

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.


Reply via email to