The CGI module provides HTML helper functions that, when passed array references, apply themselves to each element of the referenced array:
print ol( li([ qw(red blue green)]) ); <OL><LI>red</LI><LI>blue</LI><LI>green</LI></OL> @names = qw(Larry Moe Curly); print ul( li({ -TYPE => "disc" }, \@names) ); <UL><LI TYPE="disc">Larry</LI> <LI TYPE="disc">Moe</LI> <LI TYPE="disc">Curly</LI></UL>
The HTML-generating functions in CGI.pm can make it easy to generate lists and tables. Passed a simple string, these functions produce HTML for that string. But passed an array reference, they work on all strings in that array.
print li("alpha"); <LI>alpha</LI> print li( [ "alpha", "omega"] ); <LI>alpha</LI> <LI>omega</LI>
The shortcut functions for lists are loaded when you use the :standard import tag, but you need to ask for :html3 explicitly to get helper functions for tables. There's also a conflict between the <TR> tag, which would normally make a tr( ) function, and Perl's built-in tr/// operator. Therefore, to make a table row, use the Tr( ) function.
This example generates an HTML table starting with a hash of arrays. The keys will be the row headers, and the array of values are the columns.
use CGI qw(:standard :html3); %hash = ( "Wisconsin" => [ "Superior", "Lake Geneva", "Madison" ], "Colorado" => [ "Denver", "Fort Collins", "Boulder" ], "Texas" => [ "Plano", "Austin", "Fort Stockton" ], "California" => [ "Sebastopol", "Santa Rosa", "Berkeley" ], ); $\ = "\n"; print "<TABLE><CAPTION>Cities I Have Known</CAPTION>"; print Tr(th [qw(State Cities)]); for $k (sort keys %hash) { print Tr(th($k), td( [ sort @{$hash{$k}} ] )); } print "</TABLE>";
That generates text like this:
<TABLE> <CAPTION>Cities I Have Known</CAPTION> <TR><TH>State</TH> <TH>Cities</TH></TR> <TR><TH>California</TH> <TD>Berkeley</TD> <TD>Santa Rosa</TD> <TD>Sebastopol</TD> </TR> <TR><TH>Colorado</TH> <TD>Boulder</TD> <TD>Denver</TD> <TD>Fort Collins</TD> </TR> <TR><TH>Texas</TH> <TD>Austin</TD> <TD>Fort Stockton</TD> <TD>Plano</TD> </TR> <TR><TH>Wisconsin</TH> <TD>Lake Geneva</TD> <TD>Madison</TD> <TD>Superior</TD></TR> </TABLE>
You can produce the same output using one print statement, although it is slightly trickier because you have to use a map to create the implicit loop. This print statement produces output identical to that displayed previously:
print table caption('Cities I have Known'), Tr(th [qw(State Cities)]), map { Tr(th($_), td( [ sort @{$hash{$_}} ] )) } sort keys %hash;
This is especially useful for formatting the results of a database query, as in Example 19-3 (see Chapter 14 for more on databases).
#!/usr/bin/perl # salcheck - check for salaries use DBI; use strict; use CGI qw(:standard :html3); my $limit = param("LIMIT"); print header( ), start_html("Salary Query"), h1("Search"), start_form( ), p("Enter minimum salary", textfield("LIMIT")), submit( ), end_form( ); if (defined $limit) { my $dbh = DBI->connect("dbi:mysql:somedb:server.host.dom:3306", "username", "password") or die "Connecting: $DBI::errstr"; my $sth = $dbh->prepare("SELECT name,salary FROM employees WHERE salary > $limit") or die "Preparing: ", $dbh->errstr; $sth->execute or die "Executing: ", $sth->errstr; print h1("Results"), "<TABLE BORDER=1>"; while (my $row = $sth->fetchrow_arrayref( )) { print Tr( td( $row ) ); } print "</TABLE>\n"; $sth->finish; $dbh->disconnect; } print end_html( );
The documentation for the standard CGI module; Recipe 14.9
Copyright © 2003 O'Reilly & Associates. All rights reserved.