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

I'm writing my first CGI::Application/HTML::Template application, have spent a few hours Googling and trying things but can't figure out what is wrong. Any help would be appreciated. Thanks!

template:
<form method='post' action='<TMPL_VAR NAME="LOGIN_URL">'> Email Address <input type='text' name='email' size='50' maxlength='80' value='<TMPL_VAR NAME="EMAIL">'> <br><br> Last six digits of SSN <input type='password' name='pin' size='8' maxlength='6' value='<TMPL_VAR NAME="PASSWD">'> <br><br> <input type='hidden' name='rm' value='<TMPL_VAR NAME="RM">'> <input type='submit' name='submit'> </form>
code:
sub form_login { my ( $self ) = @_; my $nextrm = 'authenticate'; # Get CGI query object my $cgi = $self->query(); my $email = $cgi->param('email'); $self->tmpl_path('./'); my $output = $cgi->header(); $output .= $cgi->start_html( -title => 'Employee Login Form' ); my $tmpl_obj = $self->load_tmpl( 'Login.tmpl' ); # $output .= Dumper ( $tmpl_obj ); # print $output; # next line generates the error $tmpl_obj->param( LOGIN_URL => '/cgi-bin/Auth/Auth.cgi', EMAIL => $cgi->param('email'), PASSWD => '', RM => $nextrm, ); $output .= $tmpl_obj->output; $output .= $self->dump_html(); $output .= $cgi->end_html(); return $output; }
The resulting error message is: HTML::Template->param() : You gave me an odd number of parameters to param()! at Auth.pm line 51 If I uncomment the two output lines, I get the following:
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"> <head><title>Employee Login Form</title> </head><body>$VAR1 = bless( { 'param_map' => { 'passwd' => bless( do{\(my $o = undef)}, 'HTML::Template::VAR' ), 'email' => bless( do{\(my $o = undef)}, 'HTML::Template::VAR' ), 'rm' => bless( do{\(my $o = undef)}, 'HTML::Template::VAR' ), 'login_url' => bless( do{\(my $o = undef)}, 'HTML::Template::VAR' ) }, 'parse_stack' => [ \' <form method=\'post\' action=\'', $VAR1->{'param_map'}{'login_url'}, \'\'> Email Address <input type=\'text\' name=\'email\' size=\'50\' maxlength=\'80\' value=\'', $VAR1->{'param_map'}{'email'}, \'\'><br><br> Last six digits of SSN <input type=\'password\' name=\'pin\' size=\'8\' maxlength=\'6\' value=\'', $VAR1->{'param_map'}{'passwd'}, \'\'> <br><br> <input type=\'hidden\' name=\'rm\' value=\'', $VAR1->{'param_map'}{'rm'}, \'\'> <input type=\'submit\' name=\'submit\'> </form> ' ], 'options' => { 'memory_debug' => 0, 'double_file_cache' => 0, 'shared_cache' => 0, 'cache_debug' => 0, 'filepath' => 'Login.tmpl', 'global_vars' => 0, 'ipc_max_size' => 0, 'ipc_key' => 'TMPL', 'file_cache_dir_mode' => 448, 'vanguard_compatibility_mode' => 0, 'ipc_segment_size' => 65536, 'loop_context_vars' => 0, 'blind_cache' => 0, 'file_cache_dir' => '', 'debug' => 0, 'die_on_bad_params' => 1, 'stack_debug' => 0, 'ipc_mode' => 438, 'search_path_on_include' => 0, 'double_cache' => 0, 'file_cache' => 0, 'path' => [ './' ], 'strict' => 1, 'timing' => 0, 'shared_cache_debug' => 0, 'associate' => [], 'filename' => 'Login.tmpl', 'case_sensitive' => 0, 'no_includes' => 0, 'cache' => 0, 'max_includes' => 10 }, 'mtime' => 1087914359 }, 'HTML::Template' );

Replies are listed 'Best First'.
Re: HTML::Template error message
by Sidhekin (Priest) on Jun 22, 2004 at 17:08 UTC

    $tmpl_obj->param( LOGIN_URL => '/cgi-bin/Auth/Auth.cgi', EMAIL => $cgi->param('email'), PASSWD => '', RM => $nextrm, );

    For this to generate an odd number of elements, $cgi->param('email') must return a list with an even number of elements. (It is the only method or function call; the others are scalars.)

    In a list context (as this is), the param method will return a list. So, my guess would be that you have either zero or two instances of the 'email' parameter.

    The simplest thing seems to be just forcing a scalar context:

    $tmpl_obj->param( LOGIN_URL => '/cgi-bin/Auth/Auth.cgi', EMAIL => scalar($cgi->param('email')), PASSWD => '', RM => $nextrm, );

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

Re: HTML::Template error message
by bassplayer (Monsignor) on Jun 22, 2004 at 16:49 UTC
    $tmpl_obj->param( LOGIN_URL => '/cgi-bin/Auth/Auth.cgi', EMAIL => $cgi->param('email'), PASSWD => '', RM => $nextrm, );


    In this code snippet, you are passing a hash to the param() method. The error is due to the fact that one of your variables is undefined (or is a list, as Sidhekin points out below). Check the values of $cgi->param('email') and $nextrm to ensure that they are populated properly before passing the hash.

    Update: Here's a related node.

    bassplayer

      Actually, the problem is that HTML::Template (whether or not it has anything to do with CGI::Application, I don't know) doesn't like:
      EMAIL => $cgi->param('email'),
      I changed it to:
      EMAIL => $email,
      and it works fine now. However, it seems to me that the original version should work. Why doesn't it interpolate correctly? I ran into a similar interpolation problem on one of my other template pages in the same application.

        Why are you passing the CGI parameters back to the template like that. Just use

        my $cgi = CGI->new(); my $template = HTML::Template->new( filename => 'foo.tmpl', associate => $cgi, );
        when you instantiate the H::T object instead. Of course, you have to take care with multiple values, as usual. Check out the HTML::Template Tutorial if you already haven't and good luck. :)

        UPDATE: I suppose i should post the relevant CGI::Application code instead :O

        my $tmpl_obj = $webapp->load_tmpl('some_other.tmpl', associate => $cgi, );

        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)
        
        Because $cgi->param(x) in list returns an empty list. In scalar context it returns undef. So when you include it in the H::T->param call, it's in list context and effectively doesn't exist. When you assign it to a scalar first you get undef, which is an item in the list.