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 <html><body>Got a 404</body></html>,
                  Empty, List("Content-Type" -> "text/html; charset=utf-8"),
Nil, 404, S.ieMode)
  }

And a 404.html file (which can be localized):

<lift:surround with="default" at="content">
Couldn't find your page... sorry
</lift:surround>

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 <a...@alexblack.ca> 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 is missing something), the issue as
> I see it is that I've designed a nice 404 template using lift features
> (like surround, sitemap, headmerge), and I'd like to display it to the
> user when no handler can be found
>
> Whats preventing me from doing this is: the current notfound mechanism
> takes a liftResponse, not a template to render, and as such forces me
> to render the template itself, and although Russ proposed a way to do
> that Marius indicated this could have side effects and feels like the
> wrong approach.
>
>
> >
> >
> >
> >
> > > What about Either[RewriteResponse, LiftResponse]? E.g. same as what
> > > Marius suggested but use RewriteResponse instead of String.
> >
> > > On Dec 30, 1:26 pm, Marius <marius.dan...@gmail.com> wrote:
> > > > I thought of that but that is problematic because:
> >
> > > > 1. Having a TemplateResponse holding a path without the rendering
> > > > logic, people could use that to send a response to the client, which
> > > > would be incorrect as having a LiftResponse holding /a/b/c doesn;t
> > > > mean anything to a client. And this would alter the semantics of a
> > > > LiftResponse. That's why I proposed an Either.
> >
> > > > 2. On the other hand if we have a TemplateResponse holding the logic
> > > > of processing a template (similar to the one proposed on this thread)
> > > > would mean that we're doing the processing outside of the normal
> > > > rendering pipeline which has the downsides discussed.
> >
> > > > Br's,
> > > > Marius
> >
> > > > On Dec 30, 8:18 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> >
> > > > > Would it not be possible to have a LiftResponse that runs through
> the
> > > regular plumbing? This way instead of introducing Either you can just
> use a
> > > TemplateResponse etc.
> >
> > > > > -------------------------------------
> >
> > > > > Marius<marius.dan...@gmail.com> wrote:
> >
> > > > > Please open a defect herehttp://github.com/dpp/liftweb/issues...
> > > > > whether or not this solution will make it in master will be subject
> > > > > for reviewboard. The solution I proposed has a breaking change by
> the
> > > > > introduction of Either[List[String], LiftResponse] instead of
> > > > > LiftResponse but I don't think that many people are using
> uriNotFound
> > > > > and it's really quite a small change which regardless needs to be
> > > > > announced.
> >
> > > > > Other opinions on this?
> >
> > > > > Br's,
> > > > > Marius
> >
> > > > > On Dec 30, 6:20 pm, Alex Black <a...@alexblack.ca> wrote:
> >
> > > > > > > While I totally agree that a plain 404 + markup is much more
> > > > > > > straightforward,
> > > > > > > "breaks internet" are too big words :) .. sending back a
> > > > > > > 302 or 301 tells the UA "you asked me for a resource that I
> know I
> > > > > > > don't have but I wont tell
> > > > > > > you explicitely, instead I want you to go to this location as
> an
> > > > > > > alternative resource". Somehow it's like scratching with the
> wrong
> > > > > > > hand and purely from HTTP protocol perspective this is not
> quite
> > > > > > > straightforward as 404 + template, but I don't necessarily see
> it
> > > as a
> > > > > > > so bad thing.
> >
> > > > > > Heh, I apologise, definitely "breaking the internet" is a bit
> > > > > > dramatic.  I do have a different view than you though, I think
> its
> > > > > > incorrect to return a 301 or 302 in these scenarios, the correct
> > > > > > response is 404.  Not only is it the correct response, but given
> most
> > > > > > sites get 50%-90% of their traffic from Google, and Google thinks
> its
> > > > > > also correct to return 404 (
> http://www.google.com/url?sa=D&q=http://
> > > > > > googlewebmastercentral.blogspot.com/2008/08/farewell-to-
> > > > > > soft-404s.html, its in our best financial interest to play nice
> with
> > > > > > Google.
> >
> > > > > > > Specifically for 404 (when a template is not found we could do
> > > > > > > something like:
> >
> > > > > > > 1. In LiftRules instead of:
> >
> > > > > > > type URINotFoundPF = PartialFunction[(Req, Box[Failure]),
> > > > > > > LiftResponse]
> >
> > > > > > > use
> >
> > > > > > > type URINotFoundPF = PartialFunction[(Req, Box[Failure]),
> > > Either[List
> > > > > > > [String], LiftResponse]]
> >
> > > > > > > so that function can return a template path instead of
> response.
> >
> > > > > > > 2. In LiftSession#processRequest instead of applying the normal
> > > > > > > request pipeline only if the addressed template is found, we
> can
> > > use
> > > > > > > the path obtained from LiftRules.uriNotFound if Lift fails to
> find
> > > the
> > > > > > > normal tempalte. Hence apply the normal rendering pipeline to
> the
> > > > > > > template referenced by uriNotFound.
> >
> > > > > > > This approach allows your 404 case to be handled by the normal
> > > > > > > rendering pipeline without other hacks.
> >
> > > > > > > Unless someone thinks this is a bad solution, Alex you could
> open
> > > an
> > > > > > > issue and I'll work on it.
> >
> > > > > > Thanks for proposing that solution Marius.  I can't really
> comment on
> > > > > > whether or not its the right way to do it from Lift's point of
> view,
> > > > > > but as a user of Lift it sounds like it would work well.
> >
> > > > > > - Alex
> >
> > > > > --
> >
> > > > > 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<liftweb%2bunsubscr...@googlegroups.com>
> <liftweb%2bunsubscr...@googlegroups.com<liftweb%252bunsubscr...@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 lift...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com>
> <liftweb%2bunsubscr...@googlegroups.com<liftweb%252bunsubscr...@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 lift...@googlegroups.com.
> To unsubscribe from this group, send email to
> liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com>
> .
> 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

--

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