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

I'm in the process of writing my first app with CGI::Application. So far, it's working pretty well and I understand most of it. What's tripping me is up is trying to figure out how to share values between run modes. What I'm trying to do in the code below is set the values in the first run mode so that the values are visible in the second. For example, $self->param('foo') gets defined in the first run mode, the value can be referenced in the second.

I understand that you can set params in the setup sub and have them be visible to all the run modes, but how do you then change that value?

package Testing; use base 'CGI::Application'; use strict; use warnings; use diagnostics; sub setup { my $self = shift; $self->start_mode('cast'); $self->mode_param('rm'); $self->tmpl_path('/home/users/rich36'); $self->run_modes( 'cast' => 'castVotes', 'list' => 'listVotes' ); #$self->param('badcomments' => ""); # ??? #$self->param('goodcomments' => ""); # ??? } sub castVotes() { my $self = shift; # Get the CGI query object my $q = $self->query(); # Set the params - these are the ones I'm trying to get to in the +other run mode... $self->param( 'name' => $q->param('name'), 'id' => $q->param('id'), 'ip' => $q->param('ip'), ); # Code to validate values passed by the query string #.... # Returns HTML::Template output return $output; } sub listVotes() { my $self = shift; # Get the CGI query object my $q = $self->query(); # This doesn't work.... # I need to be able to access the values stored in # $self in the other run mode. my $name = $self->param('name'); my $id = $self->param('id'); my $ip = $self->param('ip'); } 1;

Any help would be greatly appreciated. Also, ++ rob_au for the excellent module review/tutorial (CGI::Application)...


Rich36
There's more than one way to screw it up...

Replies are listed 'Best First'.
Re: Passing values between run modes in CGI::Application
by rob_au (Abbot) on Apr 12, 2002 at 07:35 UTC
    There are a couple of ways to tackle this problem ... The first and most straight-forward is to pass the parameters set in the first run-mode back into hidden form fields or anchor links within your template file. This method is demonstrated in the code snippet below:

    . . $html->param( $_ => $self->param($_) ) foreach $self->param(); return $html->output; }

    For which the corresponding HTML::Template template file would look similar to the follow:

    . . <input type="hidden" name="rm" value="list" /> <input type="hidden" name="id" value="<tmpl_var name="id">" /> <input type="hidden" name="name" value="<tmpl_var name="name">" /> . .

    This is the most simple and correspondingly most insecure manner for providing state persistence between run-modes using CGI::Application.

    A far better approach to this issue of state persistence is to make use of a server-side based persistence solutions such as that offered by Apache::Session and CGI::Session - I demonstrated an example of such a server-side based persistence solution for CGI::Application with this post.

    With this method, only a reference to the server-side storage of persistence data is sent to the client and as such these solutions offer greater security as persistence data is not directly accessible to the client. This is important with clients who with the former method could easily edit the HTML form values and return bogus data - For a further discussion on this, see Re: A CGI chained-event theory question.

     

      "The first and most straight-forward is to pass the parameters set in the first run-mode back into hidden form fields or anchor links within your template file."

      That's what I ended up doing to make it work. For some reason, I thought that CGI::Application had an inherent mechanism to maintain state across the run modes.

      Thanks for your help.

      Rich36
      There's more than one way to screw it up...