Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

printing out a table X wide and X down without html::template

by Anonymous Monk
on Aug 21, 2007 at 15:58 UTC ( [id://634116]=perlquestion: print w/replies, xml ) Need Help??

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

Can someone help me out here with a quick question? I have a picture gallery set up and I have to do the printout of thumbnails on the screen in X number of pictures across and X number of pictures down (defined by the admin, so it can be anything).

How can I get the html to print out with TR tags between each set of X across and TD tags between each image?

I think it needs a little failsafe in there incase it isn't always an even number in the last row where there aren't empty table cells.

For an easy sample, let's assume we have @images = qw(image1.gif image2.gif image3.gif ...); We want to go say 4 wide and 5 down for a total of 20 pictures on a screen at once. However, if there's only 2 rows of images I don't want 3 blank rows. I just want the 2 rows.

  • Comment on printing out a table X wide and X down without html::template

Replies are listed 'Best First'.
Re: printing out a table X wide and X down without html::template
by ikegami (Patriarch) on Aug 21, 2007 at 16:24 UTC

    Well, the following generates valid HTML (but not XHTML).

    use constant MAX_COLS => 4; use constant MAX_ROWS => 5; my $col = 0; my $row = 0; print("<table>"); foreach my $image (@images) { print("<tr>") if !$col; print("<td>"); print(...); if (++$col == MAX_COLS) { $col = 0; if (++$row == MAX_ROWS) { last; } } } print("</table>");

    Update: Bug fix. The conditions for printing <tr> and <td> were incorrect.

Re: printing out a table X wide and X down without html::template
by BrowserUk (Patriarch) on Aug 21, 2007 at 16:46 UTC

    A generic sub using a couple of loops and a couple of lasts.

    It displays right in a browser. What that means for whether it is complient to any of the zillion slightly differing 'standards' I have no idea :)

    #! perl -slw use strict; sub formatImages{ local $\; my( $w, $h ) = ( shift, shift ); my $html = "<table>\n"; for my $hi ( 1 .. $h ) { $html .= '<tr>'; for my $wi ( 1 .. $w ) { last unless @_; $html .= '<td> ' . shift() . ' </td>'; } $html .= "</tr>\n"; last unless @_; } return $html . "</table>\n"; } while( 1 ) { my @images = ( 1 .. rand 20 ); print scalar @images; print formatImages( 4, 5, @images ); <STDIN>; }

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: printing out a table X wide and X down without html::template
by blahblah (Friar) on Aug 21, 2007 at 17:24 UTC
    Really you only need to define the number of columns. The rows will be dynamically determined based on how many images you have. Modulo is the way to go in this scenario:

    #!/usr/bin/perl # run this like: # foo.pl <number_of_cols> # foo.pl 5 use strict; # get user input for the number of columns my $cols = $ARGV[0] || 2; my @images = qw(1.gif 2.gif 3.jpg 4.png 5.jpg); my $pos = 0; my $row = 0; my @rowdata; foreach my $file (sort @images) { $rowdata[$row][$pos] = qq|<tr>\n| if $pos == 0; $rowdata[$row][$pos] .= qq| <td><img src="$file">$file</td>|; if (($pos > 0 && $pos % ($cols-1) == 0) || $cols == 1) { # we just filled the last position. Reset. $rowdata[$row][$pos] .= qq|\n</tr>\n|; $pos = 0; $row++; } else { $pos++; } } unless ($pos == 0) { $rowdata[$row][$pos++] = qq| <td>&nbsp;</td>| until $pos == $cols; $rowdata[$row][$pos] .= qq|</tr>\n|; } print join("\n",@{$_}) for @rowdata;

    I'm sure that can be golfed down much smaller.

    blahblah
Re: printing out a table X wide and X down without html::template
by dsheroh (Monsignor) on Aug 21, 2007 at 19:26 UTC
    I'm surprised nobody has presented a simple join-based solution yet...
    #!/usr/bin/perl use strict; use warnings; my $n_cols = 5; my @data = ('1'..'12'); print "<table>\n"; while (@data) { print '<tr><td>' . (join "</td>\n <td>", (@data, ('&nbsp;')x$n_cols)[0..$n_col +s - 1]) . '</td></tr>' . "\n"; @data = @data[$n_cols..$#data]; } print "</table>\n";
    Output:
    <table> <tr><td>1</td> <td>2</td> <td>3</td> <td>4</td> <td>5</td></tr> <tr><td>6</td> <td>7</td> <td>8</td> <td>9</td> <td>10</td></tr> <tr><td>11</td> <td>12</td> <td>&nbsp;</td> <td>&nbsp;</td> <td>&nbsp;</td></tr> </table>
Re: printing out a table X wide and X down without html::template
by dwm042 (Priest) on Aug 21, 2007 at 17:40 UTC
    This example uses Perl::CGI

    #!/usr/bin/perl -w use warnings; use strict; package main; # # I really like Perl::CGI -- so this example incorporates it. # use CGI; use CGI::Carp qw(fatalsToBrowser); my $q = new CGI; my $human_legible = "\n"; print $q->header, $q->start_html('Table Example'), $q->h1('How to Format a table'); # # Add breaks so ppl can read the HTML output. # This is an example after all. # print $human_legible; # # This is where we figure out spacing. It could be made into a # function easily enough. # my $x_dim = 4; my $y_dim = 5; my $test_text = "This is a test"; my @array = ( $test_text, $test_text, $test_text, $test_text, $test_text, $test_text, $test_text ); my $table_rows = int((scalar @array) / $x_dim); my $last_row_count = (scalar @array) % $x_dim; # # Print the table here. # print $q->start_table; my $array_index = 0; my $table_entries = ""; for ( my $r = 0; $r < $table_rows; $r++ ) { $table_entries = ""; for ( my $j = 0; $j < $x_dim ; $j++ ) { $table_entries .= $q->td($array[$array_index]); $array_index++; } print $q->Tr($table_entries); print $human_legible; } $table_entries = ""; for ( my $i = 0; $i < $last_row_count ; $i++ ) { $table_entries .= $q->td($array[$array_index]); $array_index++; } print $q->Tr($table_entries); print $human_legible; print $q->end_table; print $q->end_html;
    The output is:

    C:\Code>perl cgitable.pl Content-Type: text/html; charset=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-U +S"> <head> <title>Table Example</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +" /> </head> <body> <h1>How to Format a table</h1> <table><tr><td>This is a test</td><td>This is a test</td><td>This is a + test</td> <td>This is a test</td></tr> <tr><td>This is a test</td><td>This is a test</td><td>This is a test</ +td></tr> </table> </body> </html>
Re: printing out a table X wide and X down without html::template
by wfsp (Abbot) on Aug 21, 2007 at 16:10 UTC
    Or, how can I make an ommlette without breaking any eggs. :-)

    HTML::Template will do what you want very easily.

    Could explain why you need a solution without it?

      I take a inside-out approach and use CGI's distributive magic for building the td and tr blocks.
      #!/usr/bin/perl use warnings; use strict; use CGI; use constant COLS => 4; use constant ROWS => 5; use constant TABLE_SIZE => COLS * ROWS; my $cgi = new CGI; # Loop through the pages, to pretend we got a page number from a reque +st... foreach my $page_num ( 1 .. 6 ) { # Create a dummy list of image names. We're adding an orphan to test + a short # table display. my @image_names = map {"image_$_.jpg"} 1 .. 101; # ---------------------------------------- # this does the real work... # ---------------------------------------- # Get a page's table's worth of image names and wrap them inside < +img> # tags... my @imgs = map { $cgi->img($_) } splice( @image_names, ( $page_num - 1 ) * TABLE_SIZE, TABLE_SI +ZE ); # Make sure the table has enough elements. Add blank elements if not + to keep # the rows balanced... if ( scalar(@imgs) % COLS ) { push @imgs, ('&nbsp;') x ( COLS - ( scalar(@imgs) % COLS ) ); } # Read "THE DISTRIBUTIVE PROPERTY OF HTML SHORTCUTS" in the CGI pe +rldoc. # # Process rows in column-sized chunks... my @rows = (); while (@imgs) { push @rows, join( '', $cgi->td( [ splice( @imgs, 0, COLS ) ] ) + ); } print $cgi->table( $cgi->Tr( \@rows ) ), "\n\n"; # ---------------------------------------- # end o' working part # ---------------------------------------- }
Re: printing out a table X wide and X down without html::template
by chakram88 (Pilgrim) on Aug 21, 2007 at 18:58 UTC
    a simple example, using two counters. One to keep track of the image array index, and one to keep track of the number of colums:
    #!/usr/bin/perl use warnings; use strict; my @images; for (1 .. 20) { push @images, "image$_.gif";} my $x_wide = 6; # user supplied value my $output = "<table>\n"; my $i = 0; while ($i < scalar @images) { $output .= "<tr>\n"; for (my $j=0; $j<$x_wide; $j++) { if ($images[$i]) { $output .= "\t<td><img src='$images[$i]' ....></td>\n"; $i++; } } $output .= "</tr>\n"; } $output .= "</table>"; print $output;
    produces a simple:
    <table> <tr> <td><img src='image1.gif' ....></td> <td><img src='image2.gif' ....></td> <td><img src='image3.gif' ....></td> <td><img src='image4.gif' ....></td> <td><img src='image5.gif' ....></td> <td><img src='image6.gif' ....></td> </tr> <tr> <td><img src='image7.gif' ....></td> <td><img src='image8.gif' ....></td> <td><img src='image9.gif' ....></td> <td><img src='image10.gif' ....></td> <td><img src='image11.gif' ....></td> <td><img src='image12.gif' ....></td> </tr> <tr> <td><img src='image13.gif' ....></td> <td><img src='image14.gif' ....></td> <td><img src='image15.gif' ....></td> <td><img src='image16.gif' ....></td> <td><img src='image17.gif' ....></td> <td><img src='image18.gif' ....></td> </tr> <tr> <td><img src='image19.gif' ....></td> <td><img src='image20.gif' ....></td> </tr> </table>
Re: printing out a table X wide and X down without html::template
by robot_tourist (Hermit) on Aug 22, 2007 at 08:12 UTC

    I've seen one response that uses CGI.pm, but don't forget that the CGI docs explain how to use start_Tr and end_Tr.

    use CGI qw/:standard *table *Tr/; ... # decide rows and columns of table ... # e.g. AoA @rows where each element points to an array of cells ... # perhaps each cell could point to a hash of the image data print $query->start_table(...); for my $row (@rows) { print $query->start_Tr(...); for my $cell (@{$row}) { print $query->td(...); # insert image data here } print $query->end_Tr(); } print $query->end_table(); ...

    How can you feel when you're made of steel? I am made of steel. I am the Robot Tourist.
    Robot Tourist, by Ten Benson

Re: printing out a table X wide and X down without html::template
by spatterson (Pilgrim) on Aug 23, 2007 at 10:18 UTC

    Do you need them in a table or will a grid-style layout that automagically resizes to the browser window suffice? I use this in my gallery though you may want to adjust the width & height attributes.

    CSS
    div.image { float:left; display:inline; text-align: left; margin-left: 1em; margin-right: 1em; width: 200px; height: 250px; }
    HTML
    <div id='image'> <img src='1.jpg'> <img src='2.jpg'> </div>

    just another cpan module author

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2025-03-21 07:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (63 votes). Check out past polls.