From: Ian B. <ia...@co...> - 2004-04-19 16:01:11
|
I haven't been using actions very much up until now, but I used them in the Wiki and found the method layout to be suboptimal. I think other people have had the same experience. Anyway, I'll describe what I did and see what people's reactions are. First, preAction and postAction do nothing. Second, _respond invokes writeHTML always, not just when no action was found. Third, defaultAction sets self.view = 'writeContent'; other actions set it to other values. In writeBodyParts, I do: def writeBodyParts(self): getattr(self, self.view)() And actually if view is None, then writeHTML doesn't do anything (which is what I set when writing non-HTML output). Then each action does its thing, kind of like awake (but in addition to awake, which is always called) and then chooses its "view". On a form submittal, for instance, it may choose a view where it shows success, or if there were errors it may show the original form view. Often in title() I code in some different values depending on the view, there might be a better way to do that (e.g., make the title a function attribute of the view method). But anyway, at least it's possible to change some of those non-content parts of the page depending on the action. I'm not sure how this fits into what people are doing with _action_ right now. I played around with adding this pattern to Component.CPage, but I want that to be backward compatible so maybe that won't work. Ian |
From: Eric R. <th...@er...> - 2004-04-19 17:15:23
|
On 11:00 Mon 19 Apr , Ian Bicking wrote: > I'm not sure how this fits into what people are doing with _action_ > right now. My preference is that actions would do very little by default. I've had to fight with actions because they're presumptuous. I would like to see actions simplified--I don't want smart actions, I want dumb actions that require following functions to be called explicitly. Eric |
From: Matt F. <ma...@da...> - 2004-04-19 18:05:48
|
Ian Bicking wrote: > I haven't been using actions very much up until now, but I used them > in the Wiki and found the method layout to be suboptimal. I think > other people have had the same experience. Yep. We've been grouchy about this for a couple of years. We made very similar changes to what you describe in our FormKit. > Second, _respond invokes writeHTML always, not just when no action was > found. Yes, this is what should happen; UNLESS there's a redirect pending. Many times, after we do an action, we want to redirect to another URI. We do a check in writeHTML and bail if necessary, but I've always thought that it should be "deeper" in the servlet, perhaps in _respond() (or before; see next thought). What do people think about making the action calls come from the awake() step rather than the respond() step? I think that respond is about sending data to the client; typically full of writeln() calls. Actions don't seem to be for that; they seem to be for writing to databases, parsing form input, setting state, etc. These things seem like they should come before "respond". Basically, what we'd like to see in the "new lifecycle" would be something like: 1. wake up (get connections to databases, open session, whatever) 2. do any business that's required (run a query, parse a file, whatever) 3. send output, which is either a redirect or content 4. go to sleep (close connections, etc.) We always do step 2 things in actions, but have always thought that they shouldn't be jacked into this "pre-respond" place. |
From: Ian B. <ia...@co...> - 2004-04-19 18:38:47
|
Matt Feifarek wrote: > Ian Bicking wrote: >> I haven't been using actions very much up until now, but I used them >> in the Wiki and found the method layout to be suboptimal. I think >> other people have had the same experience. > > Yep. We've been grouchy about this for a couple of years. We made very > similar changes to what you describe in our FormKit. > >> Second, _respond invokes writeHTML always, not just when no action was >> found. > > Yes, this is what should happen; UNLESS there's a redirect pending. Many > times, after we do an action, we want to redirect to another URI. We do > a check in writeHTML and bail if necessary, but I've always thought that > it should be "deeper" in the servlet, perhaps in _respond() (or before; > see next thought). If you're using Page.sendRedirectAndEnd it won't be a problem -- that immediately terminates the request. (I think it still calls sleep, but that's it) > What do people think about making the action calls come from the awake() > step rather than the respond() step? I think that respond is about > sending data to the client; typically full of writeln() calls. Actions > don't seem to be for that; they seem to be for writing to databases, > parsing form input, setting state, etc. These things seem like they > should come before "respond". > > Basically, what we'd like to see in the "new lifecycle" would be > something like: > > 1. wake up (get connections to databases, open session, whatever) > 2. do any business that's required (run a query, parse a file, whatever) > 3. send output, which is either a redirect or content > 4. go to sleep (close connections, etc.) > > We always do step 2 things in actions, but have always thought that they > shouldn't be jacked into this "pre-respond" place. With the technique I describe it's really a 4 step cycle -- run awake, run the action (always some action, if only defaultAction), run writeHTML, run sleep. Technically the action and writeHTML happen in respond, but you only see the respond method when you are looking at it from WebKit's perspective. An an application author I never override that, so it's not a problem. Where you write output is really a matter of convention -- you can do it anywhere, even in sleep. I like the idea of the action and awake being separate, where awake is a kind of general setup and action is specific. You'll still want the general setup, because presumably there's something that ties all the actions together into a single servlet. So I think four steps are called for. If this gets added to awake, it would be awkward, because Page.awake would invoke your actions before you had a chance to do your servlet-specific actions. Also note, though, that the awake/respond/sleep sequence is less hard coded (in CVS) than it was before -- you can override all three with runTransaction. So another completely separate method could be added to that sequence. But I also don't think it's so bad to add it to respond, so long as it happens before writeHTML (but not in lieu of writeHTML). Ian |
From: Matt F. <ma...@da...> - 2004-04-19 19:16:23
|
Ian Bicking wrote: > If you're using Page.sendRedirectAndEnd it won't be a problem -- that > immediately terminates the request. (I think it still calls sleep, > but that's it) Yeah, that's new. We are using it, but it's weirdly inconsistent and changes behavior depending on when it is called. There's been some discussion about it in the list here. I think that the general consensus is that one shouldn't conditionally run sleep; it should probably always fire. For this reason, we actually like our old crufty way better. > Where you write output is really a matter of convention -- you can do > it anywhere, even in sleep. Yes, but for the sake of docs, new users, and such, it would be good to recommend "best practices". If you do output in sleep, does it end up after the </html> bit? > Also note, though, that the awake/respond/sleep sequence is less hard > coded (in CVS) than it was before -- you can override all three with > runTransaction. So another completely separate method could be added > to that sequence. But I also don't think it's so bad to add it to > respond, so long as it happens before writeHTML (but not in lieu of > writeHTML). > Cool. I'll look into that. Don't forget that not all servlets make HTML; I've got some that make images and such. It's more useful to think of respond as "output" (and request as input) for our purposes, I think. After having this and similar discussions on this list over the years, the trouble seems to be in what people think awake is for. One of the strengths of webkit (IMO) is that it can be so low-level; you can use the lifecycle model to do whatever you want, but this leads to a confusion: 1. some people think awake is for nothing; that we should leave it only for webkit's dark magic 2. some people think awake is for setup, but not for application-level logic (ie, database connections, security stuff, etc.) 3. some people think awake is for setup at the low-level, and at the application-level I like number 3. If you think of a servlet as an application logic object (well, it is an object, duh, but bear with me) then it should have certain methods that correspond to certain events. Actions seem to be the way to manage this sort of thing. Once you've done that, you can output, or redirect, which I consider a special-case of output that is only html specific. Number 3 is pretty easy to do by subclassing and keeping careful track of MRO. Another problem is that I don't think you can fire more than one action on one servlet, so they end up being "meta-methods" sometimes, and therefore look more like event handlers. I'm not making much sense, I guess. It's one of those flexibility get's you power, but also get's you confusion things. I agree that putting actions in awake could lead to awkwardness. It seems crufty to have two parallel processes for actions, though... actions and pseudo-actions? :-) |
From: Ian B. <ia...@co...> - 2004-04-20 03:29:31
|
On Apr 19, 2004, at 2:21 PM, Matt Feifarek wrote: > Ian Bicking wrote: >> If you're using Page.sendRedirectAndEnd it won't be a problem -- that >> immediately terminates the request. (I think it still calls sleep, >> but that's it) > > Yeah, that's new. We are using it, but it's weirdly inconsistent and > changes behavior depending on when it is called. There's been some > discussion about it in the list here. I think that the general > consensus is that one shouldn't conditionally run sleep; it should > probably always fire. For this reason, we actually like our old crufty > way better. Sleep should always be called. Hmmm... but that may have changed between versions. Right now there's: try: self.awake(trans) self.respond(trans) finally: self.sleep(trans) I don't think that's always been the way it's been implemented. >> Where you write output is really a matter of convention -- you can do >> it anywhere, even in sleep. > > Yes, but for the sake of docs, new users, and such, it would be good > to recommend "best practices". If you do output in sleep, does it end > up after the </html> bit? Certainly, best practices are called for. In many ways this is half documentation -- functionally it's all pretty freeform how you use your servlet; those factorings are just in there as a suggestion. But we should suggest. >> Also note, though, that the awake/respond/sleep sequence is less hard >> coded (in CVS) than it was before -- you can override all three with >> runTransaction. So another completely separate method could be added >> to that sequence. But I also don't think it's so bad to add it to >> respond, so long as it happens before writeHTML (but not in lieu of >> writeHTML). >> > Cool. I'll look into that. > > Don't forget that not all servlets make HTML; I've got some that make > images and such. It's more useful to think of respond as "output" (and > request as input) for our purposes, I think. Yes. Page's writeHTML implementation really *does* focus on HTML, in that it factors the page into various pieces (head, body, title stylesheet, etc). Another way to do this would be to call writeHTML in defaultAction (like we are now), and expect actions to call writeHTML when they are done (if they actually want to write HTML). This actually means less changes to code, and more just specifying a certain pattern. (preAction and postAction should be no-ops, though.) I found the view part useful as well, but I'm not sure if everyone would use that. I'd find it useful in components, though, and that would require some agreement. > After having this and similar discussions on this list over the years, > the trouble seems to be in what people think awake is for. One of the > strengths of webkit (IMO) is that it can be so low-level; you can use > the lifecycle model to do whatever you want, but this leads to a > confusion: > > 1. some people think awake is for nothing; that we should leave it > only for webkit's dark magic > 2. some people think awake is for setup, but not for application-level > logic (ie, database connections, security stuff, etc.) > 3. some people think awake is for setup at the low-level, and at the > application-level > > I like number 3. If you think of a servlet as an application logic > object (well, it is an object, duh, but bear with me) then it should > have certain methods that correspond to certain events. Actions seem > to be the way to manage this sort of thing. Once you've done that, you > can output, or redirect, which I consider a special-case of output > that is only html specific. Number 3 is pretty easy to do by > subclassing and keeping careful track of MRO. I use 3 too, though I've sometimes added a "self.setup()" to my SitePage, and allowed servlets to override that instead of awake. It's more consistent because it has no trans argument, and I define it so that you never have to call the superclass (since I put all the abstract stuff in awake()). But that's kind of a separate detail -- but it does separate "framework" setup and "servlet" setup (where I think of my SitePage as a mini-framework). > Another problem is that I don't think you can fire more than one > action on one servlet, so they end up being "meta-methods" sometimes, > and therefore look more like event handlers. I think I'm losing you here. IMHO, anything more complicated than actions (i.e., specified in a field; one action per request) should be coded explicitly. > I'm not making much sense, I guess. It's one of those flexibility > get's you power, but also get's you confusion things. > > I agree that putting actions in awake could lead to awkwardness. It > seems crufty to have two parallel processes for actions, though... > actions and pseudo-actions? :-) > -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Aaron H. <aaron@MetroNY.com> - 2004-04-20 13:37:57
|
I like actions the way they are - they are very simple to understand. If you have a hello "Aaron" type app its easy to setup a servlet like def writeContent(self): self.write('<form><input type="text" name="username"><submit name="_acctionHello"</form>'); def hello(self): self.write('Hello %s' % self.request().value('username','No User Name')) If you need a more complex action style you can switch to one of the formKits or move to some MVC type approach. I vote to leave actions as they are - but provide more robust solutions for other needs. Maybe a split page into basePage and ActionPage(basePage) where basePage provide all of the helper functions in page = except the actions. But for that matter we could just offer a newPage(page) class taht would change the way action works. You can't change actions (IMHO) without chaging the writeHead-writeBanner-WriteContent-writeFooter style of page. It makes sence in that context. If you go off and do strange things like Cheetah or serving images - then maybe having actions just speak up in the content phase is wrong. -Aaron Ian Bicking wrote: > On Apr 19, 2004, at 2:21 PM, Matt Feifarek wrote: > >> Ian Bicking wrote: >> >>> If you're using Page.sendRedirectAndEnd it won't be a problem -- >>> that immediately terminates the request. (I think it still calls >>> sleep, but that's it) >> >> >> Yeah, that's new. We are using it, but it's weirdly inconsistent and >> changes behavior depending on when it is called. There's been some >> discussion about it in the list here. I think that the general >> consensus is that one shouldn't conditionally run sleep; it should >> probably always fire. For this reason, we actually like our old >> crufty way better. > > > Sleep should always be called. Hmmm... but that may have changed > between versions. Right now there's: > > try: > self.awake(trans) > self.respond(trans) > finally: > self.sleep(trans) > > I don't think that's always been the way it's been implemented. > >>> Where you write output is really a matter of convention -- you can >>> do it anywhere, even in sleep. >> >> >> Yes, but for the sake of docs, new users, and such, it would be good >> to recommend "best practices". If you do output in sleep, does it end >> up after the </html> bit? > > > Certainly, best practices are called for. In many ways this is half > documentation -- functionally it's all pretty freeform how you use > your servlet; those factorings are just in there as a suggestion. But > we should suggest. > >>> Also note, though, that the awake/respond/sleep sequence is less >>> hard coded (in CVS) than it was before -- you can override all three >>> with runTransaction. So another completely separate method could be >>> added to that sequence. But I also don't think it's so bad to add >>> it to respond, so long as it happens before writeHTML (but not in >>> lieu of writeHTML). >>> >> Cool. I'll look into that. >> >> Don't forget that not all servlets make HTML; I've got some that make >> images and such. It's more useful to think of respond as "output" >> (and request as input) for our purposes, I think. > > > Yes. Page's writeHTML implementation really *does* focus on HTML, in > that it factors the page into various pieces (head, body, title > stylesheet, etc). > > Another way to do this would be to call writeHTML in defaultAction > (like we are now), and expect actions to call writeHTML when they are > done (if they actually want to write HTML). This actually means less > changes to code, and more just specifying a certain pattern. > (preAction and postAction should be no-ops, though.) I found the view > part useful as well, but I'm not sure if everyone would use that. I'd > find it useful in components, though, and that would require some > agreement. > >> After having this and similar discussions on this list over the >> years, the trouble seems to be in what people think awake is for. One >> of the strengths of webkit (IMO) is that it can be so low-level; you >> can use the lifecycle model to do whatever you want, but this leads >> to a confusion: >> >> 1. some people think awake is for nothing; that we should leave it >> only for webkit's dark magic >> 2. some people think awake is for setup, but not for >> application-level logic (ie, database connections, security stuff, etc.) >> 3. some people think awake is for setup at the low-level, and at the >> application-level >> >> I like number 3. If you think of a servlet as an application logic >> object (well, it is an object, duh, but bear with me) then it should >> have certain methods that correspond to certain events. Actions seem >> to be the way to manage this sort of thing. Once you've done that, >> you can output, or redirect, which I consider a special-case of >> output that is only html specific. Number 3 is pretty easy to do by >> subclassing and keeping careful track of MRO. > > > I use 3 too, though I've sometimes added a "self.setup()" to my > SitePage, and allowed servlets to override that instead of awake. > It's more consistent because it has no trans argument, and I define it > so that you never have to call the superclass (since I put all the > abstract stuff in awake()). But that's kind of a separate detail -- > but it does separate "framework" setup and "servlet" setup (where I > think of my SitePage as a mini-framework). > >> Another problem is that I don't think you can fire more than one >> action on one servlet, so they end up being "meta-methods" sometimes, >> and therefore look more like event handlers. > > > I think I'm losing you here. IMHO, anything more complicated than > actions (i.e., specified in a field; one action per request) should be > coded explicitly. > >> I'm not making much sense, I guess. It's one of those flexibility >> get's you power, but also get's you confusion things. >> >> I agree that putting actions in awake could lead to awkwardness. It >> seems crufty to have two parallel processes for actions, though... >> actions and pseudo-actions? :-) >> > -- > Ian Bicking | ia...@co... | http://blog.ianbicking.org > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Webware-discuss mailing list > Web...@li... > https://lists.sourceforge.net/lists/listinfo/webware-discuss -- -Aaron http://www.MetroNY.com/ "I don't know what's wrong with my television set. I was getting C-Span and the Home Shopping Network on the same station. I actually bought a congressman." - Bruce Baum |
From: Ian B. <ia...@co...> - 2004-04-20 15:42:24
|
Aaron Held wrote: > I like actions the way they are - they are very simple to understand. > If you have a hello "Aaron" type app its easy to setup a servlet like > > def writeContent(self): > self.write('<form><input type="text" name="username"><submit > name="_acctionHello"</form>'); > > def hello(self): > self.write('Hello %s' % self.request().value('username','No User Name')) Where it gets all annoying, though, is preAction and postAction, which are like an anemic form of the writeHTML, writeHead, writeTitle, writeStyleSheet etc. setup that Page has for normal requests. Or, where you don't want to write anything, but way to treat the action as an action (i.e., something that does something, not something that merely changes the display) -- there again preAction and postAction get in the way. Ian |
From: Eric R. <th...@er...> - 2004-04-20 20:08:49
|
On 10:41 Tue 20 Apr , Ian Bicking wrote: > Aaron Held wrote: > >I like actions the way they are - they are very simple to understand. > >If you have a hello "Aaron" type app its easy to setup a servlet like > > > >def writeContent(self): > > self.write('<form><input type="text" name="username"><submit > >name="_acctionHello"</form>'); > > > >def hello(self): > > self.write('Hello %s' % self.request().value('username','No User Name')) > > Where it gets all annoying, though, is preAction and postAction, which > are like an anemic form of the writeHTML, writeHead, writeTitle, > writeStyleSheet etc. setup that Page has for normal requests. Or, where > you don't want to write anything, but way to treat the action as an > action (i.e., something that does something, not something that merely > changes the display) -- there again preAction and postAction get in the way. > > Ian Amen! Unless you're building a demo, you have specific requirements for the output. I would like to see the extraneous functions removed. Eric |
From: Aaron H. <aaron@MetroNY.com> - 2004-04-20 21:08:59
|
>>Where it gets all annoying, though, is preAction and postAction, which >>are like an anemic form of the writeHTML, writeHead, writeTitle, >>writeStyleSheet etc. setup that Page has for normal requests. Or, where >>you don't want to write anything, but way to treat the action as an >>action (i.e., something that does something, not something that merely >>changes the display) -- there again preAction and postAction get in the way. >> >> Ian >> >> I think Ian hit on it. I like actions when you have basic read a variable - write out the same page with some differnet text. However when you want to use an action as an action then it all gets in the way. The current action system is very easy to understand and IMHO a great path to a first webware app. Once you gain some higher enlightenment you will use some MVC technique or FormKit or roll your own. My point as this: I would like to see action stay in the basic setup as a part of Page, but I would also like to see some more advanced version of page for others to use. Look at other basic examples for PHP/JSP/ASP and you will see the same type of code: 1)start writing the page 2) If there is a request var print something 3) If there is no request print a form -Aaron >------------------------------------------------------- >This SF.Net email is sponsored by: IBM Linux Tutorials >Free Linux tutorial presented by Daniel Robbins, President and CEO of >GenToo technologies. Learn everything from fundamentals to system >administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click >_______________________________________________ >Webware-discuss mailing list >Web...@li... >https://lists.sourceforge.net/lists/listinfo/webware-discuss > > -- -Aaron http://www.MetroNY.com/ "I don't know what's wrong with my television set. I was getting C-Span and the Home Shopping Network on the same station. I actually bought a congressman." - Bruce Baum |
From: Matt F. <ma...@da...> - 2004-04-20 20:31:16
|
Ian Bicking wrote: > Where it gets all annoying, though, is preAction and postAction, which > are like an anemic form of the writeHTML, writeHead, writeTitle, > writeStyleSheet etc. setup that Page has for normal requests. Or, > where you don't want to write anything, but way to treat the action as > an action (i.e., something that does something, not something that > merely changes the display) -- there again preAction and postAction > get in the way. > There's a diagram in the docs for our FormKit that may help clarify the situation: http://dalchemy.com/opensource/formkit/architecture.html About half way down. For form processing, we changed pre-action and post-action to merge the lifecycle more closely back into the normal respond; basically, we call writeHTML from post-action, which effectively inserts actions in *before* the output, rather than doing "some" of the output in pre/post. |
From: Ian B. <ia...@co...> - 2004-04-20 20:53:31
|
Matt Feifarek wrote: > There's a diagram in the docs for our FormKit that may help clarify the > situation: > > http://dalchemy.com/opensource/formkit/architecture.html > > About half way down. > > For form processing, we changed pre-action and post-action to merge the > lifecycle more closely back into the normal respond; basically, we call > writeHTML from post-action, which effectively inserts actions in > *before* the output, rather than doing "some" of the output in pre/post. Yes, that's pretty much what I was thinking too -- I was putting writeHTML in respond, but it fits more cleanly in postAction. Another option would be to require the action author to call writeHTML manually. When you are creating non-HTML content based on an action this can be convenience -- specifically, external editor support in the wiki does this for one action, but all the other actions do normal HTML processing. The way I do it there is with the special view attribute, where writeHTML is entirely suppressed if ``not self.view``. But requiring an explicit call to writeHTML would also work, and wouldn't require any very dramatic changes to Page (really, just a change to convention). Ian |
From: jose <jo...@cy...> - 2004-04-22 05:22:28
|
Just thought I would chime in to the whole actions debate. Essentially we were finding preAction and postAction pretty difficult to use, and ended up doing two things. First we extended page to include modified version of pre and post action along with a bunch of other "dynamic" functions that would let us change the title, header and a bunch of other things dynamically depending on which action we called. This worked well, however was very complicated. Now we have moved much of our actual html out of the servlets and into templates, so we really don't need all the pre and post action stuff, actions are no different then the initial writeContent now, if an action needs to write a page it outputs content to a template otherwise we just either redirect to another page or call the default page at the end of the action. We've also modified the _request function so that servlet.py?do_action will invoke the action (note that do_action is not set to anything so it never ends up in fieldStorage) Hope this makes sense Jose -----Original Message----- From: web...@li... [mailto:web...@li...] On Behalf Of Ian Bicking Sent: Tuesday, April 20, 2004 1:53 PM To: Matt Feifarek Cc: web...@li... Subject: Re: [Webware-discuss] Changing actions Matt Feifarek wrote: > There's a diagram in the docs for our FormKit that may help clarify > the > situation: > > http://dalchemy.com/opensource/formkit/architecture.html > > About half way down. > > For form processing, we changed pre-action and post-action to merge > the > lifecycle more closely back into the normal respond; basically, we call > writeHTML from post-action, which effectively inserts actions in > *before* the output, rather than doing "some" of the output in pre/post. Yes, that's pretty much what I was thinking too -- I was putting writeHTML in respond, but it fits more cleanly in postAction. Another option would be to require the action author to call writeHTML manually. When you are creating non-HTML content based on an action this can be convenience -- specifically, external editor support in the wiki does this for one action, but all the other actions do normal HTML processing. The way I do it there is with the special view attribute, where writeHTML is entirely suppressed if ``not self.view``. But requiring an explicit call to writeHTML would also work, and wouldn't require any very dramatic changes to Page (really, just a change to convention). Ian ------------------------------------------------------- This SF.Net email is sponsored by: IBM Linux Tutorials Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click _______________________________________________ Webware-discuss mailing list Web...@li... https://lists.sourceforge.net/lists/listinfo/webware-discuss |
From: Matt F. <ma...@da...> - 2004-04-20 21:08:48
|
Here is a proposal: 1. having a "default action" construct that defaults to None, but can be set in a SitePage. If an action is in the request, it's run instead of default. 2. There be a method in page that sets a redirect address, but DOES NOT end the transaction. I suggest .setRedirectURI( ). Of course, the default redirect address would be None. 3. The lifecycle of a servlet is preserved: awake/respond/sleep, with actions continuing to be called from respond, at the beginning of respond 4. After any actions are run, respond does one of two things, depending on the "pending redirect" instance attribute that I mentioned: - if it's non-empty, sends a redirect header to the browser based on the value - if it's empty, it calls writeHTML (or whatever analog for non-html http servlets) This means that unless you set a redirect, all pages, with and without actions, will call the *normal* writeHTML chain, rather than the stumpy one that's in preAction and postAction now. Also, this keeps what is in effect a "pre-respond", although it's called from respond. An argument can be made that this part should happen in awake, but that is likely to cause greater incompatibility, and I'm shying away from it. Perhaps Aaron's suggestion of having two types of page; one that has the whole pre-respond/action thing, and one that doesn't is a good one. Though, this is so trivial that a simple if/else test in one servlet could easily do it. Plus, I like the idea of there being a default action method to run if there's nothing explicit. An alternative to the above proposal would be Ian's idea of "writeHTML" being the default action, but I still don't like the idea of "output" being an action. |
From: Ian B. <ia...@co...> - 2004-04-22 04:50:41
|
On Apr 20, 2004, at 4:14 PM, Matt Feifarek wrote: > Here is a proposal: > > 1. having a "default action" construct that defaults to None, but can > be set in a SitePage. If an action is in the request, it's run instead > of default. We have defaultAction now. It's only wonky because it doesn't call preAction/postAction, where all other actions do. But if we get rid of those, then it's not a problem. Anyway, defaultAction now just calls writeHTML. > 2. There be a method in page that sets a redirect address, but DOES > NOT end the transaction. I suggest .setRedirectURI( ). Of course, the > default redirect address would be None. I'm still not clear what the problems are with sendRedirectAndEnd()? If there's a bug there we should fix it -- otherwise we're fine right now. > 3. The lifecycle of a servlet is preserved: awake/respond/sleep, with > actions continuing to be called from respond, at the beginning of > respond > > 4. After any actions are run, respond does one of two things, > depending on the "pending redirect" instance attribute that I > mentioned: > - if it's non-empty, sends a redirect header to the browser based > on the value > - if it's empty, it calls writeHTML (or whatever analog for > non-html http servlets) Right now there's no analog for non-HTML output. You just override writeHTML and write other text. It's a misnomer, but it works fine. However, for some actions you may wish to suppress writeHTML. Of course you can code this yourself (setting some flag), but it might be nice to include. Forcing writeHTML to be called by the action would serve to do this. > This means that unless you set a redirect, all pages, with and without > actions, will call the *normal* writeHTML chain, rather than the > stumpy one that's in preAction and postAction now. > > Also, this keeps what is in effect a "pre-respond", although it's > called from respond. An argument can be made that this part should > happen in awake, but that is likely to cause greater incompatibility, > and I'm shying away from it. The only thing special about awake is that it happens before respond. So I don't think it matters. > Perhaps Aaron's suggestion of having two types of page; one that has > the whole pre-respond/action thing, and one that doesn't is a good > one. Though, this is so trivial that a simple if/else test in one > servlet could easily do it. > > Plus, I like the idea of there being a default action method to run if > there's nothing explicit. An alternative to the above proposal would > be Ian's idea of "writeHTML" being the default action, but I still > don't like the idea of "output" being an action. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Matt F. <ma...@da...> - 2004-04-22 16:43:38
|
Ian Bicking wrote: > We have defaultAction now. It's only wonky because it doesn't call > preAction/postAction, where all other actions do. But if we get rid > of those, then it's not a problem. Anyway, defaultAction now just > calls writeHTML. I don't think output is an action. Output is always; actions are sometimes. Having a servlet with no output doesn't make sense (even if the output isn't html, but is an HTTP code... see below). > I'm still not clear what the problems are with sendRedirectAndEnd()? > If there's a bug there we should fix it -- otherwise we're fine right > now. From Application.py: (from 0.8.1) try: self.awake(transaction) try: self.respond(transaction) except EndResponse: pass self.sleep(transaction) except EndResponse: pass Therefore, calling the method from awake does not call sleep. This is bad. And people have pointed out that sleep may crash if it tries to close something that hasn't been opened in awake; which would happen if you raise the exception before that "something" was opened. This is also bad. It's best not to mess with awake and sleep just to send a redirect. Only mess with output. But my larger point is basically that a redirect IS output. It's an HTTP condition. It should come from response, as it does. To make this special "hijack" metaphor is wrong, especially if we end up coding the above so that it doesn't in fact hijack. The proper metaphor is to simply not do writeHTML, and send the alternate output of a redirect. It's still a response; the normal servlet "thing" is still happening. The response is not "ended" at all. If we want to keep a close method name, I would support just changing it to "sendRedirect", which would set a flag and change the output from response accordingly. > Right now there's no analog for non-HTML output. You just override > writeHTML and write other text. It's a misnomer, but it works fine. > However, for some actions you may wish to suppress writeHTML. Of > course you can code this yourself (setting some flag), but it might be > nice to include. Forcing writeHTML to be called by the action would > serve to do this. I agree; if you want to stop output from actions (and not use the redirect pattern that I've been talking about) it should be up to you to change that behavior. I do not think that we should make it so every action needs to call writeHTML at the end. > > The only thing special about awake is that it happens before respond. > So I don't think it matters. > Agreed. |
From: Ian B. <ia...@co...> - 2004-04-22 17:10:25
|
Matt Feifarek wrote: > Ian Bicking wrote: > >> We have defaultAction now. It's only wonky because it doesn't call >> preAction/postAction, where all other actions do. But if we get rid >> of those, then it's not a problem. Anyway, defaultAction now just >> calls writeHTML. > > > I don't think output is an action. Output is always; actions are > sometimes. Having a servlet with no output doesn't make sense (even if > the output isn't html, but is an HTTP code... see below). Actions are always -- that's what defaultAction is there for. >> I'm still not clear what the problems are with sendRedirectAndEnd()? >> If there's a bug there we should fix it -- otherwise we're fine right >> now. > > > From Application.py: (from 0.8.1) > > try: > self.awake(transaction) > try: > self.respond(transaction) > except EndResponse: > pass > self.sleep(transaction) > except EndResponse: > pass from Servlet.py (CVS): def runTransaction(self, trans): try: self.awake(trans) self.respond(trans) finally: self.sleep(trans) You can change this fairly easily since it's a method of Servlet now, and not Application. EndResponse and other exceptions from HTTPExceptions are still handled by Application (though you are free to trap them in your servlet as well, again using runTransaction -- Component.CPage does this). > Therefore, calling the method from awake does not call sleep. This is > bad. And people have pointed out that sleep may crash if it tries to > close something that hasn't been opened in awake; which would happen if > you raise the exception before that "something" was opened. This is also > bad. You need some way of dealing with this -- if sleep has to be cautious about how it is called, then so be it; *something* has to be cautious. There's always a possiblity of exceptions -- if you don't call sleep, then you have to be cautious that you haven't left resources open when other errors occur. To me exceptions seem like exactly the right mechanism for redirects, not flags. Flags work, but they are limited -- I think we should avoid them, at least for something as common as a redirect. A lot of good things come out of exceptions that can't come from flags. You can raise permission exceptions deep in libraries that don't have access to the servlet. You can raise a 404 in your servlet based on extraURLPath, and it looks just like it would if the servlet itself hadn't been found, and so on. > It's best not to mess with awake and sleep just to send a redirect. Only > mess with output. > > But my larger point is basically that a redirect IS output. It's an HTTP > condition. It should come from response, as it does. To make this > special "hijack" metaphor is wrong, especially if we end up coding the > above so that it doesn't in fact hijack. > > The proper metaphor is to simply not do writeHTML, and send the > alternate output of a redirect. It's still a response; the normal > servlet "thing" is still happening. The response is not "ended" at all. > > If we want to keep a close method name, I would support just changing it > to "sendRedirect", which would set a flag and change the output from > response accordingly. > > >> Right now there's no analog for non-HTML output. You just override >> writeHTML and write other text. It's a misnomer, but it works fine. >> However, for some actions you may wish to suppress writeHTML. Of >> course you can code this yourself (setting some flag), but it might be >> nice to include. Forcing writeHTML to be called by the action would >> serve to do this. > > > I agree; if you want to stop output from actions (and not use the > redirect pattern that I've been talking about) it should be up to you to > change that behavior. Well, we don't actually agree, because I wasn't actually saying we *should* encourage the use of a flag, only that we could. Right now I've been working on user management components (svn://w4py.org/LoginKit), and a more formalized way to control output seems necessary to me. Perhaps that can just be isolated in CPage (a componentized version of Page), or maybe there's another way to manage these, but we need something. > I do not think that we should make it so every action needs to call > writeHTML at the end. > >> >> The only thing special about awake is that it happens before respond. >> So I don't think it matters. >> > Agreed. |
From: Matt F. <ma...@da...> - 2004-04-22 18:20:38
|
Ian Bicking wrote: > Actions are always -- that's what defaultAction is there for. I don't think so. Actions only happen when there's _action_XXX in the request. But maybe you've changed this behavior. > from Servlet.py (CVS): > Great! But this is not what is in the current version. I was talking about the problem with the current version, and inconsistent use of sleep. People who aren't comfortable running production servers on CVS are out of luck. But, it does look way better. I'm looking forward to being able to take advantage of it. > You can change this fairly easily since it's a method of Servlet now, > and not Application. EndResponse and other exceptions from > HTTPExceptions are still handled by Application We're still not ending the response. We're still sending a response. It's shorter, yes, but we're still doing it. "End" is the wrong metaphor. > You need some way of dealing with this -- if sleep has to be cautious > about how it is called, then so be it; *something* has to be cautious. > There's always a possiblity of exceptions -- if you don't Good point. I agree. > A lot of good things come out of exceptions that can't come from > flags. You can raise permission I agree with you. Exceptions are better. Especially if they don't disrupt awake and sleep (as you've written above). I supose we have to let someone disrupt response, but then you have the possibility of having sent data to a stream that is never sent, which is weird. An example: we use a "messages" and "errors" pattern, much like what's in your sandbox. We pop them from a list in session and send them in writeHTML. If they get sent, and *then* the response is converted into a redirect, the message is lost. This is why response should be either/or. > flag, only that we could. Right now I've been working on user > management components (svn://w4py.org/LoginKit), and a more formalized > way to control output seems necessary to I like the sound of that. I'll try and look at your code. |
From: Ian B. <ia...@co...> - 2004-04-22 19:13:26
|
Matt Feifarek wrote: > Ian Bicking wrote: > >> Actions are always -- that's what defaultAction is there for. > > I don't think so. Actions only happen when there's _action_XXX in the > request. But maybe you've changed this behavior. I don't think this is new to CVS, but I don't have a copy of 0.8.1 handy, and CVS history still scares me ;) It's at the end of Page.respond, where if no actions are found it calls defaultAction -- which is different than other actions, because it doesn't go through handleAction, and thus doesn't call preAction and postAction, but that's just cruftiness anyway. >> from Servlet.py (CVS): >> > Great! But this is not what is in the current version. I was talking > about the problem with the current version, and inconsistent use of > sleep. People who aren't comfortable running production servers on CVS > are out of luck. Yes, that sucks. A lot of these things can be handled in 0.8 in more crufty ways, or by backporting small bits (like the addition of runTransaction, which is a pretty small change). > But, it does look way better. I'm looking forward to being able to take > advantage of it. > >> You can change this fairly easily since it's a method of Servlet now, >> and not Application. EndResponse and other exceptions from >> HTTPExceptions are still handled by Application > > > We're still not ending the response. We're still sending a response. > It's shorter, yes, but we're still doing it. "End" is the wrong metaphor. We are sending a response, but at the same time we're ending the response. Once you've sent the redirect there's no point ot sending anything else. In 0.8 way you would change sendResponseAndEnd to call sleep and then raise EndResponse. Either way. (Personally, I think it makes more sense to raise HTTPTemporaryRedirect, which makes it clear at the point of redirect that you're jumping out of the rest of the request -- putting the exception in sendResponseAndEnd makes hides that important part of the implementation) >> You need some way of dealing with this -- if sleep has to be cautious >> about how it is called, then so be it; *something* has to be cautious. >> There's always a possiblity of exceptions -- if you don't > > > Good point. I agree. > >> A lot of good things come out of exceptions that can't come from >> flags. You can raise permission > > > I agree with you. Exceptions are better. Especially if they don't > disrupt awake and sleep (as you've written above). > > I supose we have to let someone disrupt response, but then you have the > possibility of having sent data to a stream that is never sent, which is > weird. An example: we use a "messages" and "errors" pattern, much like > what's in your sandbox. We pop them from a list in session and send them > in writeHTML. If they get sent, and *then* the response is converted > into a redirect, the message is lost. This is why response should be > either/or. Yes, I've thought about that issue. Generally I never redirect after I'm part way through rendering a page, but other people might want to do that. There should be a way to detect that the output is being thrown away. Using the component stuff you actually could get an exception event, and perhaps infer that the output is being thrown away. >> flag, only that we could. Right now I've been working on user >> management components (svn://w4py.org/LoginKit), and a more formalized >> way to control output seems necessary to > > > I like the sound of that. I'll try and look at your code. > |
From: Matt F. <ma...@da...> - 2004-04-22 22:13:57
|
Ian Bicking wrote: > I don't think this is new to CVS, but I don't have a copy of 0.8.1 > handy, and CVS history still scares me ;) It's at the end of > Page.respond, where if no actions are found it calls defaultAction -- Yeah, I checked. It's not there. Only actions registered in actions() are looked for and/or executed. There's no "defaultAction" anywhere in WebKit. >> We're still not ending the response. We're still sending a response. >> It's shorter, yes, but we're still doing it. "End" is the wrong >> metaphor. > > We are sending a response, but at the same time we're ending the > response. Once you've sent the redirect there's no point ot sending > anything else. Now, it seems that we're splitting hairs. ;-) I would say that by your definition, all responses are "ended" eventually. Oh well. Technically, one can send a redirect header AND an html page, but that may actually break the rules. Webkit allows it, and probably Apache passes it through, but it may be against spec. My argument is that a redirect *IS* the response; "ending" it is redundant. Theory aside (I'll stop whining about this now), I definitely agree that there's no point in sending anything else after you send a redirect, which is why I want to *conditionalize* writeHTML in most cases. >> I supose we have to let someone disrupt response, but then you have >> the possibility of having sent data to a stream that is never sent, >> which is weird. An example: we use a "messages" and "errors" pattern, >> much like what's in your sandbox. We pop them from a list in session >> and send them in writeHTML. If they get sent, and *then* the response >> is converted into a redirect, the message is lost. This is why >> response should be either/or. > > Yes, I've thought about that issue. Generally I never redirect after > I'm part way through rendering a page, but other people might want to > do that. > > There should be a way to detect that the output is being thrown away. > Using the component stuff you actually could get an exception event, > and perhaps infer that the output is being thrown away. If you *want* that behavior, by all means, you should be allowed to do so. But, sane-defaults/best-practices, whatever you want to call it, I say that writeHTML() shouldn't be called if a redirect is already there when you start respond(). Obviously, if you raise it in the middle of writeHTML, it's different. I like the idea of an exception being thrown to warn us, and of course, we could always catch it and ignore it. |
From: Ben P. <be...@we...> - 2004-04-20 21:27:18
|
Ian Bicking wrote: > Aaron Held wrote: > > I like actions the way they are - they are very simple to understand. > > If you have a hello "Aaron" type app its easy to setup a servlet like > > > > def writeContent(self): > > self.write('<form><input type="text" name="username"><submit > > name="_acctionHello"</form>'); > > > > def hello(self): > > self.write('Hello %s' % self.request().value('username','No > User Name')) > > Where it gets all annoying, though, is preAction and postAction, which > are like an anemic form of the writeHTML, writeHead, writeTitle, > writeStyleSheet etc. setup that Page has for normal requests. Or, where > you don't want to write anything, but way to treat the action as an > action (i.e., something that does something, not something that merely > changes the display) -- there again preAction and postAction get > in the way. > > Ian We change the meaning of preAction and postAction in our site's base Page subclass. Works very well: def preAction(self, action): pass def postAction(self, action): # By default, all actions are followed by drawing the page # Servlets with actions that draw screens can override self.writeHTML() def writeHTML(self): if not self.response().hasHeader('Location'): self.writeDocType() self.write('\n<html ...snip...>\n\n') self.writeHead() self.writeBody() self.write('\n</html>') NOTE: the if statement to check for Location is unnecessary if you always follow sendRedirect with endResponse, or use sendRedirectAndEnd. This implementation pre-dates the existence of that exception handling framework, and was left in for backwards compatability. Although we've never had to override preAction in another subclass, I could envision some framework doing it. I think the structure of actions works well in the 0.8.1 implementation. I'll second Aaron's vote for "simple to understand". Regards, Ben |
From: Matt F. <ma...@da...> - 2004-04-20 21:06:49
|
Ian Bicking wrote: > I use 3 too, though I've sometimes added a "self.setup()" to my > SitePage, and allowed servlets to override that instead of awake. > It's more consistent because it has no trans argument, and I Agreed. We like that pattern, too. It's just basically adding a "postAwake" into the lifecycle. >> Another problem is that I don't think you can fire more than one >> action on one servlet, so they end up being "meta-methods" sometimes, >> and therefore look more like event handlers. > > I think I'm losing you here. IMHO, anything more complicated than > actions (i.e., specified in a field; one action per request) should be > coded explicitly. No surprising ;-). What I mean is that rather than actions simply firing "deleteRecord()" on a database, they probably have to do several items of "application logic". Which means they aren't very atomic in nature. SO, they tend to be more along the lines of "submit()" or "search()" or "login()", which may group together several tasks into one action call. It's a moot point, really. |
From: Shayne O. <sh...@pe...> - 2004-04-20 02:01:34
|
Would perhaps a state flag be apropriate that tells the object *NOT* to talk to the html output system? -- Shayne O'Neill http://perth.indymedia.org I know how hard it is for you to put food on your family." ----George W. Bush On Mon, 19 Apr 2004, Ian Bicking wrote: > I haven't been using actions very much up until now, but I used them in > the Wiki and found the method layout to be suboptimal. I think other > people have had the same experience. > > Anyway, I'll describe what I did and see what people's reactions are. > > First, preAction and postAction do nothing. > > Second, _respond invokes writeHTML always, not just when no action was > found. > > Third, defaultAction sets self.view = 'writeContent'; other actions set > it to other values. > > In writeBodyParts, I do: > > def writeBodyParts(self): > getattr(self, self.view)() > > And actually if view is None, then writeHTML doesn't do anything (which > is what I set when writing non-HTML output). > > Then each action does its thing, kind of like awake (but in addition to > awake, which is always called) and then chooses its "view". On a form > submittal, for instance, it may choose a view where it shows success, or > if there were errors it may show the original form view. > > Often in title() I code in some different values depending on the view, > there might be a better way to do that (e.g., make the title a function > attribute of the view method). But anyway, at least it's possible to > change some of those non-content parts of the page depending on the action. > > I'm not sure how this fits into what people are doing with _action_ > right now. I played around with adding this pattern to Component.CPage, > but I want that to be backward compatible so maybe that won't work. > > Ian > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Webware-discuss mailing list > Web...@li... > https://lists.sourceforge.net/lists/listinfo/webware-discuss > |