I'd like to handle 404s on my site in such a way that: - there is no redirect, e.g. if you type in a url like mysite.com/ foobarme, you'll stay at that url, so maybe you can correct it - the status code returned is 404 (not 200 OK)
But of course RewriteResponse is not a LiftResponse. Whats the best way to do this? Basically I've got a template called 404.html which I'd like to display whenever there is a 404.
I Just thought of something, perhaps I could add a RewriteRule that matches everything?
To be clear, RewriteResponse is a LiftResponse, and therefore, valid.
If you want to display the contents of your 404.html, checkout NodeResponse... just load up your template using the template helpers (this will give you NodeSeq) and then you can present that back to the user. Job done.
> But of course RewriteResponse is not a LiftResponse. Whats the best > way to do this? Basically I've got a template called 404.html which > I'd like to display whenever there is a 404.
> I Just thought of something, perhaps I could add a RewriteRule that > matches everything?
> If you want to display the contents of your 404.html, checkout NodeResponse... just load up your template using the template helpers (this will give you NodeSeq) and then you can present that back to the user. Job done.
I'll take a look, that sounds promising, thx. What are the template helpers? This sounds similar to using S.render, but I wasn't able to use that since I'm still on 1.0, it looks like it was added later. (I am considering moving to 1.1-M6).
> > But of course RewriteResponse is not a LiftResponse. Whats the best > > way to do this? Basically I've got a template called 404.html which > > I'd like to display whenever there is a 404.
> > I Just thought of something, perhaps I could add a RewriteRule that > > matches everything?
>> If you want to display the contents of your 404.html, checkout >> NodeResponse... just load up your template using the template >> helpers (this will give you NodeSeq) and then you can present that >> back to the user. Job done.
> I'll take a look, that sounds promising, thx. What are the template > helpers? This sounds similar to using S.render, but I wasn't able to > use that since I'm still on 1.0, it looks like it was added later. (I > am considering moving to 1.1-M6).
> - Alex
>> Cheers, Tim
>> On 29 Dec 2009, at 15:23, Alex Black wrote:
>>> But of course RewriteResponse is not a LiftResponse. Whats the best >>> way to do this? Basically I've got a template called 404.html which >>> I'd like to display whenever there is a 404.
>>> I Just thought of something, perhaps I could add a RewriteRule that >>> matches everything?
> --
> You received this message because you are subscribed to the Google > Groups "Lift" group. > To post to this group, send email to liftweb@googlegroups.com. > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com > . > For more options, visit this group at http://groups.google.com/group/liftweb?hl=en > .
> >> If you want to display the contents of your 404.html, checkout > >> NodeResponse... just load up your template using the template > >> helpers (this will give you NodeSeq) and then you can present that > >> back to the user. Job done.
> > I'll take a look, that sounds promising, thx. What are the template > > helpers? This sounds similar to using S.render, but I wasn't able to > > use that since I'm still on 1.0, it looks like it was added later. (I > > am considering moving to 1.1-M6).
> > - Alex
> >> Cheers, Tim
> >> On 29 Dec 2009, at 15:23, Alex Black wrote:
> >>> But of course RewriteResponse is not a LiftResponse. Whats the best > >>> way to do this? Basically I've got a template called 404.html which > >>> I'd like to display whenever there is a 404.
> >>> I Just thought of something, perhaps I could add a RewriteRule that > >>> matches everything?
> > --
> > You received this message because you are subscribed to the Google > > Groups "Lift" group. > > To post to this group, send email to liftweb@googlegroups.com. > > To unsubscribe from this group, send email to > liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@googlegroups.com > > . > For more options, visit this group at > http://groups.google.com/group/liftweb?hl=en.
M8 is pretty stable, yes. M7 was not, and so M6 was recommended before that. I haven't heard of any reason to recommend M6 over M8, but maybe dpp has some reasons.
> >> If you want to display the contents of your 404.html, checkout > >> NodeResponse... just load up your template using the template > >> helpers (this will give you NodeSeq) and then you can present that > >> back to the user. Job done.
> > I'll take a look, that sounds promising, thx. What are the template > > helpers? This sounds similar to using S.render, but I wasn't able to > > use that since I'm still on 1.0, it looks like it was added later. > (I > > am considering moving to 1.1-M6).
> > - Alex
> >> Cheers, Tim
> >> On 29 Dec 2009, at 15:23, Alex Black wrote:
> >>> But of course RewriteResponse is not a LiftResponse. Whats the > best > >>> way to do this? Basically I've got a template called 404.html > which > >>> I'd like to display whenever there is a 404.
> >>> I Just thought of something, perhaps I could add a RewriteRule > that > >>> matches everything?
> > --
> > You received this message because you are subscribed to the Google > > Groups "Lift" group. > > To post to this group, send email to liftweb@googlegroups.com. > > To unsubscribe from this group, send email to liftweb+unsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to liftweb+unsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com > . > For more options, visit this group at http://groups.google.com/group/liftweb?hl=en > .
> If you want to display the contents of your 404.html, checkout NodeResponse... just load up your template using the template helpers (this will give you NodeSeq) and then you can present that back to the user. Job done.
I am familiar with NodeResponse and its subclasses. I've used them in our REST api. But, what I can't figure out, is how to use them in conjuction with the templating engine as you seem to be alluding to (with the template helpers).
Can you point me in the right direction? I am going to try switching to M8 and then using S.render like this:
val node404 = <lift:surround with="default" at="content"> <h1>Not Found</h1> </lift:surround>
> > But of course RewriteResponse is not a LiftResponse. Whats the best > > way to do this? Basically I've got a template called 404.html which > > I'd like to display whenever there is a 404.
> > I Just thought of something, perhaps I could add a RewriteRule that > > matches everything?
> M8 is pretty stable, yes. M7 was not, and so M6 was recommended before > that. I haven't heard of any reason to recommend M6 over M8, but maybe > dpp has some reasons.
> -Ross
> On Dec 29, 2009, at 1:11 PM, Alex Black wrote:
>> Is M8 pretty stable? A little while back DavidP recommended M6 as >> being the most stable of the milestones.
>> On Tue, Dec 29, 2009 at 1:07 PM, Ross Mellgren <dri...@gmail.com >> <mailto:dri...@gmail.com>> wrote:
>> Switch to 1.1-M8, if you can.
>> -Ross
>> On Dec 29, 2009, at 1:04 PM, Alex Black wrote:
>> >> To be clear, RewriteResponse is a LiftResponse, and therefore, >> valid.
>> > I had tried it, and got a compile error, keep in mind I'm still on >> > 1.0:
>> >> If you want to display the contents of your 404.html, checkout >> >> NodeResponse... just load up your template using the template >> >> helpers (this will give you NodeSeq) and then you can present that >> >> back to the user. Job done.
>> > I'll take a look, that sounds promising, thx. What are the template >> > helpers? This sounds similar to using S.render, but I wasn't able to >> > use that since I'm still on 1.0, it looks like it was added >> later. (I >> > am considering moving to 1.1-M6).
>> > - Alex
>> >> Cheers, Tim
>> >> On 29 Dec 2009, at 15:23, Alex Black wrote:
>> >>> But of course RewriteResponse is not a LiftResponse. Whats the >> best >> >>> way to do this? Basically I've got a template called 404.html >> which >> >>> I'd like to display whenever there is a 404.
>> >>> I Just thought of something, perhaps I could add a RewriteRule >> that >> >>> matches everything?
>> > --
>> > You received this message because you are subscribed to the Google >> > Groups "Lift" group. >> > To post to this group, send email to liftweb@googlegroups.com >> <mailto:liftweb@googlegroups.com>. >> > To unsubscribe from this group, send email to >> liftweb+unsubscribe@googlegroups.com >> <mailto:liftweb%2Bunsubscribe@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 liftweb@googlegroups.com >> <mailto:liftweb@googlegroups.com>. >> To unsubscribe from this group, send email to >> liftweb+unsubscribe@googlegroups.com >> <mailto:liftweb%2Bunsubscribe@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 liftweb@googlegroups.com >> <mailto:liftweb@googlegroups.com>. >> To unsubscribe from this group, send email to >> liftweb+unsubscribe@googlegroups.com >> <mailto:liftweb+unsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/liftweb?hl=en.
> > If you want to display the contents of your 404.html, checkout NodeResponse... just load up your template using the template helpers (this will give you NodeSeq) and then you can present that back to the user. Job done.
> I am familiar with NodeResponse and its subclasses. I've used them in > our REST api. But, what I can't figure out, is how to use them in > conjuction with the templating engine as you seem to be alluding to > (with the template helpers).
> Can you point me in the right direction? I am going to try switching > to M8 and then using S.render like this:
> > > But of course RewriteResponse is not a LiftResponse. Whats the best > > > way to do this? Basically I've got a template called 404.html which > > > I'd like to display whenever there is a 404.
> > > I Just thought of something, perhaps I could add a RewriteRule that > > > matches everything?
On Tue, Dec 29, 2009 at 10:14 AM, Ross Mellgren <dri...@gmail.com> wrote: > M8 is pretty stable, yes. M7 was not, and so M6 was recommended before > that. I haven't heard of any reason to recommend M6 over M8, but maybe dpp > has some reasons.
Usually, HarryH and others find the lurking issues with a given milestone. There have not been any core issues with M8 over the last few weeks... so I think it's the blessed version.
>> >> If you want to display the contents of your 404.html, checkout >> >> NodeResponse... just load up your template using the template >> >> helpers (this will give you NodeSeq) and then you can present that >> >> back to the user. Job done.
>> > I'll take a look, that sounds promising, thx. What are the template >> > helpers? This sounds similar to using S.render, but I wasn't able to >> > use that since I'm still on 1.0, it looks like it was added later. (I >> > am considering moving to 1.1-M6).
>> > - Alex
>> >> Cheers, Tim
>> >> On 29 Dec 2009, at 15:23, Alex Black wrote:
>> >>> But of course RewriteResponse is not a LiftResponse. Whats the best >> >>> way to do this? Basically I've got a template called 404.html which >> >>> I'd like to display whenever there is a 404.
>> >>> I Just thought of something, perhaps I could add a RewriteRule that >> >>> matches everything?
>> > --
>> > You received this message because you are subscribed to the Google >> > Groups "Lift" group. >> > To post to this group, send email to liftweb@googlegroups.com. >> > To unsubscribe from this group, send email to >> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. >> To unsubscribe from this group, send email to >> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@googlegroups.com > > . > For more options, visit this group at > http://groups.google.com/group/liftweb?hl=en.
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.
> I'd offer to write the new wiki page - is there a way for me to get an > account on that wiki - or is it just for contributors?
> - Alex
> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > > > If you want to display the contents of your 404.html, checkout > NodeResponse... just load up your template using the template helpers (this > will give you NodeSeq) and then you can present that back to the user. Job > done.
> > I am familiar with NodeResponse and its subclasses. I've used them in > > our REST api. But, what I can't figure out, is how to use them in > > conjuction with the templating engine as you seem to be alluding to > > (with the template helpers).
> > Can you point me in the right direction? I am going to try switching > > to M8 and then using S.render like this:
> > > > But of course RewriteResponse is not a LiftResponse. Whats the best > > > > way to do this? Basically I've got a template called 404.html which > > > > I'd like to display whenever there is a 404.
> > > > I Just thought of something, perhaps I could add a RewriteRule that > > > > matches everything?
> --
> You received this message because you are subscribed to the Google Groups > "Lift" group. > To post to this group, send email to liftweb@googlegroups.com. > To unsubscribe from this group, send email to > liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@googlegroups.com > > . > For more options, visit this group at > http://groups.google.com/group/liftweb?hl=en.
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:
> 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" />
> > I'd offer to write the new wiki page - is there a way for me to get an > > account on that wiki - or is it just for contributors?
> > - Alex
> > On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > > > > If you want to display the contents of your 404.html, checkout > > NodeResponse... just load up your template using the template helpers (this > > will give you NodeSeq) and then you can present that back to the user. Job > > done.
> > > I am familiar with NodeResponse and its subclasses. I've used them in > > > our REST api. But, what I can't figure out, is how to use them in > > > conjuction with the templating engine as you seem to be alluding to > > > (with the template helpers).
> > > Can you point me in the right direction? I am going to try switching > > > to M8 and then using S.render like this:
> > > > On 29 Dec 2009, at 15:23, Alex Black wrote:
> > > > > But of course RewriteResponse is not a LiftResponse. Whats the best > > > > > way to do this? Basically I've got a template called 404.html which > > > > > I'd like to display whenever there is a 404.
> > > > > I Just thought of something, perhaps I could add a RewriteRule that > > > > > matches everything?
> > --
> > You received this message because you are subscribed to the Google Groups > > "Lift" group. > > To post to this group, send email to liftweb@googlegroups.com. > > To unsubscribe from this group, send email to > > liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@googlegroups.com > > > . > > For more options, visit this group at > >http://groups.google.com/group/liftweb?hl=en.
> 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:
>> 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" />
>>> I'd offer to write the new wiki page - is there a way for me to get an >>> account on that wiki - or is it just for contributors?
>>> - Alex
>>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: >>>>> If you want to display the contents of your 404.html, checkout >>> NodeResponse... just load up your template using the template helpers (this >>> will give you NodeSeq) and then you can present that back to the user. Job >>> done.
>>>> I am familiar with NodeResponse and its subclasses. I've used them in >>>> our REST api. But, what I can't figure out, is how to use them in >>>> conjuction with the templating engine as you seem to be alluding to >>>> (with the template helpers).
>>>> Can you point me in the right direction? I am going to try switching >>>> to M8 and then using S.render like this:
>>>>>> But of course RewriteResponse is not a LiftResponse. Whats the best >>>>>> way to do this? Basically I've got a template called 404.html which >>>>>> I'd like to display whenever there is a 404.
>>>>>> I Just thought of something, perhaps I could add a RewriteRule that >>>>>> matches everything?
>>> --
>>> You received this message because you are subscribed to the Google Groups >>> "Lift" group. >>> To post to this group, send email to liftweb@googlegroups.com. >>> To unsubscribe from this group, send email to >>> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
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.
> 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:
> >> 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" />
> >>> // If you're using a sitemap, make sure you have a catch-all item, > >>> e.g > >>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: Nil)) ::
> >>> I'd offer to write the new wiki page - is there a way for me to get an > >>> account on that wiki - or is it just for contributors?
> >>> - Alex
> >>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > >>>>> If you want to display the contents of your 404.html, checkout > >>> NodeResponse... just load up your template using the template helpers (this > >>> will give you NodeSeq) and then you can present that back to the user. Job > >>> done.
> >>>> I am familiar with NodeResponse and its subclasses. I've used them in > >>>> our REST api. But, what I can't figure out, is how to use them in > >>>> conjuction with the templating engine as you seem to be alluding to > >>>> (with the template helpers).
> >>>> Can you point me in the right direction? I am going to try switching > >>>> to M8 and then using S.render like this:
> >>>>> On 29 Dec 2009, at 15:23, Alex Black wrote:
> >>>>>> But of course RewriteResponse is not a LiftResponse. Whats the best > >>>>>> way to do this? Basically I've got a template called 404.html which > >>>>>> I'd like to display whenever there is a 404.
> >>>>>> I Just thought of something, perhaps I could add a RewriteRule that > >>>>>> matches everything?
> >>> --
> >>> You received this message because you are subscribed to the Google Groups > >>> "Lift" group. > >>> To post to this group, send email to liftweb@googlegroups.com. > >>> To unsubscribe from this group, send email to > >>> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com. > > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en.
<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.
> 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:
> > >> 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" />
> > >>> // If you're using a sitemap, make sure you have a catch-all item, > > >>> e.g > > >>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: Nil)) ::
> > >>> I'd offer to write the new wiki page - is there a way for me to get an > > >>> account on that wiki - or is it just for contributors?
> > >>> - Alex
> > >>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > > >>>>> If you want to display the contents of your 404.html, checkout > > >>> NodeResponse... just load up your template using the template helpers (this > > >>> will give you NodeSeq) and then you can present that back to the user. Job > > >>> done.
> > >>>> I am familiar with NodeResponse and its subclasses. I've used them in > > >>>> our REST api. But, what I can't figure out, is how to use them in > > >>>> conjuction with the templating engine as you seem to be alluding to > > >>>> (with the template helpers).
> > >>>> Can you point me in the right direction? I am going to try switching > > >>>> to M8 and then using S.render like this:
> > >>>>> On 29 Dec 2009, at 15:23, Alex Black wrote:
> > >>>>>> But of course RewriteResponse is not a LiftResponse. Whats the best > > >>>>>> way to do this? Basically I've got a template called 404.html which > > >>>>>> I'd like to display whenever there is a 404.
> > >>>>>> I Just thought of something, perhaps I could add a RewriteRule that > > >>>>>> matches everything?
> > >>> --
> > >>> You received this message because you are subscribed to the Google Groups > > >>> "Lift" group. > > >>> To post to this group, send email to liftweb@googlegroups.com. > > >>> To unsubscribe from this group, send email to > > >>> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > > > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com. > > > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en.
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:
> <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.
> > 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:
> > > >> 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" />
> > > >>> // If you're using a sitemap, make sure you have a catch-all item, > > > >>> e.g > > > >>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: Nil)) ::
> > > >>> I'd offer to write the new wiki page - is there a way for me to get an > > > >>> account on that wiki - or is it just for contributors?
> > > >>> - Alex
> > > >>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > > > >>>>> If you want to display the contents of your 404.html, checkout > > > >>> NodeResponse... just load up your template using the template helpers (this > > > >>> will give you NodeSeq) and then you can present that back to the user. Job > > > >>> done.
> > > >>>> I am familiar with NodeResponse and its subclasses. I've used them in > > > >>>> our REST api. But, what I can't figure out, is how to use them in > > > >>>> conjuction with the templating engine as you seem to be alluding to > > > >>>> (with the template helpers).
> > > >>>> Can you point me in the right direction? I am going to try switching > > > >>>> to M8 and then using S.render like this:
> > > >>>>> On 29 Dec 2009, at 15:23, Alex Black wrote:
> > > >>>>>> But of course RewriteResponse is not a LiftResponse. Whats the best > > > >>>>>> way to do this? Basically I've got a template called 404.html which > > > >>>>>> I'd like to display whenever there is a 404.
> > > >>>>>> I Just thought of something, perhaps I could add a RewriteRule that > > > >>>>>> matches everything?
> > > >>> --
> > > >>> You received this message because you are subscribed to the Google Groups > > > >>> "Lift" group. > > > >>> To post to this group, send email to liftweb@googlegroups.com. > > > >>> To unsubscribe from this group, send email to > > > >>> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. > > > > To unsubscribe from this group, send email to liftweb+unsubscribe@googlegroups.com. > > > > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en.
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) }
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.
> 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.
>>> 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:
>>>>>> 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" />
>>>>>>> // If you're using a sitemap, make sure you have a catch-all item, >>>>>>> e.g >>>>>>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: Nil)) ::
>>>>>>> I'd offer to write the new wiki page - is there a way for me to get an >>>>>>> account on that wiki - or is it just for contributors?
>>>>>>> - Alex
>>>>>>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: >>>>>>>>> If you want to display the contents of your 404.html, checkout >>>>>>> NodeResponse... just load up your template using the template helpers (this >>>>>>> will give you NodeSeq) and then you can present that back to the user. Job >>>>>>> done.
>>>>>>>> I am familiar with NodeResponse and its subclasses. I've used them in >>>>>>>> our REST api. But, what I can't figure out, is how to use them in >>>>>>>> conjuction with the templating engine as you seem to be alluding to >>>>>>>> (with the template helpers).
>>>>>>>> Can you point me in the right direction? I am going to try switching >>>>>>>> to M8 and then using S.render like this:
>>>>>>>>> On 29 Dec 2009, at 15:23, Alex Black wrote:
>>>>>>>>>> But of course RewriteResponse is not a LiftResponse. Whats the best >>>>>>>>>> way to do this? Basically I've got a template called 404.html which >>>>>>>>>> I'd like to display whenever there is a 404.
>>>>>>>>>> I Just thought of something, perhaps I could add a RewriteRule that >>>>>>>>>> matches everything?
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google Groups >>>>>>> "Lift" group. >>>>>>> To post to this group, send email to liftweb@googlegroups.com. >>>>>>> To unsubscribe from this group, send email to >>>>>>> liftweb+unsubscribe@googlegroups.com<liftweb%2Bunsubscribe@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 liftweb@googlegroups.com. >>>>> To unsubscribe from this group, send email to liftweb+unsubscribe@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
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) > }
> 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.
> >>> 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:
> >>>>>> 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" />
> >>>>>>> // If you're using a sitemap, make sure you have a catch-all item, > >>>>>>> e.g > >>>>>>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: Nil)) ::
> >>>>>>> I'd offer to write the new wiki page - is there a way for me to get an > >>>>>>> account on that wiki - or is it just for contributors?
> >>>>>>> - Alex
> >>>>>>> On Dec 29, 1:20 pm, Alex Black <a...@alexblack.ca> wrote: > >>>>>>>>> If you want to display the contents of your 404.html, checkout > >>>>>>> NodeResponse... just load up your template using the template helpers (this > >>>>>>> will give you NodeSeq) and then you can present that back to the user. Job > >>>>>>> done.
> >>>>>>>> I am familiar with NodeResponse and its subclasses. I've used them in > >>>>>>>> our REST api. But, what I can't figure out, is how to use them in > >>>>>>>> conjuction with the templating engine as you seem to be alluding to > >>>>>>>> (with the template helpers).
> >>>>>>>> Can you point me in the right direction? I am going to try switching > >>>>>>>> to M8 and then using S.render like this:
I'll try out that solution Russ, thanks. Although as the solution gets a bit more complex, and taking into account Marius's advice, it sounds like this might not be the right direction to go in.
Stepping back a moment, conceptually what I'd like to do is: create a nice 404.html template (using lift features like head merge and surround tags and sitemap), and then tell Lift to show this page to my users when it can't find a handler for the url requested.
Conceptually a nice solution might be:
LiftRules.uriNotFound.prepend { case _ => RewriteResponse("404.html") }
Any other opinions on Russ's solution? Is it the right way to go? Or is there another way? Or perhaps could we propose an enhancement to Lift to handle this well?
To Marius's question about why I (and perhaps others) don't want to use a redirect:
It breaks the internet. The way its meant to work is: a user-agent (either browser, or crawler etc) asks a web server for a resource by url, the web server should respond with code 404 if it can't find the resource. Your proposal would have it respond with code 301 which tells the user-agent that the resource was located but its moved.
LIft is generally very good I've found at making it easy to build good internet applications the *right* way. Examples include: its easy to build rest-ful APIs and return the correct response codes, its easy to re-write urls to have friendly urls for users, its easy to build XHTML compliant pages etc.
This is one of those areas where we (the lift community) should make sure that Lift makes it easy to do things the right way. Unlike say Microsoft of the past where they continually broke internet standards and made it easy to do things the wrong way!
- Alex
On Dec 30, 4:32 am, Marius <marius.dan...@gmail.com> 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.
> > 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.
> > >>> 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:
> > >>>>>> 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" />
> I'll try out that solution Russ, thanks. Although as the solution > gets a bit more complex, and taking into account Marius's advice, it > sounds like this might not be the right direction to go in.
> Stepping back a moment, conceptually what I'd like to do is: create a > nice 404.html template (using lift features like head merge and > surround tags and sitemap), and then tell Lift to show this page to my > users when it can't find a handler for the url requested.
> Conceptually a nice solution might be:
> LiftRules.uriNotFound.prepend { > case _ => RewriteResponse("404.html") > }
> Any other opinions on Russ's solution? Is it the right way to go? Or > is there another way? Or perhaps could we propose an enhancement to > Lift to handle this well?
> To Marius's question about why I (and perhaps others) don't want to > use a redirect:
> It breaks the internet. The way its meant to work is: a user-agent > (either browser, or crawler etc) asks a web server for a resource by > url, the web server should respond with code 404 if it can't find the > resource. Your proposal would have it respond with code 301 which > tells the user-agent that the resource was located but its moved.
> LIft is generally very good I've found at making it easy to build good > internet applications the *right* way. Examples include: its easy to > build rest-ful APIs and return the correct response codes, its easy to > re-write urls to have friendly urls for users, its easy to build XHTML > compliant pages etc.
> This is one of those areas where we (the lift community) should make > sure that Lift makes it easy to do things the right way. Unlike say > Microsoft of the past where they continually broke internet standards > and made it easy to do things the wrong way!
> - Alex
> On Dec 30, 4:32 am, Marius <marius.dan...@gmail.com> 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.
> > > 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.
> > > >>> 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:
> > > >>>>>> 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:
> I'll try out that solution Russ, thanks. Although as the solution > gets a bit more complex, and taking into account Marius's advice, it > sounds like this might not be the right direction to go in.
> Stepping back a moment, conceptually what I'd like to do is: create a > nice 404.html template (using lift features like head merge and > surround tags and sitemap), and then tell Lift to show this page to my > users when it can't find a handler for the url requested.
> Conceptually a nice solution might be:
> LiftRules.uriNotFound.prepend { > case _ => RewriteResponse("404.html") > }
> Any other opinions on Russ's solution? Is it the right way to go? Or > is there another way? Or perhaps could we propose an enhancement to > Lift to handle this well?
> To Marius's question about why I (and perhaps others) don't want to > use a redirect:
> It breaks the internet. The way its meant to work is: a user-agent > (either browser, or crawler etc) asks a web server for a resource by > url, the web server should respond with code 404 if it can't find the > resource. Your proposal would have it respond with code 301 which > tells the user-agent that the resource was located but its moved.
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.
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.
> LIft is generally very good I've found at making it easy to build good > internet applications the *right* way. Examples include: its easy to > build rest-ful APIs and return the correct response codes, its easy to > re-write urls to have friendly urls for users, its easy to build XHTML > compliant pages etc.
> This is one of those areas where we (the lift community) should make > sure that Lift makes it easy to do things the right way. Unlike say > Microsoft of the past where they continually broke internet standards > and made it easy to do things the wrong way!
> - Alex
> On Dec 30, 4:32 am, Marius <marius.dan...@gmail.com> 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.
> > > 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.
> > > >>> 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
Ouch, it does sound ugly. Is there some alternative way to change the currently requested URI, for the purposes of sitemap generation and so on? It seems like the alternative is spinning one's own SiteMap menu snippet that knows to do this work?
Also, it seems odd there's no way to invoke the normal template flow even barring the re-init of S. The closest you can get that I know of is LiftSession.processSurroundAndInclude or S.render, but neither of those do head merge which seems to be a very key part of the rendering pipeline. Perhaps I'm misreading the code? It looks like LiftMerge.merge is called from LiftSession.processRequest which is called from LiftServlet.dispatchStatefulRequest, and so on, all private to net.liftweb.http.
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?
> 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) >> }
>> 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.
>>>>> 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:
>>>>>>>> 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" />
>>>>>>>>> // If you're using a sitemap, make sure you have a catch- >>>>>>>>> all item, >>>>>>>>> e.g >>>>>>>>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: >>>>>>>>> Nil)) ::
> Ouch, it does sound ugly. Is there some alternative way to change the > currently requested URI, for the purposes of sitemap generation and so > on? It seems like the alternative is spinning one's own SiteMap menu > snippet that knows to do this work?
> Also, it seems odd there's no way to invoke the normal template flow > even barring the re-init of S. The closest you can get that I know of > is LiftSession.processSurroundAndInclude or S.render, but neither of > those do head merge which seems to be a very key part of the rendering > pipeline. Perhaps I'm misreading the code? It looks like > LiftMerge.merge is called from LiftSession.processRequest which is > called from LiftServlet.dispatchStatefulRequest, and so on, all > private to net.liftweb.http.
> 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?
> -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.
> >> 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.
> >>>>> 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:
> >>>>>>>> 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" />
> 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.
> 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.
> > 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.
> >> 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.
> >>>>> 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:
> >>>>>>>> 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" />
> >>>>>>>>> // If you're using a sitemap, make sure you have a catch- > >>>>>>>>> all item, > >>>>>>>>> e.g > >>>>>>>>> // Menu(Loc("Catchall", Pair(Nil, true), "", Hidden :: > >>>>>>>>> Nil)) ::