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

I've inheritted a CGI application which I think is a good fit for CGI::Application as it has a lot of "page" states.

Unfortunately these pages are currently called by different parameters - rather than one.

For example I have the following requests:

?page=top
?stats=1
?new=1

Rather than the CGI::Application-styled single run mode:

?mode=stats
?mode=article
?mode=new

Given that I wish all the old historical links to work, is there a way of shoe-horning CGI::Application to work with these parameters? Or would I be better off sticking with my current dispatch-table styled approach?

(I guess I could use mod_rewrite to coerce things, but that seems like the worst of both worlds)

Replies are listed 'Best First'.
Re: Converting to CGI::Application
by PodMaster (Abbot) on May 14, 2005 at 10:05 UTC
    No shoehorning required, just write your setup accordingly, something like the following would work
    sub setup { my $self = shift; my $cgi = $self->query; $cgi->param('mode','stats') if $cgi->param('stats'); ... }

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Converting to CGI::Application
by mpeters (Chaplain) on May 14, 2005 at 23:22 UTC
    All of the other responses have been good, but for another (and IMHO, a more C::A) way...
    I would use the mode_param() accessor that can also take an anonymous sub.
    sub setup { my $self = shift; $self->mode_param(\&_translate_old); } sub _translate_old { my $self = shift; my $query = $self->query(); if( $query->param('page') { return $query->param('page'); } elsif ( $query->param('stats') } return 'stats'; } elsif( $query->param('new') { return 'new'; } }

    -- fast, working, cheap - pick two
Re: Converting to CGI::Application
by derby (Abbot) on May 14, 2005 at 10:41 UTC
    In this case, I would replace the cgi script with something a bit more complicated than the normal CGI::Application wrapper. Something like this that sets the start_mode:
    #!/usr/bin/perl -w use strict; use CGI; use My::App; my $cgi = CGI->new(); my $mode; if( $cgi->param( 'page' ) { $mode = $cgi->param( 'page' ); } elsif( $cgi->param( 'stats' ) ) { $mode = "stats"; } elsif( $cgi->param( 'new' ) ) { $mode = "new"; } else { $mode = "some_default"; } my $app = My::App->new(); $app->start_mode( $mode ); $app->run();
    -derby

    Update: Uggg ... I like podmaster's solution much better since it appears the cgi-script is always the same. I've used the above approach - setting the start_mode in the cgi-script - when the the different modes of a multi-page cgi were different cgis (/cgi-bin/search, /cgi-bin/results, /cgi-bin/product, etc).