http://qs321.pair.com?node_id=748939

c4onastick has asked for the wisdom of the Perl Monks concerning the following question:

I haven't done much web development in Perl as of yet (I came to Perl from PHP to get away from the web), but decided to get my feet wet a bit with a new project at work. I stumbled across CGI::Application the other day while getting started and thought it'd be great for a rapid development framework (yet another reason I came to Perl from PHP: CPAN! Back in my PHP days I ended "rolling my own" pseudo-CGI::Application for PHP.)

CGI::Application's interface is great (much better than mine!), it gives you a nice MVC canvas to start painting your site upon. However, I did run into a bit of a problem trying to pass variables via both GET and POST, which is typically how I've handled form submissions before (i.e. use the form method "POST" and an action of something like "index.cgi?page=submit_form")

Here's a simplified version of what I've got so far:

File: TestSite.pm

package TestSite; use base 'CGI::Application'; use warnings; use strict; sub setup { my $self = shift; $self->start_mode('mode1'); $self->mode_param('rm'); $self->run_modes( 'mode1' => 'one', 'mode2' => 'two' ); } sub one { my $self = shift; my $template = $self->load_tmpl; return $template->output; } sub two { my $self = shift; my $q = $self->query(); my $template = $self->load_tmpl; $template->param(test_post => $q->param('test_post')); return $template->output; } 1;

With templates that look like:

File: mode1.html

<html> <head> <title>One</title> </head> <body> <h1>Page one</h1> <form action='index.pl?rm=mode2' method='post'> <p>Input: <input type='text' name='test_post' size='20' /> +</p> <p><input type='submit' value='Submit' /></p> </form> </body> </html>

File: mode2.html

<html> <head> <title>Two</title> </head> <body> <h1>Page two</h1> <p>Value of &quot;test_post&quot; is <tmpl_var name='test_post +'>.</p> <p><a href='index.pl?rm=mode1'>Click to go back to one</a></p> </body> </html>

When testing this locally on Apache 2.2 (in Win32), CGI::Application seems to choke, it would make the switch to run mode "mode2" (the address bar would have "rm=mode2") but it would still display "mode1" (the form page), which makes me think it caught some exception and defaulted to "mode1". Unfortunately, I wasn't able to find anything interesting in the Apache logs. I tried a number of things to try to manually debug but with little luck.

Changing to 100% POST did work as expected though...

File: mode1.html

<html> <head> <title>One</title> </head> <body> <h1>Page one</h1> <form action='index.pl' method='post'> <input type='hidden' name='rm' value='mode2' /> <p>Input: <input type='text' name='test_post' size='20' /> +</p> <p><input type='submit' value='Submit' /></p> </form> </body> </html>

So, that leads to my question: How do you handle both POST and GET with CGI::Application?
Or is there some good reason why I shouldn't be mixing POST and GET?
(And thirdly, any tips for debugging CGI::Application? Tried "dump" and "dump_html" but as seen above my problem caused it to die before it got to "dump")

I did some looking through CGI.pm and it looks like it handles POST and GET via two different methods: "param" (for POST) and "url_param" (for GET). "url_param" doesn't appear anywhere in CGI::Application and I was able to isolate CGI::Application as the source by writing it "old-school". The following works as expected:

File: one.pl

#!/Perl/bin/perl use warnings; use strict; use CGI; use HTML::Template; my $q = new CGI; my $template = HTML::Template->new(filename => 'mode1a.html'); print "Content-Type: text/html\n\n", $template->output;

File: two.pl

#!/Perl/bin/perl use warnings; use strict; use CGI; use HTML::Template; my $q = new CGI; my $template = HTML::Template->new(filename => 'mode2a.html'); $template->param(test_post => $q->param('test_post')); print "Content-Type: text/html\n\n", $template->output;

File: mode1a.html

<html> <head> <title>One</title> </head> <body> <h1>Page one</h1> <form action='two.pl?some_var=foo&other_var=bar' method='post' +> <p>Input: <input type='text' name='test_post' size='20' /> +</p> <p><input type='submit' value='Submit' /></p> </form> </body> </html>

File: mode2a.html

<html> <head> <title>Two</title> </head> <body> <h1>Page two</h1> <p>Value of &quot;test_post&quot; is <b><tmpl_var name='test_p +ost'></b>.</p> <p><a href='one.pl'>Click to go back to one</a></p> </body> </html>

Thanks in advance for your help!

Update: I'm using:

Just through CGI, no mod_perl yet.