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

Should I be using CGI.pm to process forms? I've seen it recommended often. (At this point I'm mainly interested in parsing data from forms - I'm having trouble parsing a POST request that contains a Query String.)

If yes, where's the best place to install it? It sounds like either the server administrator can install it with the Perl program, or I can install it under my domain. Is one method better than the other?

If it makes sense for me to install it under the domain, I'm not clear on how. The instructions say to enter 3 commands for the install - where do I do that? Not on WS_ftp I don't think. Using shell access? (yes, I'm a Perl newbee)

Thanks,
Dean

Replies are listed 'Best First'.
Re: Using CGI.pm
by adrianh (Chancellor) on Nov 18, 2003 at 14:11 UTC

    It's likely that a version of the CGI module will already be available. It's been a core module since Perl version v5.004.

    Try running a single "hello world" script like:

    #! /usr/bin/perl use strict; use warnings; use CGI; my $q = CGI->new; my $name = $q->param('name') || 'mystery user'; print $q->header, $q->start_html('Hello'), $q->h1('Hello'), $q->p("Hello $name."), $q->end_html;

    Which you should then be able to call something like:

    http://localhost/cgi-bin/hello.cgi?name=Deanimal
Re: Using CGI.pm
by hmerrill (Friar) on Nov 18, 2003 at 14:25 UTC
    Yes, IMHO CGI.pm is the best way to process forms - it was written by Lincoln Stein (http://stein.cshl.org/~lstein/), has been around for a long time so is very mature, and as Dean said it's been included in the standard perl distribution since perl version 5.004. I'm guessing since you refer to WS_ftp that you are on a Windows machine - I can't be much help there. If you can get to a command prompt, you should be able to do
    perldoc CGI
    to read the excellent documentation included with the CGI.pm module. The CGI scripts you write will need to exist on the webserver machine which is where they will run.

    Just so you know, the CGI.pm module can be used for much more than just processing forms - it provides shortcuts for printing out your entire HTML page. I prefer to use it for just processing forms data myself - I like to code my own HTML because I feel too removed from the HTML if I use CGI.pm's shortcuts HTH.
      I like to use HTML::Template or Template to "generate" HTML from Perl, but CGI.pm is really good at creating form fields as well. Here is an example of creating a select box of the months with the current month selected:
      use strict; use warnings; use Time::Piece; use CGI qw(popup_menu); my $time = localtime; my @month = $time->mon_list; print popup_menu( -name => 'month', -values => [0..11], -default => $time->_mon, -labels => { map {($_ => $month[$_])} 0..11 }, );

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)
      

        Using HTML::Template to do this isn't too extreme, though it is definitely not as pretty-looking as CGI.pm's html-generating methods. Chances are I'd still go the templating route, just because I'm now very used to doing so.

        #!c:/perl/bin/perl -w $|++; use strict; use CGI::Simple; use HTML::Template; my $cur_month = 'November'; my $count = 0; my $months = [ map { [ $count++, $_ ] } qw( January February March April May Jun July August September October November December ) ]; my $q = CGI::Simple->new; my $t = HTML::Template->new(filehandle => *DATA); $t->param( url => $q->self_url, months => [ map { { month_num => $_->[0], month_name => $_->[1], selected => ($cur_month eq $_->[1] ? 'SELECTED' : '') } } @$months ] ); print $q->header, $t->output; exit; __DATA__ <html> <head> <title>test</title> </head> <body> <form action="<TMPL_VAR NAME="url" ESCAPE="HTML">"> <select name="month"> <TMPL_LOOP NAME="months"> <option value="<TMPL_VAR NAME="month_num" ESCAPE="HTML">" <TMPL_VAR NAME="selected" ESCAPE="HTML"> ><TMPL_VAR NAME="month_name" ESCAPE="HTML"></option> </TMPL_LOOP> </select> <input type="submit" value="Continue" /> </form> </body> </html>
Re: Using CGI.pm
by ptkdb (Monk) on Nov 18, 2003 at 14:14 UTC
    CGI.pm has been distributed with perl since about 5.6.1 I believe, so it may be installed in your system already. My CGI.pm is a little rusty, but try:
    use CGI qw/:standard/ ; print header() ; print start_html() print "Hello World" print end_html() ;
    as a CGI script and see if it works. You'll get an "Internal Server Error", and an entry in the error log saying something to the effect of "could not locate CGI.pm" if CGI.pm is not there.
      Why so many print's?
      print header, start_html('Hello World'), p('Hello World'), end_html, ;
      works just as well and is not only cleaner, but less prone to typos ... and by the way, the example you give is missing some important delimiters. Please check your code before you post or disclaim it with "untested".

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)
      
      Even if CGI.pm is part of your set-up, you might still get errors or other weird behaviour of your script, if you do not put your script in the right folder. Check with your sys-admin or web-admin where to place your scripts. At the same time ask him whether CGI.pm is installed (and if so, what version).

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Using CGI.pm
by BUU (Prior) on Nov 18, 2003 at 18:27 UTC
    (TIMTOWTDI!)
    Personally I prefer CGI::Lite over CGI. For me I find the interface much cleaner than CGI, and it's drastically faster, not having to load thirteen million subroutines for doing every possible thing someone might conceive doing with cgi/html. For example to get your form data you just do:
    my $c = new CGI::Lite; my %post = $c->parse_form_data('POST');
    or to get cookies you just call parse_cookies(). But this is all the module does, just parse forms and cookies, it doesn't bother with all the bastardized html functions (Which I deeply, deeply hate, but thats another story) and other assorted nonsense CGI comes with.

    As to html, I vastly prefer using HTML::Template for all of my html needs. And another advantage to both of these modules is that they're "pure perl" meaning all you would have to do is download cgi-lite.tar.gz, make a folder on your website called 'CGI' and then upload the file called 'Lite.pm' to that folder, then presto, you can instantly use CGI::Lite;.

      Excellent answer, BUU. I'll give CGI::Lite a try because parsing forms is all I'm working with right now. Minimalism appeals to me.

      I'm not sure what you mean by "bastardized html functions," but I'm perfectly happy to write my own HTML and CSS. I hand-code everything and know my way around the specs at W3C.org quite well. So I'm not looking for a mod to help with the markup - maybe later if I see the need but certainly not now.

      Thanks also for the installation instructions.

      Take care,
      Dean (aka D9r)

        the 'bastardized html functions' are all the little ones that CGI.pm comes with.. p(),hr(), etc.

      BUU wrote:
      "For example to get your form data you just do:"

      my $c = new CGI::Lite; my %post = $c->parse_form_data('POST');

      Will that work for a post request that contains a query string? Like this:

      <form method="post" action="script.cgi?choice=one">
        Well, to be pedantic, no the above code wouldn't, as it only specifies the POST data. If you wanted the query string you would just call it with 'GET' as an arguement: my %get = $c->parse_form_data('GET');. If you wanted both types of paramaters in one hash then you would need to merge them some how. How you merge depends on how you want to treat duplicates and such.
Re: Using CGI.pm
by tilly (Archbishop) on Nov 19, 2003 at 06:23 UTC
    Let me run slightly counter to the advice that you got from everyone else.

    Yes, use the param() method of CGI to parse form data.

    Do not use it as a method of producing HTML for anything but the simplest of scripts. When you use it, you guarantee that all HTML coding has to be done by a programmer, and translation to and from any external layout tools will be a real PITA. Unless you want to find people who are both decent programmers and decent HTML designers, that is a poor way to factor work.

    See Re (tilly) 6: Code Critique for a somewhat theoretical explanation of the real tradeoffs between different approaches to generating HTML in code.

Re: Using CGI.pm
by Deanimal (Acolyte) on Nov 18, 2003 at 17:31 UTC

    Thanks for that test script. Funny, I've never run one of those 'Hello' tests before - I just run what I'm working on and get it to work. But it's good to start from the beginning, and it's good to see an example of how the first few lines should be written. (I haven't used 'strict' before and know I should.)

    I ran the script and received the 500 internal server error. The error log confirms I don't have CGI.pm installed:

    Can't locate CGI.pm in @INC @INC contains: /usr/lib/perl5/5.8.0/i386-linux-thread-multi

    I'll see if I can get my host admin to install it for me. I asked them yesterday and they haven't done it yet - maybe if I quote some of your responses they'll see it's a reasonable request.

    Regarding my earlier reference to WS_ftp: That's my ftp program. Yes, I'm using a Windows PC at home, but the site is hosted on Linux. I transfer files using FTP. I've never worked with the command line or used Shell access, and I'm assuming that's what everyone is talking about when they say to enter single Perl commands such as the ones needed for installing CGI.pm. So at this point I have no idea how to enter Perl commands other than through a script. Maybe I should just go experiment with the shell access (if I have it - I'm not sure).

    I like writing my own HTML and CSS too. I'd be using CGI.pm primarily for it's other features.

    Thanks again, everybody. I appreciate your help.
    Dean

      Do you know what operating system the server is using? CGI.pm is part of the core Perl. On Red Hat, the perl-CGI package was split out so that it could be upgraded separately. My guess is that the admin didn't install that package. It really should be installed on any web server with Perl.