You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Joshua Chamas <jo...@chamas.com> on 2001/11/15 20:57:51 UTC

Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Scott Chapman wrote:
> 
> I'm very interested in making a modular site design but haven't
> found the tools yet to allow this with the twist I'm looking for.
> 

I'll try to show how Apache::ASP could help here.  In Apache::ASP,
scripts can be executed as subroutines, even with return values,
and I think this goes to the heart of what you need here.

I would probably break abstract headers & footers out of 
each page, to be called automatically in global.asa.  This allows
all pages to not need to know about HTML headers & footers being sent:

# global.asa
sub Script_OnStart { $Response->Include('header.inc'); }
sub Script_OnEnd   { $Response->Include('footer.inc'); }

> Say I have a page that encapsulates some functionality, such as
> sending a form then validating the contents that are returned. I'd
> call that PageB.
> 
> PageB could be more than one page or a page calling itself, etc.
> 

Right ... PageB is just form logic/rendering, headers & footers
are called automatically via events in global.asa.

> When PageA calls PageB, as soon as PageB finishes presenting
> the form it doesn't stop but drops out the bottom and returns
> immediately to PageA.  There are commands in some of the tools
> (Mason and soon Embperl - maybe others) to force it to stop there
> but this doesn't make for the modularity I have in mind.
> 
#PageA
<% my @rv = $Response->Include('PageB', @args); %>
<!-- Rest of PageA -->

$Response->Include() just calls another page as a perl subroutine
is called with @args passed in as @_ in the script, and @rv returned
if return(@rv) is used in the script too.

> PageB then gets submitted by the user and it either calls itself
> (using conditionals to then do the data validation) or another page.
> After things are validated Ok, I'd like to have it return right back to
> PageA, just where it left off using a "Return" statement. Thus,
> PageA could call a "PageB" and have it do all it's processing then
> return, just like calling a regular subroutine.
> 

PageA can execute PageB, and PageB can execute PageA, but this
could cause a loop, so I am not sure what you really want here,
but hope the above showed how one might achieve this.

> 2) are there any tools (preferrably perl) out there that support this
> cleanly.  I've worked with Embperl and glanced through the docs of
> Mason, AxKit and TT and didn't see anything looking like this.
> 

The $Response->Include() mechanism is very powerful, turning pages
into subroutines, and always returns to the original caller.  
To transfer control to another page without returning, 
use $Server->Transfer().  This differs from $Response->Redirect()
in that all the globals like $Session/$Application/$Request remain
the same.  If the ASP syntax is too ugly for you, you could turn 
this into an XMLSub used like:

  <page:include file="PageB" arg1="..." arg2="..." />

where you would define:

# global.asa or page.pm or any perl module that gets loaded
sub page::include {
  my($args) = @_;
  $Response->Include($args->{'file'}, $args);
}

-- Josh
_________________________________________________________________
Joshua Chamas                           Chamas Enterprises Inc.
NodeWorks Founder                       Huntington Beach, CA  USA 
http://www.nodeworks.com                1-714-625-4051

Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Rob Nagler <na...@bivio.net>.
> In my opinion, trying to abstract that stuff away in a web application
> causes to more problems than it solves, especially where back buttons and
> bookmarks are concerned.

We haven't found this to be the case.  Our servers are sessionless,
so bookmarks work fine.   Back buttons aren't any more or less of a
problem.  I actually haven't heard of any problems with our sub-forms
and back buttons.  People do bookmark URLs with form context, but
that's a good thing.  It usually is the login page and they login and
it automatically restores the page which they thought they
bookmarked (which redirected to login in the first place).

> I think it's easier to take a state machine
> approach, the way CGI::MxScreen or Apache::PageKit do.

I don't think this works.  The state machine can manage states going
forward, but not backward.  Consider the problem of a Symbol Lookup on
our site (www.bivio.com).  We come into it from just about any
accounting page having to do with a stock transaction.  It's a single
task, which looks up the ticker and fills it in in the Calling form.
You need to stack the state or you have to introduce N new states
(for entry from forms A, B, C, D, ...).

It did take about two years to come up with a decent implementation of
FormContext.  It's a non-trivial problem, but it can be generalized
and it solves the problem we had.

Rob

Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Rob Nagler <na...@bivio.net>.
Perrin Harkins writes:
> breaks caused by the request model of HTTP, and that's what I was commenting
> on.  You're talking about a way to preserve data across multiple page
> requests.

FormContext maintains an "HTTP call stack", which holds the parameters
(form, query, path_info) and return address (calling Task).  Tasks are
work units (server subroutines).  URIs are UI elements, which is why
we don't store them in the FormContext.

> If I understand your FormContext approach correctly, you are storing the
> state of the current application in URLs or hidden fields.  This is what we
> used at eToys as well, and I think it's a pretty common solution.

FormContext is a formal stack architecture.  The callee can reach into
the stack to get or to modify caller's form data as in the
ShippingAddressForm case.  It also handles the case of a call from a
non-form Task, e.g. if you bookmark your private home page on a site,
the LoginForm requires context so it knows where to return to after
successful authentication.  The Login task needs no knowledge of who
called it; it just returns to the Task specified in its FormContext.
If there is no FormContext, it returns to its "next" task specified by
the state machine.

The reason I brought up sessions is that the above mechanism wouldn't
work if there were sessions.  Sessions might time out or go away for
bookmarked pages.  FormContext survives server restarts and renaming
of the calling page's URI.

Rob

Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Perrin Harkins <pe...@elem.com>.
> > In my opinion, trying to abstract that stuff away in a web application
> > causes to more problems than it solves, especially where back buttons
and
> > bookmarks are concerned.
>
> We haven't found this to be the case.  Our servers are sessionless,
> so bookmarks work fine.

These are different (though related) concepts.  The original poster was
looking for a way to structure web programs without thinking about the
breaks caused by the request model of HTTP, and that's what I was commenting
on.  You're talking about a way to preserve data across multiple page
requests.

> > I think it's easier to take a state machine
> > approach, the way CGI::MxScreen or Apache::PageKit do.
>
> I don't think this works.  The state machine can manage states going
> forward, but not backward.

You can code a state machine that defines legal transitions from one state
to another, and that could include stepping "backward".  There's no real
concept of forward and backward in what I had in mind, just a collection of
states and legal transitions between them.

If you hit the back button, you're still okay as long as the form's data is
stored in the URL or hidden fields rather than in a global session, i.e.
going back will return you to the state you were in correctly.

Most people instinctively code a state machine when they start using CGI,
but they do it in the form of a bunch of statements like "if $form_action eq
'save'".  The frameworks I mentioned just pull it out and make it more
explicit.

If I understand your FormContext approach correctly, you are storing the
state of the current application in URLs or hidden fields.  This is what we
used at eToys as well, and I think it's a pretty common solution.  It's the
only way to safely handle possibilities like multiple browser windows using
the same application.  There are some CPAN modules that help with this kind
of thing, like CGI::EncryptForm.

- Perrin


Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Scott Chapman <sc...@mischko.com>.

On 15 Nov 2001, at 15:33, Perrin Harkins wrote:

> The original e-mail was confusing, but I think what he's after is not so
> much the ability to call pages as subs but rather the ability to abstract
> away the fact that a sub might actually involve multiple user interactions
> (present a form, get a response, present another form, etc.) with breaks in
> actual execution.  In other words, he wants to think of program execution in
> terms of a linear user session (as you would with a GUI app) rather than a
> series of separate requests.

I'm sorry the original email was confusing. You've stated it exactly 
right.  I want an abstraction layer here so that web pages work like 
calling a subroutine in a regular programming language works.
 
> In my opinion, trying to abstract that stuff away in a web application
> causes to more problems than it solves, especially where back buttons and
> bookmarks are concerned.  I think it's easier to take a state machine
> approach, the way CGI::MxScreen or Apache::PageKit do.  (CGI::Application
> sort of does, but it doesn't capture the relationships of states to each
> other.)  With Apache::ASP, I think people would generally embed the state
> transition logic in the pages, although this could probably be separated out
> if you were careful about it.

Back buttons and bookmarks already cause plenty of problems, 
not really having to do with this abstraction layer idea.  The people 
who do the work with an abstraction layer will have to keep 
bookmarks and back buttons in mind just like you have to today.  It 
would be worth it to have the abstraction layer in my opinion.  I'd 
love to be able to deal with these problems!

Scott
 
> - Perrin
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org


Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Scott Chapman <sc...@mischko.com>.

On 15 Nov 2001, at 15:33, Perrin Harkins wrote:

> The original e-mail was confusing, but I think what he's after is not so
> much the ability to call pages as subs but rather the ability to abstract
> away the fact that a sub might actually involve multiple user interactions
> (present a form, get a response, present another form, etc.) with breaks in
> actual execution.  In other words, he wants to think of program execution in
> terms of a linear user session (as you would with a GUI app) rather than a
> series of separate requests.

I'm sorry the original email was confusing. You've stated it exactly 
right.  I want an abstraction layer here so that web pages work like 
calling a subroutine in a regular programming language works.
 
> In my opinion, trying to abstract that stuff away in a web application
> causes to more problems than it solves, especially where back buttons and
> bookmarks are concerned.  I think it's easier to take a state machine
> approach, the way CGI::MxScreen or Apache::PageKit do.  (CGI::Application
> sort of does, but it doesn't capture the relationships of states to each
> other.)  With Apache::ASP, I think people would generally embed the state
> transition logic in the pages, although this could probably be separated out
> if you were careful about it.

Back buttons and bookmarks already cause plenty of problems, 
not really having to do with this abstraction layer idea.  The people 
who do the work with an abstraction layer will have to keep 
bookmarks and back buttons in mind just like you have to today.  It 
would be worth it to have the abstraction layer in my opinion.  I'd 
love to be able to deal with these problems!

Scott
 
> - Perrin
> 



Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Perrin Harkins <pe...@elem.com>.
> I'll try to show how Apache::ASP could help here.  In Apache::ASP,
> scripts can be executed as subroutines, even with return values,
> and I think this goes to the heart of what you need here.

The original e-mail was confusing, but I think what he's after is not so
much the ability to call pages as subs but rather the ability to abstract
away the fact that a sub might actually involve multiple user interactions
(present a form, get a response, present another form, etc.) with breaks in
actual execution.  In other words, he wants to think of program execution in
terms of a linear user session (as you would with a GUI app) rather than a
series of separate requests.

In my opinion, trying to abstract that stuff away in a web application
causes to more problems than it solves, especially where back buttons and
bookmarks are concerned.  I think it's easier to take a state machine
approach, the way CGI::MxScreen or Apache::PageKit do.  (CGI::Application
sort of does, but it doesn't capture the relationships of states to each
other.)  With Apache::ASP, I think people would generally embed the state
transition logic in the pages, although this could probably be separated out
if you were careful about it.

- Perrin


Re: [Maybe OT] Modular design - calling pages like a subroutine with a twist.

Posted by Perrin Harkins <pe...@elem.com>.
> I'll try to show how Apache::ASP could help here.  In Apache::ASP,
> scripts can be executed as subroutines, even with return values,
> and I think this goes to the heart of what you need here.

The original e-mail was confusing, but I think what he's after is not so
much the ability to call pages as subs but rather the ability to abstract
away the fact that a sub might actually involve multiple user interactions
(present a form, get a response, present another form, etc.) with breaks in
actual execution.  In other words, he wants to think of program execution in
terms of a linear user session (as you would with a GUI app) rather than a
series of separate requests.

In my opinion, trying to abstract that stuff away in a web application
causes to more problems than it solves, especially where back buttons and
bookmarks are concerned.  I think it's easier to take a state machine
approach, the way CGI::MxScreen or Apache::PageKit do.  (CGI::Application
sort of does, but it doesn't capture the relationships of states to each
other.)  With Apache::ASP, I think people would generally embed the state
transition logic in the pages, although this could probably be separated out
if you were careful about it.

- Perrin


---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org