Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

table()'s with CGI.pm

by mexnix (Pilgrim)
on Jun 25, 2001 at 20:10 UTC ( [id://91324]=perlquestion: print w/replies, xml ) Need Help??

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

With the latest things I've been working on, I've been trying to get into the Perl (and CGI.pm) way of thinking. This is a problem that struck me today, I just wasn't sure what to do, but it may require changing my data structures. This comes from a script I decided to put together to keep a current status of all our web sites so that my department (1 programmer working in a graphics design studio) doesn't get ignored. The data comes in like this :

my %sites; open (INFILE, "<sites.txt"); #data from file looks like this: #sitename|siteaddress|status|comments while (<INFILE>) { my($name, @status) = split/|/; $sites{$name} = @status; } close (INFILE);

Now I want to take %sites and print it into table. My first thought was that I would iterate over %sites with foreach and print a <td> each time, but when I was reading the CGI.pm documention, table() was totally different than I thought. What I want to do is print a table that looks roughly like this:

Site Name | Site Address       | Status             | Comments
$site     | $sites{$site}->[0] | $sites{$site}->[1] | $sites{$site}->[2]

Is this possible? Or does %sites need to change to @sites or a hash reference?

__________________________________________________
%mexnix = (email = > "mexnix@hotmail.com", website => "http://mexnix.perlmonk.org");

Replies are listed 'Best First'.
Re: table()'s with CGI.pm
by Masem (Monsignor) on Jun 25, 2001 at 20:40 UTC
    One of the nice things about the CGI.pm table and other params is that if you pass, say, TD, an array value, it will make a TD for each one of those array values, with the optional modifiers for the tag. Combine this with map, and you can easily make complex tables:
    print $cgi->table( $cgi->Tr( map { $cgi->td( [ $_, @{$sites{$_}} ] ) } keys %sites ) # Tr ); #table

    update: should be keys %sites as davorg pointed out.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

      Just a couple of points on that code.

      1. I think you meant keys %sites
      2. I find the object interface to CGI.pm clutters code up unnecessarily and can confuse beginners

      Here's a complete test program based on your code:

      #!/usr/bin/perl -w use strict; use CGI qw (:standard); my %sites; while (<DATA>) { chomp; my($name, @status) = split/\|/; $sites{$name} = [@status]; } print header; print start_html; print table(Tr(th(['Site Name', 'Site Address', 'Status', 'Comments'])), Tr([ map { td([$_, @{$sites{$_}}])} keys %sites ])); print end_html; __END__ site A|www.sitea.com|0|Not ready site B|www.siteb.org|1|Ready!!
      --
      <http://www.dave.org.uk>

      Perl Training in the UK <http://www.iterative-software.com>

Re: table()'s with CGI.pm
by buckaduck (Chaplain) on Jun 25, 2001 at 21:09 UTC
    I'm a big fan of the HTML::Table and Data::Table modules. The looping technique you're thinking about is best suited to the former:
    use HTML::Table; # Create an HTML::Table object my $table = HTML::Table->new; $table->addRow('Site Name', 'Site Address', 'Status', 'Comments', ); $table->setRowHead(1); # Add the data one row at a time foreach my $site (keys %sites) { $table->addRow($site, $sites{$site}->[0], $sites{$site]->[1], $sites{$site}->[2], ); } print $table;
    buckaduck
Re: tables with CGI.pm
by petdance (Parson) on Jun 25, 2001 at 21:30 UTC
    You've got a couple of problems.
    1. split takes a regex, so you have to quote the pipe.
    2. You're assigning a list to a scalar in the hash, so you're just storing the number of elements. If you want to store the entire list, you have to say $sites{$site} = [@values];

    Now, as to printing the table. I'm assuming you're printing in the order that they come in. Here's how I like to do this kind of thing:

    my @rows; open (INFILE, "<sites.txt"); my @headings = ( "Site Name", "Site Address", "Status", "Comments" ); push( @rows, th( \@headings ) ); while (<INFILE>) { my @fields = split /\|/; push( @rows, td( \@fields ) ); } # while close (INFILE); print table( TR( \@rows ) ); # NOTE: It's TR, not tr, so it doesn't get confused with tr///

    xoxo,
    Andy
    --
    I was dreaming when I wrote this, so sue me if I go too fast.

Re: table()'s with CGI.pm
by jaldhar (Vicar) on Jun 25, 2001 at 20:35 UTC
    I find the HTML functions in CGI.pm to be more trouble than they're worth most of the time. Just add your own tags with print. The Data::ShowTable module from CPAN might also be useful if you don't want print statements everywhere. -- Jaldhar
Re: table()'s with CGI.pm
by thabenksta (Pilgrim) on Jun 25, 2001 at 20:32 UTC

    No need for all that fancy mess, I would do the following.

    my $table open (INFILE, "<sites.txt"); #data from file looks like this: #sitename|siteaddress|status|comments while (<INFILE>) { my(@vals) = split/|/; $table .= "<tr><td>$vals[0]</td><td>$vals[1]</td><td>$vals[2]</td><t +d>$vals[3]</td></tr>\n"; } close (INFILE); print "<table>$table</table>";

    With the appropriate header of course.

    -thabenksta
    my $name = 'Ben Kittrell'; $name=~s/^(.+)\s(.).+$/\L$1$2/g; my $nick = 'tha' . $name . 'sta';

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://91324]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-23 09:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found