John Tsangaris wrote:
> I've been playing around with CGI::Application and while I've made it do
> what I want it to, there seems to be some things missing...

There are a lot of things missing from CGI::Application, like user 
authentication and session persistence. As I've commented here before, 
CGI::App is essentially a glorified switch statement. But it is the 
appropriate size tool for many jobs. And I'm sure many would argue it is 
better to start out with a simple framework, and have plugins for the 
more complicated stuff.


> ...if you have a large program with 1000 different run
> modes, well.. you end up with 1000 line of mode1 => \&mode1,.

CGI::App might not be the right tool if you really have 1000 different 
run modes, :-)  and/or you need to refine your architecture. Keep in 
mind that you can always split your application among multiple CGI 
scripts, if there is a logical division in your application.


> ...there doesn't seem to be an easy way of loading only the modules
> you need based on the run mode.
...
> In the past I used a super simple framework, not as full featured, but
> at least it had the capability to dynamically load parts of the program
> when needed, rather than the whole shebang.

(Might you be referring to the architecture used in the WebEvent product 
that we both worked on?)

You'll want to look at CGI::Application::Plugin::AutoRunmode::FileDelegate:

http://search.cpan.org/~thilo/CGI-Application-Plugin-AutoRunmode-0.05/AutoRunmode/FileDelegate.pm

Its description says, "each run mode is contained in its own file, named 
foo.pl for a run mode called foo." (That's essentially the same as what 
WebEvent used.)

Though I don't think this is necessarily the best approach. Spreading 
your application across dozens of small files isn't the most attractive 
solution, and may not provide any performance wins. It might also 
interfere with your ability to reuse CGI::App subclasses you've recreated.


Another similar plugin is CGI::Application::Plugin::TemplateRunner:

http://search.cpan.org/~thilo/CGI-Application-Plugin-TemplateRunner-0.03/TemplateRunner.pm

which "provides a runmode to automatically get the name of an 
HTML::Template from the path_info string, load the template, fill it 
with data from an associated Perl data file and display the template."


A more interesting approach is CGI::Application::Plugin::AutoRunmode:

http://search.cpan.org/~thilo/CGI-Application-Plugin-AutoRunmode-0.05/AutoRunmode.pm

which lets you use attributes to neatly declare which of your subclass' 
methods correspond to runmodes. Per the synopsis:

         sub my_run_mode : Runmode {
                 # do something here
         }

         sub another_run_mode : Runmode {
                 # do something else
         }

I see this is also similar to what Catalyst does.


> On top of that.. all examples show the &mode1 as being coded inside your
> main package.
>  
> Now, while I know that you can clean stuff up by moving the subs to
> various other modules which can be used in your main package...

Are you sure about that? The typical use of CGI::App is that you 
subclass it, so your runmodes should be methods of your subclass (in 
your package rather than main).


> I've looked for examples of a better way to use CGI::Application than the
> simple run_mode => \&sub in the main package way but can't find any.

Have you looked at the wiki:
http://twiki.med.yale.edu/twiki2/bin/view/CGIapp/WebHome

or searched the mailing list archives:
http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2


> Also, what is the standard (or several of the better ways) of using the
> run modes?  For instance, to create a register function I have two
> choices, create a page template using one run mode to display and another
> to process it, or use the same run mode to display and process it
> determining which to do by watching which button was clicked (which seems
> to make the whole run mode idea pointless).

In my experience, run modes typically have a tight association with a 
particular screen or template.

So in your example, you'd have one run mode to process the registration 
form template and display it, and if submitting that form resulted in 
some acknowledgment page being displayed, then that would be a different 
run mode. If it redisplayed the same form, it would be the same run mode.

Where things get a bit more tricky is where you might not produce a 
separate acknowledgment screen, but instead pass the user on to some 
other unrelated screen, which may or may not incorporate an 
acknowledgment message for the prior action.

And even trickier yet is if you're building a "web 2.0" or AJAX app. and 
you're saving data without switching screens. People are starting to 
work on incorporating AJAX techniques into CGI::App, such as 
CGI::Application::Plugin::AJAX:

http://kemitix.net/bitware/2005/07/02/cgiapplicationpluginajax-v002/

though I wonder if one interested in using AJAX might be better off 
using a framework that was designed with that in mind.


> After writing my third copy of that pattern I figured there must be a
> better way of handling requests for display / processing purposes in
> CGI::Application.

To me, the real weakness in using a simple framework that spits out hand 
coded forms from templates and processes the random collection of 
parameters that gets sent back, is that there isn't a good "closed loop" 
definition of what the data objects are, how to render them as form, and 
how to validate them. Data::FormValidator (for which there is a CGI::App 
plugin) supposedly addresses this to some extent, as does Class::DBI, 
but they still don't seem to address the full problem.

  -Tom

-- 
Tom Metro
Venture Logic, Newton, MA, USA
"Enterprise solutions through open source."
Professional Profile: https://www.linkedin.com/e/fps/3452158/
 
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to